mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-07 00:48:41 +00:00
lt sync 2667
This commit is contained in:
parent
7adf503bb6
commit
bd8dcbce91
25 changed files with 925 additions and 529 deletions
|
@ -549,6 +549,10 @@ namespace libtorrent
|
||||||
|
|
||||||
udp_socket m_dht_socket;
|
udp_socket m_dht_socket;
|
||||||
|
|
||||||
|
// these are used when starting the DHT
|
||||||
|
// (and bootstrapping it), and then erased
|
||||||
|
std::list<std::pair<std::string, int> > m_dht_router_nodes;
|
||||||
|
|
||||||
void on_receive_udp(error_code const& e
|
void on_receive_udp(error_code const& e
|
||||||
, udp::endpoint const& ep, char const* buf, int len);
|
, udp::endpoint const& ep, char const* buf, int len);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace libtorrent
|
||||||
, proxy_settings const& ps
|
, proxy_settings const& ps
|
||||||
, std::string const& password = "");
|
, std::string const& password = "");
|
||||||
|
|
||||||
|
void start();
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -92,6 +93,11 @@ namespace libtorrent
|
||||||
|
|
||||||
tracker_manager& m_man;
|
tracker_manager& m_man;
|
||||||
boost::shared_ptr<http_connection> m_tracker_connection;
|
boost::shared_ptr<http_connection> m_tracker_connection;
|
||||||
|
session_settings const& m_settings;
|
||||||
|
address m_bind_iface;
|
||||||
|
proxy_settings const& m_ps;
|
||||||
|
connection_queue& m_cc;
|
||||||
|
io_service& m_ios;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,9 @@ namespace libtorrent { namespace dht
|
||||||
{
|
{
|
||||||
friend void intrusive_ptr_add_ref(dht_tracker const*);
|
friend void intrusive_ptr_add_ref(dht_tracker const*);
|
||||||
friend void intrusive_ptr_release(dht_tracker const*);
|
friend void intrusive_ptr_release(dht_tracker const*);
|
||||||
dht_tracker(udp_socket& sock, dht_settings const& settings
|
dht_tracker(udp_socket& sock, dht_settings const& settings);
|
||||||
, entry const& bootstrap);
|
|
||||||
|
void start(entry const& bootstrap);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void add_node(udp::endpoint node);
|
void add_node(udp::endpoint node);
|
||||||
|
|
|
@ -161,7 +161,7 @@ class node_impl : boost::noncopyable
|
||||||
typedef std::map<node_id, torrent_entry> table_t;
|
typedef std::map<node_id, torrent_entry> table_t;
|
||||||
public:
|
public:
|
||||||
node_impl(boost::function<void(msg const&)> const& f
|
node_impl(boost::function<void(msg const&)> const& f
|
||||||
, dht_settings const& settings, boost::optional<node_id> node_id);
|
, dht_settings const& settings);
|
||||||
|
|
||||||
virtual ~node_impl() {}
|
virtual ~node_impl() {}
|
||||||
|
|
||||||
|
@ -186,7 +186,9 @@ public:
|
||||||
|
|
||||||
typedef table_t::iterator data_iterator;
|
typedef table_t::iterator data_iterator;
|
||||||
|
|
||||||
|
void set_node_id(node_id const& nid) { m_id = nid; }
|
||||||
node_id const& nid() const { return m_id; }
|
node_id const& nid() const { return m_id; }
|
||||||
|
|
||||||
boost::tuple<int, int> size() const{ return m_table.size(); }
|
boost::tuple<int, int> size() const{ return m_table.size(); }
|
||||||
size_type num_global_nodes() const
|
size_type num_global_nodes() const
|
||||||
{ return m_table.num_global_nodes(); }
|
{ return m_table.num_global_nodes(); }
|
||||||
|
|
|
@ -151,7 +151,7 @@ namespace libtorrent
|
||||||
policy::peer* peer_info_struct() const
|
policy::peer* peer_info_struct() const
|
||||||
{ return m_peer_info; }
|
{ return m_peer_info; }
|
||||||
|
|
||||||
enum peer_speed_t { slow, medium, fast };
|
enum peer_speed_t { slow = 1, medium, fast };
|
||||||
peer_speed_t peer_speed();
|
peer_speed_t peer_speed();
|
||||||
|
|
||||||
void send_allowed_set();
|
void send_allowed_set();
|
||||||
|
@ -187,6 +187,8 @@ namespace libtorrent
|
||||||
bool on_parole() const
|
bool on_parole() const
|
||||||
{ return peer_info_struct() && peer_info_struct()->on_parole; }
|
{ return peer_info_struct() && peer_info_struct()->on_parole; }
|
||||||
|
|
||||||
|
int picker_options() const;
|
||||||
|
|
||||||
void prefer_whole_pieces(int num)
|
void prefer_whole_pieces(int num)
|
||||||
{ m_prefer_whole_pieces = num; }
|
{ m_prefer_whole_pieces = num; }
|
||||||
|
|
||||||
|
@ -213,7 +215,12 @@ namespace libtorrent
|
||||||
|
|
||||||
bool is_seed() const;
|
bool is_seed() const;
|
||||||
|
|
||||||
void set_upload_only(bool u) { m_upload_only = u; }
|
void set_upload_only(bool u)
|
||||||
|
{
|
||||||
|
m_upload_only = u;
|
||||||
|
disconnect_if_redundant();
|
||||||
|
}
|
||||||
|
|
||||||
bool upload_only() const { return m_upload_only; }
|
bool upload_only() const { return m_upload_only; }
|
||||||
|
|
||||||
// will send a keep-alive message to the peer
|
// will send a keep-alive message to the peer
|
||||||
|
|
|
@ -88,6 +88,14 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// the number of priority levels
|
||||||
|
priority_levels = 8,
|
||||||
|
// priority factor
|
||||||
|
prio_factor = priority_levels - 4
|
||||||
|
};
|
||||||
|
|
||||||
struct block_info
|
struct block_info
|
||||||
{
|
{
|
||||||
block_info(): peer(0), num_peers(0), state(state_none) {}
|
block_info(): peer(0), num_peers(0), state(state_none) {}
|
||||||
|
@ -110,6 +118,20 @@ namespace libtorrent
|
||||||
enum piece_state_t
|
enum piece_state_t
|
||||||
{ none, slow, medium, fast };
|
{ none, slow, medium, fast };
|
||||||
|
|
||||||
|
enum options_t
|
||||||
|
{
|
||||||
|
// pick rarest first
|
||||||
|
rarest_first = 1,
|
||||||
|
// pick the most common first, or the last pieces if sequential
|
||||||
|
reverse = 2,
|
||||||
|
// only pick pieces exclusively requested from this peer
|
||||||
|
on_parole = 4,
|
||||||
|
// always pick partial pieces before any other piece
|
||||||
|
prioritize_partials = 8,
|
||||||
|
// pick pieces in sequential order
|
||||||
|
sequential = 16
|
||||||
|
};
|
||||||
|
|
||||||
struct downloading_piece
|
struct downloading_piece
|
||||||
{
|
{
|
||||||
downloading_piece(): finished(0), writing(0), requested(0) {}
|
downloading_piece(): finished(0), writing(0), requested(0) {}
|
||||||
|
@ -133,9 +155,6 @@ namespace libtorrent
|
||||||
|
|
||||||
void get_availability(std::vector<int>& avail) const;
|
void get_availability(std::vector<int>& avail) const;
|
||||||
|
|
||||||
void sequential_download(bool sd);
|
|
||||||
bool sequential_download() const { return m_sequential_download >= 0; }
|
|
||||||
|
|
||||||
// increases the peer count for the given piece
|
// increases the peer count for the given piece
|
||||||
// (is used when a HAVE message is received)
|
// (is used when a HAVE message is received)
|
||||||
void inc_refcount(int index);
|
void inc_refcount(int index);
|
||||||
|
@ -161,6 +180,9 @@ namespace libtorrent
|
||||||
void we_have(int index);
|
void we_have(int index);
|
||||||
void we_dont_have(int index);
|
void we_dont_have(int index);
|
||||||
|
|
||||||
|
int cursor() const { return m_cursor; }
|
||||||
|
int reverse_cursor() const { return m_reverse_cursor; }
|
||||||
|
|
||||||
// sets all pieces to dont-have
|
// sets all pieces to dont-have
|
||||||
void init(int blocks_per_piece, int total_num_blocks);
|
void init(int blocks_per_piece, int total_num_blocks);
|
||||||
int num_pieces() const { return int(m_piece_map.size()); }
|
int num_pieces() const { return int(m_piece_map.size()); }
|
||||||
|
@ -202,11 +224,9 @@ namespace libtorrent
|
||||||
// The last argument is the policy::peer pointer for the peer that
|
// The last argument is the policy::peer pointer for the peer that
|
||||||
// we'll download from.
|
// we'll download from.
|
||||||
void pick_pieces(bitfield const& pieces
|
void pick_pieces(bitfield const& pieces
|
||||||
, std::vector<piece_block>& interesting_blocks
|
, std::vector<piece_block>& interesting_blocks, int num_blocks
|
||||||
, int num_pieces, int prefer_whole_pieces
|
, int prefer_whole_pieces, void* peer, piece_state_t speed
|
||||||
, void* peer, piece_state_t speed
|
, int options, std::vector<int> const& suggested_pieces) const;
|
||||||
, bool rarest_first, bool on_parole
|
|
||||||
, std::vector<int> const& suggested_pieces) const;
|
|
||||||
|
|
||||||
// picks blocks from each of the pieces in the piece_list
|
// picks blocks from each of the pieces in the piece_list
|
||||||
// vector that is also in the piece bitmask. The blocks
|
// vector that is also in the piece bitmask. The blocks
|
||||||
|
@ -214,20 +234,23 @@ namespace libtorrent
|
||||||
// added to backup_blocks. num blocks is the number of
|
// added to backup_blocks. num blocks is the number of
|
||||||
// blocks to be picked. Blocks are not picked from pieces
|
// blocks to be picked. Blocks are not picked from pieces
|
||||||
// that are being downloaded
|
// that are being downloaded
|
||||||
int add_blocks(std::vector<int> const& piece_list
|
int add_blocks(int piece, bitfield const& pieces
|
||||||
, bitfield const& pieces
|
|
||||||
, std::vector<piece_block>& interesting_blocks
|
|
||||||
, int num_blocks, int prefer_whole_pieces
|
|
||||||
, void* peer, std::vector<int> const& ignore) const;
|
|
||||||
|
|
||||||
// picks blocks only from downloading pieces
|
|
||||||
int add_blocks_downloading(
|
|
||||||
bitfield const& pieces
|
|
||||||
, std::vector<piece_block>& interesting_blocks
|
, std::vector<piece_block>& interesting_blocks
|
||||||
, std::vector<piece_block>& backup_blocks
|
, std::vector<piece_block>& backup_blocks
|
||||||
|
, std::vector<piece_block>& backup_blocks2
|
||||||
|
, int num_blocks, int prefer_whole_pieces
|
||||||
|
, void* peer, std::vector<int> const& ignore
|
||||||
|
, piece_state_t speed, int options) const;
|
||||||
|
|
||||||
|
// picks blocks only from downloading pieces
|
||||||
|
int add_blocks_downloading(downloading_piece const& dp
|
||||||
|
, bitfield const& pieces
|
||||||
|
, std::vector<piece_block>& interesting_blocks
|
||||||
|
, std::vector<piece_block>& backup_blocks
|
||||||
|
, std::vector<piece_block>& backup_blocks2
|
||||||
, int num_blocks, int prefer_whole_pieces
|
, int num_blocks, int prefer_whole_pieces
|
||||||
, void* peer, piece_state_t speed
|
, void* peer, piece_state_t speed
|
||||||
, bool on_parole) const;
|
, int options) const;
|
||||||
|
|
||||||
// clears the peer pointer in all downloading pieces with this
|
// clears the peer pointer in all downloading pieces with this
|
||||||
// peer pointer
|
// peer pointer
|
||||||
|
@ -291,6 +314,8 @@ namespace libtorrent
|
||||||
void check_invariant(const torrent* t = 0) const;
|
void check_invariant(const torrent* t = 0) const;
|
||||||
void verify_pick(std::vector<piece_block> const& picked
|
void verify_pick(std::vector<piece_block> const& picked
|
||||||
, bitfield const& bits) const;
|
, bitfield const& bits) const;
|
||||||
|
#endif
|
||||||
|
#if defined TORRENT_PICKER_LOG || !defined NDEBUG
|
||||||
void print_pieces() const;
|
void print_pieces() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -313,6 +338,7 @@ namespace libtorrent
|
||||||
friend struct piece_pos;
|
friend struct piece_pos;
|
||||||
|
|
||||||
bool can_pick(int piece, bitfield const& bitmask) const;
|
bool can_pick(int piece, bitfield const& bitmask) const;
|
||||||
|
bool is_piece_free(int piece, bitfield const& bitmask) const;
|
||||||
std::pair<int, int> expand_piece(int piece, int whole_pieces
|
std::pair<int, int> expand_piece(int piece, int whole_pieces
|
||||||
, bitfield const& have) const;
|
, bitfield const& have) const;
|
||||||
|
|
||||||
|
@ -354,7 +380,7 @@ namespace libtorrent
|
||||||
// the priority value that means the piece is filtered
|
// the priority value that means the piece is filtered
|
||||||
filter_priority = 0,
|
filter_priority = 0,
|
||||||
// the max number the peer count can hold
|
// the max number the peer count can hold
|
||||||
max_peer_count = 0x3ff
|
max_peer_count = 0x3ff,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool have() const { return index == we_have_index; }
|
bool have() const { return index == we_have_index; }
|
||||||
|
@ -364,20 +390,41 @@ namespace libtorrent
|
||||||
bool filtered() const { return piece_priority == filter_priority; }
|
bool filtered() const { return piece_priority == filter_priority; }
|
||||||
void filtered(bool f) { piece_priority = f ? filter_priority : 0; }
|
void filtered(bool f) { piece_priority = f ? filter_priority : 0; }
|
||||||
|
|
||||||
|
// prio 7 is always top priority
|
||||||
|
// prio 0 is always -1 (don't pick)
|
||||||
|
// downloading pieces are always on an even prio_factor priority
|
||||||
|
//
|
||||||
|
// availability x, downloading
|
||||||
|
// | availability x, prio 3; availability 2x, prio 6
|
||||||
|
// | | availability x, prio 2; availability 2x, prio 5
|
||||||
|
// | | | availability x, prio 1; availability 2x, prio 4
|
||||||
|
// | | | |
|
||||||
|
// +---+---+---+---+
|
||||||
|
// | 0 | 1 | 2 | 3 |
|
||||||
|
// +---+---+---+---+
|
||||||
|
|
||||||
int priority(piece_picker const* picker) const
|
int priority(piece_picker const* picker) const
|
||||||
{
|
{
|
||||||
if (downloading || filtered()
|
// filtered pieces (prio = 0), pieces we have or pieces with
|
||||||
|| have() || peer_count + picker->m_seeds == 0)
|
// availability = 0 should not be present in the piece list
|
||||||
|
// returning -1 indicates that they shouldn't.
|
||||||
|
if (filtered() || have() || peer_count + picker->m_seeds == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// priority 5, 6 and 7 disregards availability of the piece
|
// prio 7 disregards availability
|
||||||
if (piece_priority > 4) return 7 - piece_priority;
|
if (piece_priority == priority_levels - 1) return 1 - downloading;
|
||||||
|
|
||||||
// pieces we are currently downloading have high priority
|
// prio 4,5,6 halves the availability of a piece
|
||||||
int prio = peer_count * 4;
|
int availability = peer_count;
|
||||||
// if (prio >= picker->m_prio_limit * 6) prio = picker->m_prio_limit * 6;
|
int priority = piece_priority;
|
||||||
|
if (piece_priority >= priority_levels / 2)
|
||||||
|
{
|
||||||
|
availability /= 2;
|
||||||
|
priority -= (priority_levels - 2) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
return prio + (4 - piece_priority);
|
if (downloading) return availability * prio_factor;
|
||||||
|
return availability * prio_factor + (priority_levels / 2) - priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(piece_pos p) const
|
bool operator!=(piece_pos p) const
|
||||||
|
@ -467,11 +514,14 @@ namespace libtorrent
|
||||||
// the number of pieces we have
|
// the number of pieces we have
|
||||||
int m_num_have;
|
int m_num_have;
|
||||||
|
|
||||||
// -1 means sequential download is not active.
|
// we have all pieces in the range [0, m_cursor)
|
||||||
// >= 0 means that pieces are requested in sequential order
|
// m_cursor is the first piece we don't have
|
||||||
// and this variable is the next piece to request.
|
int m_cursor;
|
||||||
// in that case m_pieces is cleared and not used.
|
|
||||||
int m_sequential_download;
|
// we have all pieces in the range [m_reverse_cursor, end)
|
||||||
|
// m_reverse_cursor is the first piece where we also have
|
||||||
|
// all the subsequent pieces
|
||||||
|
int m_reverse_cursor;
|
||||||
|
|
||||||
// if this is set to true, it means update_pieces()
|
// if this is set to true, it means update_pieces()
|
||||||
// has to be called before accessing m_pieces.
|
// has to be called before accessing m_pieces.
|
||||||
|
|
|
@ -141,6 +141,7 @@ namespace libtorrent
|
||||||
, auto_scrape_min_interval(300)
|
, auto_scrape_min_interval(300)
|
||||||
, max_peerlist_size(8000)
|
, max_peerlist_size(8000)
|
||||||
, min_announce_interval(5 * 60)
|
, min_announce_interval(5 * 60)
|
||||||
|
, prioritize_partial_pieces(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// this is the user agent that will be sent to the tracker
|
// this is the user agent that will be sent to the tracker
|
||||||
|
@ -436,6 +437,10 @@ namespace libtorrent
|
||||||
// that is lower than this, will be clamped to this
|
// that is lower than this, will be clamped to this
|
||||||
// value. It's specified in seconds
|
// value. It's specified in seconds
|
||||||
int min_announce_interval;
|
int min_announce_interval;
|
||||||
|
|
||||||
|
// if true, partial pieces are picked before pieces
|
||||||
|
// that are more rare
|
||||||
|
bool prioritize_partial_pieces;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
|
@ -259,6 +259,8 @@ namespace libtorrent
|
||||||
disk_check_aborted = -3
|
disk_check_aborted = -3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
storage_interface* get_storage_impl() { return m_storage.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
fs::path save_path() const;
|
fs::path save_path() const;
|
||||||
|
|
|
@ -170,6 +170,12 @@ namespace libtorrent
|
||||||
int seed_rank(session_settings const& s) const;
|
int seed_rank(session_settings const& s) const;
|
||||||
|
|
||||||
storage_mode_t storage_mode() const { return m_storage_mode; }
|
storage_mode_t storage_mode() const { return m_storage_mode; }
|
||||||
|
storage_interface* get_storage()
|
||||||
|
{
|
||||||
|
if (!m_owning_storage) return 0;
|
||||||
|
return m_owning_storage->get_storage_impl();
|
||||||
|
}
|
||||||
|
|
||||||
// this will flag the torrent as aborted. The main
|
// this will flag the torrent as aborted. The main
|
||||||
// loop in session_impl will check for this state
|
// loop in session_impl will check for this state
|
||||||
// on all torrents once every second, and take
|
// on all torrents once every second, and take
|
||||||
|
|
|
@ -366,6 +366,8 @@ namespace libtorrent
|
||||||
bool resolve_countries() const;
|
bool resolve_countries() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
storage_interface* get_storage_impl() const;
|
||||||
|
|
||||||
// all these are deprecated, use piece
|
// all these are deprecated, use piece
|
||||||
// priority functions instead
|
// priority functions instead
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void fail(int code, char const* msg);
|
void fail(int code, char const* msg);
|
||||||
void fail_timeout();
|
void fail_timeout();
|
||||||
|
virtual void start() = 0;
|
||||||
virtual void close();
|
virtual void close();
|
||||||
address const& bind_interface() const { return m_bind_interface; }
|
address const& bind_interface() const { return m_bind_interface; }
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ namespace libtorrent
|
||||||
, session_settings const& stn
|
, session_settings const& stn
|
||||||
, proxy_settings const& ps);
|
, proxy_settings const& ps);
|
||||||
|
|
||||||
|
void start();
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -74,8 +74,9 @@ namespace libtorrent {
|
||||||
xt.sec += 1;
|
xt.sec += 1;
|
||||||
}
|
}
|
||||||
xt.nsec = boost::xtime::xtime_nsec_t(nsec);
|
xt.nsec = boost::xtime::xtime_nsec_t(nsec);
|
||||||
|
// apparently this call can be interrupted
|
||||||
|
// prematurely if there are other signals
|
||||||
if (!m_condition.timed_wait(lock, xt)) return 0;
|
if (!m_condition.timed_wait(lock, xt)) return 0;
|
||||||
TORRENT_ASSERT(!m_alerts.empty());
|
|
||||||
if (m_alerts.empty()) return 0;
|
if (m_alerts.empty()) return 0;
|
||||||
return m_alerts.front();
|
return m_alerts.front();
|
||||||
}
|
}
|
||||||
|
|
|
@ -945,7 +945,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "got bitfield with invalid size: " << (packet_size() - 1)
|
msg << "got bitfield with invalid size: " << (packet_size() - 1)
|
||||||
<< "bytes. expected: " << ((t->torrent_file().num_pieces() + 7) / 8)
|
<< " bytes. expected: " << ((t->torrent_file().num_pieces() + 7) / 8)
|
||||||
<< " bytes";
|
<< " bytes";
|
||||||
disconnect(msg.str().c_str(), 2);
|
disconnect(msg.str().c_str(), 2);
|
||||||
return;
|
return;
|
||||||
|
@ -1444,7 +1444,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
// don't send a bitfield if we don't have any pieces
|
// don't send a bitfield if we don't have any pieces
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
(*m_logger) << time_now_string() << " *** NOT SENDING BITFIELD";
|
(*m_logger) << time_now_string() << " *** NOT SENDING BITFIELD\n";
|
||||||
#endif
|
#endif
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_sent_bitfield = true;
|
m_sent_bitfield = true;
|
||||||
|
|
|
@ -79,11 +79,19 @@ namespace libtorrent
|
||||||
, std::string const& auth)
|
, std::string const& auth)
|
||||||
: tracker_connection(man, req, ios, bind_infc, c)
|
: tracker_connection(man, req, ios, bind_infc, c)
|
||||||
, m_man(man)
|
, m_man(man)
|
||||||
|
, m_settings(stn)
|
||||||
|
, m_bind_iface(bind_infc)
|
||||||
|
, m_ps(ps)
|
||||||
|
, m_cc(cc)
|
||||||
|
, m_ios(ios)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void http_tracker_connection::start()
|
||||||
{
|
{
|
||||||
// TODO: authentication
|
// TODO: authentication
|
||||||
std::string url = req.url;
|
std::string url = tracker_req().url;
|
||||||
|
|
||||||
if (req.kind == tracker_request::scrape_request)
|
if (tracker_req().kind == tracker_request::scrape_request)
|
||||||
{
|
{
|
||||||
// find and replace "announce" with "scrape"
|
// find and replace "announce" with "scrape"
|
||||||
// in request
|
// in request
|
||||||
|
@ -91,8 +99,8 @@ namespace libtorrent
|
||||||
std::size_t pos = url.find("announce");
|
std::size_t pos = url.find("announce");
|
||||||
if (pos == std::string::npos)
|
if (pos == std::string::npos)
|
||||||
{
|
{
|
||||||
//fail(-1, ("scrape is not available on url: '"
|
fail(-1, ("scrape is not available on url: '"
|
||||||
// + req.url +"'").c_str());
|
+ tracker_req().url +"'").c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
url.replace(pos, 8, "scrape");
|
url.replace(pos, 8, "scrape");
|
||||||
|
@ -109,70 +117,70 @@ namespace libtorrent
|
||||||
|
|
||||||
url += "info_hash=";
|
url += "info_hash=";
|
||||||
url += escape_string(
|
url += escape_string(
|
||||||
reinterpret_cast<const char*>(req.info_hash.begin()), 20);
|
reinterpret_cast<const char*>(tracker_req().info_hash.begin()), 20);
|
||||||
|
|
||||||
if (req.kind == tracker_request::announce_request)
|
if (tracker_req().kind == tracker_request::announce_request)
|
||||||
{
|
{
|
||||||
url += "&peer_id=";
|
url += "&peer_id=";
|
||||||
url += escape_string(
|
url += escape_string(
|
||||||
reinterpret_cast<const char*>(req.pid.begin()), 20);
|
reinterpret_cast<const char*>(tracker_req().pid.begin()), 20);
|
||||||
|
|
||||||
url += "&port=";
|
url += "&port=";
|
||||||
url += boost::lexical_cast<std::string>(req.listen_port);
|
url += boost::lexical_cast<std::string>(tracker_req().listen_port);
|
||||||
|
|
||||||
url += "&uploaded=";
|
url += "&uploaded=";
|
||||||
url += boost::lexical_cast<std::string>(req.uploaded);
|
url += boost::lexical_cast<std::string>(tracker_req().uploaded);
|
||||||
|
|
||||||
url += "&downloaded=";
|
url += "&downloaded=";
|
||||||
url += boost::lexical_cast<std::string>(req.downloaded);
|
url += boost::lexical_cast<std::string>(tracker_req().downloaded);
|
||||||
|
|
||||||
url += "&left=";
|
url += "&left=";
|
||||||
url += boost::lexical_cast<std::string>(req.left);
|
url += boost::lexical_cast<std::string>(tracker_req().left);
|
||||||
|
|
||||||
if (req.event != tracker_request::none)
|
if (tracker_req().event != tracker_request::none)
|
||||||
{
|
{
|
||||||
const char* event_string[] = {"completed", "started", "stopped"};
|
const char* event_string[] = {"completed", "started", "stopped"};
|
||||||
url += "&event=";
|
url += "&event=";
|
||||||
url += event_string[req.event - 1];
|
url += event_string[tracker_req().event - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
url += "&key=";
|
url += "&key=";
|
||||||
std::stringstream key_string;
|
std::stringstream key_string;
|
||||||
key_string << std::hex << req.key;
|
key_string << std::hex << tracker_req().key;
|
||||||
url += key_string.str();
|
url += key_string.str();
|
||||||
|
|
||||||
url += "&compact=1";
|
url += "&compact=1";
|
||||||
|
|
||||||
url += "&numwant=";
|
url += "&numwant=";
|
||||||
url += boost::lexical_cast<std::string>(
|
url += boost::lexical_cast<std::string>(
|
||||||
(std::min)(req.num_want, 999));
|
(std::min)(tracker_req().num_want, 999));
|
||||||
|
|
||||||
if (stn.announce_ip != address())
|
if (m_settings.announce_ip != address())
|
||||||
{
|
{
|
||||||
url += "&ip=";
|
url += "&ip=";
|
||||||
url += stn.announce_ip.to_string();
|
url += m_settings.announce_ip.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
url += "&supportcrypto=1";
|
url += "&supportcrypto=1";
|
||||||
#endif
|
#endif
|
||||||
url += "&ipv6=";
|
url += "&ipv6=";
|
||||||
url += req.ipv6;
|
url += tracker_req().ipv6;
|
||||||
|
|
||||||
// extension that tells the tracker that
|
// extension that tells the tracker that
|
||||||
// we don't need any peer_id's in the response
|
// we don't need any peer_id's in the response
|
||||||
url += "&no_peer_id=1";
|
url += "&no_peer_id=1";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_tracker_connection.reset(new http_connection(ios, cc
|
m_tracker_connection.reset(new http_connection(m_ios, m_cc
|
||||||
, boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4)));
|
, boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4)));
|
||||||
|
|
||||||
int timeout = req.event==tracker_request::stopped
|
int timeout = tracker_req().event==tracker_request::stopped
|
||||||
?stn.stop_tracker_timeout
|
?m_settings.stop_tracker_timeout
|
||||||
:stn.tracker_completion_timeout;
|
:m_settings.tracker_completion_timeout;
|
||||||
|
|
||||||
m_tracker_connection->get(url, seconds(timeout)
|
m_tracker_connection->get(url, seconds(timeout)
|
||||||
, 1, &ps, 5, stn.user_agent, bind_infc);
|
, 1, &m_ps, 5, m_settings.user_agent, m_bind_iface);
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
|
||||||
|
|
|
@ -83,21 +83,6 @@ namespace
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::optional<node_id> read_id(libtorrent::entry const& d)
|
|
||||||
{
|
|
||||||
using namespace libtorrent;
|
|
||||||
using libtorrent::dht::node_id;
|
|
||||||
|
|
||||||
if (d.type() != entry::dictionary_t) return boost::optional<node_id>();
|
|
||||||
entry const* nid = d.find_key("node-id");
|
|
||||||
if (!nid
|
|
||||||
|| nid->type() != entry::string_t
|
|
||||||
|| nid->string().length() != 40)
|
|
||||||
return boost::optional<node_id>();
|
|
||||||
return boost::optional<node_id>(
|
|
||||||
boost::lexical_cast<node_id>(nid->string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EndpointType>
|
template <class EndpointType>
|
||||||
void read_endpoint_list(libtorrent::entry const* n, std::vector<EndpointType>& epl)
|
void read_endpoint_list(libtorrent::entry const* n, std::vector<EndpointType>& epl)
|
||||||
{
|
{
|
||||||
|
@ -142,10 +127,8 @@ namespace libtorrent { namespace dht
|
||||||
|
|
||||||
// class that puts the networking and the kademlia node in a single
|
// class that puts the networking and the kademlia node in a single
|
||||||
// unit and connecting them together.
|
// unit and connecting them together.
|
||||||
dht_tracker::dht_tracker(udp_socket& sock, dht_settings const& settings
|
dht_tracker::dht_tracker(udp_socket& sock, dht_settings const& settings)
|
||||||
, entry const& bootstrap)
|
: m_dht(bind(&dht_tracker::send_packet, this, _1), settings)
|
||||||
: m_dht(bind(&dht_tracker::send_packet, this, _1), settings
|
|
||||||
, read_id(bootstrap))
|
|
||||||
, m_sock(sock)
|
, m_sock(sock)
|
||||||
, m_last_new_key(time_now() - minutes(key_refresh))
|
, m_last_new_key(time_now() - minutes(key_refresh))
|
||||||
, m_timer(sock.get_io_service())
|
, m_timer(sock.get_io_service())
|
||||||
|
@ -185,6 +168,10 @@ namespace libtorrent { namespace dht
|
||||||
// dht_tracker_log.enable(false);
|
// dht_tracker_log.enable(false);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void dht_tracker::start(entry const& bootstrap)
|
||||||
|
{
|
||||||
std::vector<udp::endpoint> initial_nodes;
|
std::vector<udp::endpoint> initial_nodes;
|
||||||
|
|
||||||
if (bootstrap.type() == entry::dictionary_t)
|
if (bootstrap.type() == entry::dictionary_t)
|
||||||
|
@ -194,6 +181,12 @@ namespace libtorrent { namespace dht
|
||||||
if (entry const* nodes = bootstrap.find_key("nodes"))
|
if (entry const* nodes = bootstrap.find_key("nodes"))
|
||||||
read_endpoint_list<udp::endpoint>(nodes, initial_nodes);
|
read_endpoint_list<udp::endpoint>(nodes, initial_nodes);
|
||||||
} catch (std::exception&) {}
|
} catch (std::exception&) {}
|
||||||
|
|
||||||
|
entry const* nid = bootstrap.find_key("node-id");
|
||||||
|
if (nid
|
||||||
|
&& nid->type() == entry::string_t
|
||||||
|
&& nid->string().length() == 40)
|
||||||
|
m_dht.set_node_id(boost::lexical_cast<node_id>(nid->string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_timer.expires_from_now(seconds(1));
|
m_timer.expires_from_now(seconds(1));
|
||||||
|
@ -465,6 +458,8 @@ namespace libtorrent { namespace dht
|
||||||
m.transaction_id = e["t"].string();
|
m.transaction_id = e["t"].string();
|
||||||
|
|
||||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||||
|
log_line << " t: " << to_hex(m.transaction_id);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
entry const* ver = e.find_key("v");
|
entry const* ver = e.find_key("v");
|
||||||
|
@ -512,8 +507,7 @@ namespace libtorrent { namespace dht
|
||||||
if (msg_type == "r")
|
if (msg_type == "r")
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||||
log_line << " r: " << messages::ids[m.message_id]
|
log_line << " r: " << messages::ids[m.message_id];
|
||||||
<< " t: " << to_hex(m.transaction_id);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m.reply = true;
|
m.reply = true;
|
||||||
|
@ -616,7 +610,7 @@ namespace libtorrent { namespace dht
|
||||||
if (target.size() != 20) throw std::runtime_error("invalid size of target id");
|
if (target.size() != 20) throw std::runtime_error("invalid size of target id");
|
||||||
std::copy(target.begin(), target.end(), m.info_hash.begin());
|
std::copy(target.begin(), target.end(), m.info_hash.begin());
|
||||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||||
log_line << " t: " << boost::lexical_cast<std::string>(m.info_hash);
|
log_line << " target: " << boost::lexical_cast<std::string>(m.info_hash);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m.message_id = libtorrent::dht::messages::find_node;
|
m.message_id = libtorrent::dht::messages::find_node;
|
||||||
|
|
|
@ -91,9 +91,9 @@ void purge_peers(std::set<peer_entry>& peers)
|
||||||
void nop() {}
|
void nop() {}
|
||||||
|
|
||||||
node_impl::node_impl(boost::function<void(msg const&)> const& f
|
node_impl::node_impl(boost::function<void(msg const&)> const& f
|
||||||
, dht_settings const& settings, boost::optional<node_id> node_id)
|
, dht_settings const& settings)
|
||||||
: m_settings(settings)
|
: m_settings(settings)
|
||||||
, m_id(node_id ? *node_id : generate_id())
|
, m_id(generate_id())
|
||||||
, m_table(m_id, 8, settings)
|
, m_table(m_id, 8, settings)
|
||||||
, m_rpc(bind(&node_impl::incoming_request, this, _1)
|
, m_rpc(bind(&node_impl::incoming_request, this, _1)
|
||||||
, m_id, m_table, f)
|
, m_id, m_table, f)
|
||||||
|
|
|
@ -572,6 +572,50 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int peer_connection::picker_options() const
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
|
TORRENT_ASSERT(t);
|
||||||
|
if (!t) return 0;
|
||||||
|
|
||||||
|
if (t->is_sequential_download())
|
||||||
|
{
|
||||||
|
ret |= piece_picker::sequential;
|
||||||
|
}
|
||||||
|
else if (t->num_have() < t->settings().initial_picker_threshold)
|
||||||
|
{
|
||||||
|
// if we have fewer pieces than a certain threshols
|
||||||
|
// don't pick rare pieces, just pick random ones,
|
||||||
|
// and prioritize finishing them
|
||||||
|
ret |= piece_picker::prioritize_partials;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret |= piece_picker::rarest_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_snubbed)
|
||||||
|
{
|
||||||
|
// snubbed peers should request
|
||||||
|
// the common pieces first, just to make
|
||||||
|
// it more likely for all snubbed peers to
|
||||||
|
// request blocks from the same piece
|
||||||
|
ret |= piece_picker::reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->settings().prioritize_partial_pieces)
|
||||||
|
ret |= piece_picker::prioritize_partials;
|
||||||
|
|
||||||
|
if (on_parole()) ret |= piece_picker::on_parole
|
||||||
|
| piece_picker::prioritize_partials;
|
||||||
|
|
||||||
|
// only one of rarest_first, common_first and sequential can be set.
|
||||||
|
TORRENT_ASSERT(bool(ret & piece_picker::rarest_first)
|
||||||
|
+ bool(ret & piece_picker::sequential) <= 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void peer_connection::fast_reconnect(bool r)
|
void peer_connection::fast_reconnect(bool r)
|
||||||
{
|
{
|
||||||
if (!peer_info_struct() || peer_info_struct()->fast_reconnects > 1)
|
if (!peer_info_struct() || peer_info_struct()->fast_reconnects > 1)
|
||||||
|
@ -1129,6 +1173,8 @@ namespace libtorrent
|
||||||
<< " <== HAVE [ piece: " << index << "]\n";
|
<< " <== HAVE [ piece: " << index << "]\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (is_disconnecting()) return;
|
||||||
|
|
||||||
if (!t->valid_metadata() && index > int(m_have_piece.size()))
|
if (!t->valid_metadata() && index > int(m_have_piece.size()))
|
||||||
{
|
{
|
||||||
if (index < 65536)
|
if (index < 65536)
|
||||||
|
@ -1343,6 +1389,7 @@ namespace libtorrent
|
||||||
// if we haven't received a bitfield, it was
|
// if we haven't received a bitfield, it was
|
||||||
// probably omitted, which is the same as 'have_none'
|
// probably omitted, which is the same as 'have_none'
|
||||||
if (!m_bitfield_received) incoming_have_none();
|
if (!m_bitfield_received) incoming_have_none();
|
||||||
|
if (is_disconnecting()) return;
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
for (extension_list_t::iterator i = m_extensions.begin()
|
for (extension_list_t::iterator i = m_extensions.begin()
|
||||||
|
@ -1549,6 +1596,7 @@ namespace libtorrent
|
||||||
// if we haven't received a bitfield, it was
|
// if we haven't received a bitfield, it was
|
||||||
// probably omitted, which is the same as 'have_none'
|
// probably omitted, which is the same as 'have_none'
|
||||||
if (!m_bitfield_received) incoming_have_none();
|
if (!m_bitfield_received) incoming_have_none();
|
||||||
|
if (is_disconnecting()) return;
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
for (extension_list_t::iterator i = m_extensions.begin()
|
for (extension_list_t::iterator i = m_extensions.begin()
|
||||||
|
@ -1572,7 +1620,7 @@ namespace libtorrent
|
||||||
"s: " << p.start << " | "
|
"s: " << p.start << " | "
|
||||||
"l: " << p.length << " | "
|
"l: " << p.length << " | "
|
||||||
"ds: " << statistics().download_rate() << " | "
|
"ds: " << statistics().download_rate() << " | "
|
||||||
"qs: " << m_desired_queue_size << " ]\n";
|
"qs: " << int(m_desired_queue_size) << " ]\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (p.length == 0)
|
if (p.length == 0)
|
||||||
|
@ -1639,7 +1687,7 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int block_index = b - m_download_queue.begin();
|
int block_index = b - m_download_queue.begin() - 1;
|
||||||
for (int i = 0; i < block_index; ++i)
|
for (int i = 0; i < block_index; ++i)
|
||||||
{
|
{
|
||||||
pending_block& qe = m_download_queue[i];
|
pending_block& qe = m_download_queue[i];
|
||||||
|
@ -1660,6 +1708,7 @@ namespace libtorrent
|
||||||
m_ses.m_alerts.post_alert(request_dropped_alert(t->get_handle()
|
m_ses.m_alerts.post_alert(request_dropped_alert(t->get_handle()
|
||||||
, remote(), pid(), qe.block.block_index, qe.block.piece_index));
|
, remote(), pid(), qe.block.block_index, qe.block.piece_index));
|
||||||
picker.abort_download(qe.block);
|
picker.abort_download(qe.block);
|
||||||
|
TORRENT_ASSERT(m_download_queue.begin() + i != b);
|
||||||
m_download_queue.erase(m_download_queue.begin() + i);
|
m_download_queue.erase(m_download_queue.begin() + i);
|
||||||
--i;
|
--i;
|
||||||
--block_index;
|
--block_index;
|
||||||
|
@ -1723,9 +1772,12 @@ namespace libtorrent
|
||||||
bool multi = picker.num_peers(block_finished) > 1;
|
bool multi = picker.num_peers(block_finished) > 1;
|
||||||
picker.mark_as_writing(block_finished, peer_info_struct());
|
picker.mark_as_writing(block_finished, peer_info_struct());
|
||||||
|
|
||||||
|
TORRENT_ASSERT(picker.num_peers(block_finished) == 0);
|
||||||
// if we requested this block from other peers, cancel it now
|
// if we requested this block from other peers, cancel it now
|
||||||
if (multi) t->cancel_block(block_finished);
|
if (multi) t->cancel_block(block_finished);
|
||||||
|
|
||||||
|
TORRENT_ASSERT(picker.num_peers(block_finished) == 0);
|
||||||
|
|
||||||
#if !defined NDEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
|
#if !defined NDEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
|
||||||
t->check_invariant();
|
t->check_invariant();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1776,6 +1828,7 @@ namespace libtorrent
|
||||||
|
|
||||||
TORRENT_ASSERT(p.piece == j.piece);
|
TORRENT_ASSERT(p.piece == j.piece);
|
||||||
TORRENT_ASSERT(p.start == j.offset);
|
TORRENT_ASSERT(p.start == j.offset);
|
||||||
|
TORRENT_ASSERT(picker.num_peers(block_finished) == 0);
|
||||||
picker.mark_as_finished(block_finished, peer_info_struct());
|
picker.mark_as_finished(block_finished, peer_info_struct());
|
||||||
if (t->alerts().should_post<block_finished_alert>())
|
if (t->alerts().should_post<block_finished_alert>())
|
||||||
{
|
{
|
||||||
|
@ -2332,7 +2385,7 @@ namespace libtorrent
|
||||||
"s: " << r.start << " | "
|
"s: " << r.start << " | "
|
||||||
"l: " << r.length << " | "
|
"l: " << r.length << " | "
|
||||||
"ds: " << statistics().download_rate() << " B/s | "
|
"ds: " << statistics().download_rate() << " B/s | "
|
||||||
"qs: " << m_desired_queue_size << " "
|
"qs: " << int(m_desired_queue_size) << " "
|
||||||
"blk: " << (m_request_large_blocks?"large":"single") << " ]\n";
|
"blk: " << (m_request_large_blocks?"large":"single") << " ]\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3898,7 +3951,7 @@ namespace libtorrent
|
||||||
m_speed = medium;
|
m_speed = medium;
|
||||||
else if (download_rate < torrent_download_rate / 15 && m_speed == fast)
|
else if (download_rate < torrent_download_rate / 15 && m_speed == fast)
|
||||||
m_speed = medium;
|
m_speed = medium;
|
||||||
else if (download_rate < torrent_download_rate / 63 && m_speed == medium)
|
else
|
||||||
m_speed = slow;
|
m_speed = slow;
|
||||||
|
|
||||||
return m_speed;
|
return m_speed;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -200,8 +200,6 @@ namespace libtorrent
|
||||||
|
|
||||||
int prefer_whole_pieces = c.prefer_whole_pieces();
|
int prefer_whole_pieces = c.prefer_whole_pieces();
|
||||||
|
|
||||||
bool rarest_first = t.num_have() >= t.settings().initial_picker_threshold;
|
|
||||||
|
|
||||||
if (prefer_whole_pieces == 0)
|
if (prefer_whole_pieces == 0)
|
||||||
{
|
{
|
||||||
prefer_whole_pieces = c.statistics().download_payload_rate()
|
prefer_whole_pieces = c.statistics().download_payload_rate()
|
||||||
|
@ -250,7 +248,7 @@ namespace libtorrent
|
||||||
|
|
||||||
p.pick_pieces(mask, interesting_pieces
|
p.pick_pieces(mask, interesting_pieces
|
||||||
, num_requests, prefer_whole_pieces, c.peer_info_struct()
|
, num_requests, prefer_whole_pieces, c.peer_info_struct()
|
||||||
, state, rarest_first, c.on_parole(), suggested);
|
, state, c.picker_options(), suggested);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -264,7 +262,7 @@ namespace libtorrent
|
||||||
// then use this mode.
|
// then use this mode.
|
||||||
p.pick_pieces(bits, interesting_pieces
|
p.pick_pieces(bits, interesting_pieces
|
||||||
, num_requests, prefer_whole_pieces, c.peer_info_struct()
|
, num_requests, prefer_whole_pieces, c.peer_info_struct()
|
||||||
, state, rarest_first, c.on_parole(), suggested);
|
, state, c.picker_options(), suggested);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
|
@ -303,10 +301,6 @@ namespace libtorrent
|
||||||
|
|
||||||
if (busy_pieces.empty() || num_requests <= 0)
|
if (busy_pieces.empty() || num_requests <= 0)
|
||||||
{
|
{
|
||||||
// in this case, we could not find any blocks
|
|
||||||
// that was free. If we couldn't find any busy
|
|
||||||
// blocks as well, we cannot download anything
|
|
||||||
// more from this peer.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1494,6 +1494,8 @@ namespace aux {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_allowed_upload_slots > 0)
|
||||||
|
{
|
||||||
m_optimistic_unchoke_time_scaler--;
|
m_optimistic_unchoke_time_scaler--;
|
||||||
if (m_optimistic_unchoke_time_scaler <= 0)
|
if (m_optimistic_unchoke_time_scaler <= 0)
|
||||||
{
|
{
|
||||||
|
@ -1528,7 +1530,8 @@ namespace aux {
|
||||||
&& !p->is_disconnecting()
|
&& !p->is_disconnecting()
|
||||||
&& p->is_peer_interested()
|
&& p->is_peer_interested()
|
||||||
&& t->free_upload_slots()
|
&& t->free_upload_slots()
|
||||||
&& p->is_choked())
|
&& p->is_choked()
|
||||||
|
&& t->valid_metadata())
|
||||||
{
|
{
|
||||||
last_unchoke = pi->last_optimistically_unchoked;
|
last_unchoke = pi->last_optimistically_unchoked;
|
||||||
optimistic_unchoke_candidate = i;
|
optimistic_unchoke_candidate = i;
|
||||||
|
@ -1558,6 +1561,7 @@ namespace aux {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void session_impl::operator()()
|
void session_impl::operator()()
|
||||||
{
|
{
|
||||||
|
@ -2046,11 +2050,20 @@ namespace aux {
|
||||||
, m_dht_settings.service_port
|
, m_dht_settings.service_port
|
||||||
, m_dht_settings.service_port);
|
, m_dht_settings.service_port);
|
||||||
}
|
}
|
||||||
m_dht = new dht::dht_tracker(m_dht_socket, m_dht_settings, startup_state);
|
m_dht = new dht::dht_tracker(m_dht_socket, m_dht_settings);
|
||||||
if (!m_dht_socket.is_open() || m_dht_socket.local_port() != m_dht_settings.service_port)
|
if (!m_dht_socket.is_open() || m_dht_socket.local_port() != m_dht_settings.service_port)
|
||||||
{
|
{
|
||||||
m_dht_socket.bind(m_dht_settings.service_port);
|
m_dht_socket.bind(m_dht_settings.service_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::list<std::pair<std::string, int> >::iterator i = m_dht_router_nodes.begin()
|
||||||
|
, end(m_dht_router_nodes.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
m_dht->add_router_node(*i);
|
||||||
|
}
|
||||||
|
std::list<std::pair<std::string, int> >().swap(m_dht_router_nodes);
|
||||||
|
|
||||||
|
m_dht->start(startup_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::stop_dht()
|
void session_impl::stop_dht()
|
||||||
|
@ -2114,9 +2127,10 @@ namespace aux {
|
||||||
|
|
||||||
void session_impl::add_dht_router(std::pair<std::string, int> const& node)
|
void session_impl::add_dht_router(std::pair<std::string, int> const& node)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_dht);
|
// router nodes should be added before the DHT is started (and bootstrapped)
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
m_dht->add_router_node(node);
|
if (m_dht) m_dht->add_router_node(node);
|
||||||
|
else m_dht_router_nodes.push_back(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2167,7 +2181,7 @@ namespace aux {
|
||||||
|
|
||||||
void session_impl::set_max_uploads(int limit)
|
void session_impl::set_max_uploads(int limit)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(limit > 0 || limit == -1);
|
TORRENT_ASSERT(limit >= 0 || limit == -1);
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
|
@ -754,10 +754,14 @@ namespace libtorrent
|
||||||
|
|
||||||
m_progress = j.piece / float(torrent_file().num_pieces());
|
m_progress = j.piece / float(torrent_file().num_pieces());
|
||||||
|
|
||||||
|
m_picker->check_invariant();
|
||||||
|
|
||||||
TORRENT_ASSERT(m_picker);
|
TORRENT_ASSERT(m_picker);
|
||||||
if (j.offset >= 0 && !m_picker->have_piece(j.offset))
|
if (j.offset >= 0 && !m_picker->have_piece(j.offset))
|
||||||
m_picker->we_have(j.offset);
|
m_picker->we_have(j.offset);
|
||||||
|
|
||||||
|
m_picker->check_invariant();
|
||||||
|
|
||||||
// we're not done checking yet
|
// we're not done checking yet
|
||||||
// this handler will be called repeatedly until
|
// this handler will be called repeatedly until
|
||||||
// we're done, or encounter a failure
|
// we're done, or encounter a failure
|
||||||
|
@ -3298,9 +3302,6 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!is_seed())
|
if (!is_seed())
|
||||||
{
|
{
|
||||||
if (m_sequential_download)
|
|
||||||
picker().sequential_download(m_sequential_download);
|
|
||||||
|
|
||||||
// if we just finished checking and we're not a seed, we are
|
// if we just finished checking and we're not a seed, we are
|
||||||
// likely to be unpaused
|
// likely to be unpaused
|
||||||
if (m_ses.m_auto_manage_time_scaler > 1)
|
if (m_ses.m_auto_manage_time_scaler > 1)
|
||||||
|
@ -3549,13 +3550,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void torrent::set_sequential_download(bool sd)
|
void torrent::set_sequential_download(bool sd)
|
||||||
{
|
{ m_sequential_download = sd; }
|
||||||
m_sequential_download = sd;
|
|
||||||
if (has_picker())
|
|
||||||
{
|
|
||||||
picker().sequential_download(sd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void torrent::set_queue_position(int p)
|
void torrent::set_queue_position(int p)
|
||||||
{
|
{
|
||||||
|
|
|
@ -499,6 +499,12 @@ namespace libtorrent
|
||||||
TORRENT_FORWARD(replace_trackers(urls));
|
TORRENT_FORWARD(replace_trackers(urls));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storage_interface* torrent_handle::get_storage_impl() const
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
TORRENT_FORWARD_RETURN(get_storage(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
torrent_info const& torrent_handle::get_torrent_info() const
|
torrent_info const& torrent_handle::get_torrent_info() const
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
|
@ -229,6 +229,7 @@ namespace libtorrent
|
||||||
|
|
||||||
boost::shared_ptr<request_callback> cb = con->requester();
|
boost::shared_ptr<request_callback> cb = con->requester();
|
||||||
if (cb) cb->m_manager = this;
|
if (cb) cb->m_manager = this;
|
||||||
|
con->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tracker_manager::abort_all_requests()
|
void tracker_manager::abort_all_requests()
|
||||||
|
|
|
@ -93,14 +93,17 @@ namespace libtorrent
|
||||||
, m_state(action_error)
|
, m_state(action_error)
|
||||||
{
|
{
|
||||||
m_socket.set_proxy_settings(proxy);
|
m_socket.set_proxy_settings(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void udp_tracker_connection::start()
|
||||||
|
{
|
||||||
std::string hostname;
|
std::string hostname;
|
||||||
int port;
|
int port;
|
||||||
char const* error;
|
char const* error;
|
||||||
|
|
||||||
using boost::tuples::ignore;
|
using boost::tuples::ignore;
|
||||||
boost::tie(ignore, ignore, hostname, port, ignore, error)
|
boost::tie(ignore, ignore, hostname, port, ignore, error)
|
||||||
= parse_url_components(req.url);
|
= parse_url_components(tracker_req().url);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +115,7 @@ namespace libtorrent
|
||||||
m_name_lookup.async_resolve(q
|
m_name_lookup.async_resolve(q
|
||||||
, boost::bind(
|
, boost::bind(
|
||||||
&udp_tracker_connection::name_lookup, self(), _1, _2));
|
&udp_tracker_connection::name_lookup, self(), _1, _2));
|
||||||
set_timeout(req.event == tracker_request::stopped
|
set_timeout(tracker_req().event == tracker_request::stopped
|
||||||
? m_settings.stop_tracker_timeout
|
? m_settings.stop_tracker_timeout
|
||||||
: m_settings.tracker_completion_timeout
|
: m_settings.tracker_completion_timeout
|
||||||
, m_settings.tracker_receive_timeout);
|
, m_settings.tracker_receive_timeout);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue