mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-15 23:08:41 +00:00
revert libtorrent updates
This commit is contained in:
parent
3733b91d32
commit
9ecb8a388d
27 changed files with 476 additions and 512 deletions
|
@ -178,7 +178,9 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
friend struct checker_impl;
|
friend struct checker_impl;
|
||||||
friend class invariant_access;
|
friend class invariant_access;
|
||||||
typedef std::set<boost::intrusive_ptr<peer_connection> > connection_map;
|
typedef std::map<boost::shared_ptr<socket_type>
|
||||||
|
, boost::intrusive_ptr<peer_connection> >
|
||||||
|
connection_map;
|
||||||
typedef std::map<sha1_hash, boost::shared_ptr<torrent> > torrent_map;
|
typedef std::map<sha1_hash, boost::shared_ptr<torrent> > torrent_map;
|
||||||
|
|
||||||
session_impl(
|
session_impl(
|
||||||
|
@ -188,8 +190,7 @@ namespace libtorrent
|
||||||
~session_impl();
|
~session_impl();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(
|
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext);
|
||||||
torrent*, void*)> ext);
|
|
||||||
#endif
|
#endif
|
||||||
void operator()();
|
void operator()();
|
||||||
|
|
||||||
|
@ -213,7 +214,7 @@ namespace libtorrent
|
||||||
peer_id const& get_peer_id() const { return m_peer_id; }
|
peer_id const& get_peer_id() const { return m_peer_id; }
|
||||||
|
|
||||||
void close_connection(boost::intrusive_ptr<peer_connection> const& p);
|
void close_connection(boost::intrusive_ptr<peer_connection> const& p);
|
||||||
void connection_failed(boost::intrusive_ptr<peer_connection> const& p
|
void connection_failed(boost::shared_ptr<socket_type> const& s
|
||||||
, tcp::endpoint const& a, char const* message);
|
, tcp::endpoint const& a, char const* message);
|
||||||
|
|
||||||
void set_settings(session_settings const& s);
|
void set_settings(session_settings const& s);
|
||||||
|
@ -341,8 +342,8 @@ namespace libtorrent
|
||||||
for (connection_map::const_iterator i = m_connections.begin()
|
for (connection_map::const_iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end; ++i)
|
, end(m_connections.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
send_buffer_capacity += (*i)->send_buffer_capacity();
|
send_buffer_capacity += i->second->send_buffer_capacity();
|
||||||
used_send_buffer += (*i)->send_buffer_size();
|
used_send_buffer += i->second->send_buffer_size();
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(send_buffer_capacity >= used_send_buffer);
|
TORRENT_ASSERT(send_buffer_capacity >= used_send_buffer);
|
||||||
m_buffer_usage_logger << log_time() << " send_buffer_size: " << send_buffer_capacity << std::endl;
|
m_buffer_usage_logger << log_time() << " send_buffer_size: " << send_buffer_capacity << std::endl;
|
||||||
|
@ -374,6 +375,12 @@ namespace libtorrent
|
||||||
// buffers from.
|
// buffers from.
|
||||||
boost::pool<> m_send_buffers;
|
boost::pool<> m_send_buffers;
|
||||||
|
|
||||||
|
// this is where all active sockets are stored.
|
||||||
|
// the selector can sleep while there's no activity on
|
||||||
|
// them
|
||||||
|
io_service m_io_service;
|
||||||
|
asio::strand m_strand;
|
||||||
|
|
||||||
// the file pool that all storages in this session's
|
// the file pool that all storages in this session's
|
||||||
// torrents uses. It sets a limit on the number of
|
// torrents uses. It sets a limit on the number of
|
||||||
// open files by this session.
|
// open files by this session.
|
||||||
|
@ -385,17 +392,9 @@ namespace libtorrent
|
||||||
// handles disk io requests asynchronously
|
// handles disk io requests asynchronously
|
||||||
// peers have pointers into the disk buffer
|
// peers have pointers into the disk buffer
|
||||||
// pool, and must be destructed before this
|
// pool, and must be destructed before this
|
||||||
// object. The disk thread relies on the file
|
// object.
|
||||||
// pool object, and must be destructed before
|
|
||||||
// m_files.
|
|
||||||
disk_io_thread m_disk_thread;
|
disk_io_thread m_disk_thread;
|
||||||
|
|
||||||
// this is where all active sockets are stored.
|
|
||||||
// the selector can sleep while there's no activity on
|
|
||||||
// them
|
|
||||||
io_service m_io_service;
|
|
||||||
asio::strand m_strand;
|
|
||||||
|
|
||||||
// this is a list of half-open tcp connections
|
// this is a list of half-open tcp connections
|
||||||
// (only outgoing connections)
|
// (only outgoing connections)
|
||||||
// this has to be one of the last
|
// this has to be one of the last
|
||||||
|
@ -647,7 +646,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void debug_log(const std::string& line)
|
void debug_log(const std::string& line)
|
||||||
{
|
{
|
||||||
(*m_ses.m_logger) << time_now_string() << " " << line << "\n";
|
(*m_ses.m_logger) << line << "\n";
|
||||||
}
|
}
|
||||||
session_impl& m_ses;
|
session_impl& m_ses;
|
||||||
};
|
};
|
||||||
|
|
|
@ -135,38 +135,26 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class InIt>
|
template <class InIt>
|
||||||
std::string read_until(InIt& in, InIt end, char end_token, bool& err)
|
std::string read_until(InIt& in, InIt end, char end_token)
|
||||||
{
|
{
|
||||||
|
if (in == end) throw invalid_encoding();
|
||||||
std::string ret;
|
std::string ret;
|
||||||
if (in == end)
|
|
||||||
{
|
|
||||||
err = true;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
while (*in != end_token)
|
while (*in != end_token)
|
||||||
{
|
{
|
||||||
ret += *in;
|
ret += *in;
|
||||||
++in;
|
++in;
|
||||||
if (in == end)
|
if (in == end) throw invalid_encoding();
|
||||||
{
|
|
||||||
err = true;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InIt>
|
template<class InIt>
|
||||||
void read_string(InIt& in, InIt end, int len, std::string& str, bool& err)
|
void read_string(InIt& in, InIt end, int len, std::string& str)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(len >= 0);
|
TORRENT_ASSERT(len >= 0);
|
||||||
for (int i = 0; i < len; ++i)
|
for (int i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
if (in == end)
|
if (in == end) throw invalid_encoding();
|
||||||
{
|
|
||||||
err = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
str += *in;
|
str += *in;
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
|
@ -214,13 +202,9 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InIt>
|
template<class InIt>
|
||||||
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err)
|
void bdecode_recursive(InIt& in, InIt end, entry& ret)
|
||||||
{
|
{
|
||||||
if (in == end)
|
if (in == end) throw invalid_encoding();
|
||||||
{
|
|
||||||
err = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (*in)
|
switch (*in)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -229,8 +213,7 @@ namespace libtorrent
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
++in; // 'i'
|
++in; // 'i'
|
||||||
std::string val = read_until(in, end, 'e', err);
|
std::string val = read_until(in, end, 'e');
|
||||||
if (err) return;
|
|
||||||
TORRENT_ASSERT(*in == 'e');
|
TORRENT_ASSERT(*in == 'e');
|
||||||
++in; // 'e'
|
++in; // 'e'
|
||||||
ret = entry(entry::int_t);
|
ret = entry(entry::int_t);
|
||||||
|
@ -247,13 +230,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
ret.list().push_back(entry());
|
ret.list().push_back(entry());
|
||||||
entry& e = ret.list().back();
|
entry& e = ret.list().back();
|
||||||
bdecode_recursive(in, end, e, err);
|
bdecode_recursive(in, end, e);
|
||||||
if (err) return;
|
if (in == end) throw invalid_encoding();
|
||||||
if (in == end)
|
|
||||||
{
|
|
||||||
err = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(*in == 'e');
|
TORRENT_ASSERT(*in == 'e');
|
||||||
++in; // 'e'
|
++in; // 'e'
|
||||||
|
@ -268,16 +246,10 @@ namespace libtorrent
|
||||||
while (*in != 'e')
|
while (*in != 'e')
|
||||||
{
|
{
|
||||||
entry key;
|
entry key;
|
||||||
bdecode_recursive(in, end, key, err);
|
bdecode_recursive(in, end, key);
|
||||||
if (err) return;
|
|
||||||
entry& e = ret[key.string()];
|
entry& e = ret[key.string()];
|
||||||
bdecode_recursive(in, end, e, err);
|
bdecode_recursive(in, end, e);
|
||||||
if (err) return;
|
if (in == end) throw invalid_encoding();
|
||||||
if (in == end)
|
|
||||||
{
|
|
||||||
err = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(*in == 'e');
|
TORRENT_ASSERT(*in == 'e');
|
||||||
++in; // 'e'
|
++in; // 'e'
|
||||||
|
@ -288,19 +260,16 @@ namespace libtorrent
|
||||||
default:
|
default:
|
||||||
if (isdigit((unsigned char)*in))
|
if (isdigit((unsigned char)*in))
|
||||||
{
|
{
|
||||||
std::string len_s = read_until(in, end, ':', err);
|
std::string len_s = read_until(in, end, ':');
|
||||||
if (err) return;
|
|
||||||
TORRENT_ASSERT(*in == ':');
|
TORRENT_ASSERT(*in == ':');
|
||||||
++in; // ':'
|
++in; // ':'
|
||||||
int len = std::atoi(len_s.c_str());
|
int len = std::atoi(len_s.c_str());
|
||||||
ret = entry(entry::string_t);
|
ret = entry(entry::string_t);
|
||||||
read_string(in, end, len, ret.string(), err);
|
read_string(in, end, len, ret.string());
|
||||||
if (err) return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err = true;
|
throw invalid_encoding();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,19 +284,17 @@ namespace libtorrent
|
||||||
template<class InIt>
|
template<class InIt>
|
||||||
entry bdecode(InIt start, InIt end)
|
entry bdecode(InIt start, InIt end)
|
||||||
{
|
{
|
||||||
entry e;
|
try
|
||||||
bool err = false;
|
|
||||||
detail::bdecode_recursive(start, end, e, err);
|
|
||||||
if (err)
|
|
||||||
{
|
{
|
||||||
#ifdef BOOST_NO_EXCEPTIONS
|
entry e;
|
||||||
return entry();
|
detail::bdecode_recursive(start, end, e);
|
||||||
#else
|
|
||||||
throw invalid_encoding();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
catch(type_error&)
|
||||||
|
{
|
||||||
|
throw invalid_encoding();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,6 @@ public:
|
||||||
void done(int ticket);
|
void done(int ticket);
|
||||||
void limit(int limit);
|
void limit(int limit);
|
||||||
int limit() const;
|
int limit() const;
|
||||||
void close();
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
||||||
|
|
|
@ -161,10 +161,8 @@ namespace libtorrent
|
||||||
// is a dictionary, otherwise they will throw
|
// is a dictionary, otherwise they will throw
|
||||||
entry& operator[](char const* key);
|
entry& operator[](char const* key);
|
||||||
entry& operator[](std::string const& key);
|
entry& operator[](std::string const& key);
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
const entry& operator[](char const* key) const;
|
const entry& operator[](char const* key) const;
|
||||||
const entry& operator[](std::string const& key) const;
|
const entry& operator[](std::string const& key) const;
|
||||||
#endif
|
|
||||||
entry* find_key(char const* key);
|
entry* find_key(char const* key);
|
||||||
entry const* find_key(char const* key) const;
|
entry const* find_key(char const* key) const;
|
||||||
|
|
||||||
|
@ -223,80 +221,55 @@ namespace libtorrent
|
||||||
copy(e);
|
copy(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline entry::integer_type& entry::integer()
|
inline entry::integer_type& entry::integer()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(int_t);
|
if (m_type == undefined_t) construct(int_t);
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == int_t);
|
|
||||||
return *reinterpret_cast<integer_type*>(data);
|
return *reinterpret_cast<integer_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::integer_type const& entry::integer() const
|
inline entry::integer_type const& entry::integer() const
|
||||||
{
|
{
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == int_t);
|
|
||||||
return *reinterpret_cast<const integer_type*>(data);
|
return *reinterpret_cast<const integer_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::string_type& entry::string()
|
inline entry::string_type& entry::string()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(string_t);
|
if (m_type == undefined_t) construct(string_t);
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == string_t);
|
|
||||||
return *reinterpret_cast<string_type*>(data);
|
return *reinterpret_cast<string_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::string_type const& entry::string() const
|
inline entry::string_type const& entry::string() const
|
||||||
{
|
{
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == string_t);
|
|
||||||
return *reinterpret_cast<const string_type*>(data);
|
return *reinterpret_cast<const string_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::list_type& entry::list()
|
inline entry::list_type& entry::list()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(list_t);
|
if (m_type == undefined_t) construct(list_t);
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == list_t);
|
|
||||||
return *reinterpret_cast<list_type*>(data);
|
return *reinterpret_cast<list_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::list_type const& entry::list() const
|
inline entry::list_type const& entry::list() const
|
||||||
{
|
{
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == list_t);
|
|
||||||
return *reinterpret_cast<const list_type*>(data);
|
return *reinterpret_cast<const list_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::dictionary_type& entry::dict()
|
inline entry::dictionary_type& entry::dict()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(dictionary_t);
|
if (m_type == undefined_t) construct(dictionary_t);
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == dictionary_t);
|
|
||||||
return *reinterpret_cast<dictionary_type*>(data);
|
return *reinterpret_cast<dictionary_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::dictionary_type const& entry::dict() const
|
inline entry::dictionary_type const& entry::dict() const
|
||||||
{
|
{
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
||||||
#endif
|
|
||||||
TORRENT_ASSERT(m_type == dictionary_t);
|
|
||||||
return *reinterpret_cast<const dictionary_type*>(data);
|
return *reinterpret_cast<const dictionary_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,8 +130,6 @@ namespace libtorrent
|
||||||
, proxy_settings const& ps
|
, proxy_settings const& ps
|
||||||
, std::string const& password = "");
|
, std::string const& password = "");
|
||||||
|
|
||||||
void close();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::intrusive_ptr<http_tracker_connection> self()
|
boost::intrusive_ptr<http_tracker_connection> self()
|
||||||
|
|
|
@ -367,12 +367,8 @@ namespace libtorrent
|
||||||
return boost::optional<piece_block_progress>();
|
return boost::optional<piece_block_progress>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// these functions are virtual to let bt_peer_connection hook into them
|
void send_buffer(char const* begin, int size);
|
||||||
// and encrypt the content
|
buffer::interval allocate_send_buffer(int size);
|
||||||
virtual void send_buffer(char const* begin, int size);
|
|
||||||
virtual buffer::interval allocate_send_buffer(int size);
|
|
||||||
virtual void setup_send();
|
|
||||||
|
|
||||||
template <class Destructor>
|
template <class Destructor>
|
||||||
void append_send_buffer(char* buffer, int size, Destructor const& destructor)
|
void append_send_buffer(char* buffer, int size, Destructor const& destructor)
|
||||||
{
|
{
|
||||||
|
@ -382,6 +378,7 @@ namespace libtorrent
|
||||||
m_ses.log_buffer_usage();
|
m_ses.log_buffer_usage();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
void setup_send();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||||
void set_country(char const* c)
|
void set_country(char const* c)
|
||||||
|
@ -469,6 +466,9 @@ namespace libtorrent
|
||||||
// the peer belongs to.
|
// the peer belongs to.
|
||||||
aux::session_impl& m_ses;
|
aux::session_impl& m_ses;
|
||||||
|
|
||||||
|
boost::intrusive_ptr<peer_connection> self()
|
||||||
|
{ return boost::intrusive_ptr<peer_connection>(this); }
|
||||||
|
|
||||||
// called from the main loop when this connection has any
|
// called from the main loop when this connection has any
|
||||||
// work to do.
|
// work to do.
|
||||||
void on_send_data(asio::error_code const& error
|
void on_send_data(asio::error_code const& error
|
||||||
|
|
|
@ -85,7 +85,6 @@ namespace libtorrent
|
||||||
// the tracker, pex, lsd or dht.
|
// the tracker, pex, lsd or dht.
|
||||||
policy::peer* peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid
|
policy::peer* peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid
|
||||||
, int source, char flags);
|
, int source, char flags);
|
||||||
void update_peer_port(int port, policy::peer* p, int src);
|
|
||||||
|
|
||||||
// called when an incoming connection is accepted
|
// called when an incoming connection is accepted
|
||||||
void new_connection(peer_connection& c);
|
void new_connection(peer_connection& c);
|
||||||
|
@ -220,8 +219,6 @@ namespace libtorrent
|
||||||
typedef std::multimap<address, peer>::const_iterator const_iterator;
|
typedef std::multimap<address, peer>::const_iterator const_iterator;
|
||||||
iterator begin_peer() { return m_peers.begin(); }
|
iterator begin_peer() { return m_peers.begin(); }
|
||||||
iterator end_peer() { return m_peers.end(); }
|
iterator end_peer() { return m_peers.end(); }
|
||||||
const_iterator begin_peer() const { return m_peers.begin(); }
|
|
||||||
const_iterator end_peer() const { return m_peers.end(); }
|
|
||||||
|
|
||||||
bool connect_one_peer();
|
bool connect_one_peer();
|
||||||
bool disconnect_one_peer();
|
bool disconnect_one_peer();
|
||||||
|
|
|
@ -171,7 +171,7 @@ namespace libtorrent
|
||||||
boost::tuples::tuple<size_type, size_type> bytes_done() const;
|
boost::tuples::tuple<size_type, size_type> bytes_done() const;
|
||||||
size_type quantized_bytes_done() const;
|
size_type quantized_bytes_done() const;
|
||||||
|
|
||||||
void ip_filter_updated() { m_policy.ip_filter_updated(); }
|
void ip_filter_updated() { m_policy->ip_filter_updated(); }
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
|
@ -204,7 +204,7 @@ namespace libtorrent
|
||||||
tcp::endpoint const& get_interface() const { return m_net_interface; }
|
tcp::endpoint const& get_interface() const { return m_net_interface; }
|
||||||
|
|
||||||
void connect_to_url_seed(std::string const& url);
|
void connect_to_url_seed(std::string const& url);
|
||||||
bool connect_to_peer(policy::peer* peerinfo) throw();
|
peer_connection* connect_to_peer(policy::peer* peerinfo);
|
||||||
|
|
||||||
void set_ratio(float ratio)
|
void set_ratio(float ratio)
|
||||||
{ TORRENT_ASSERT(ratio >= 0.0f); m_ratio = ratio; }
|
{ TORRENT_ASSERT(ratio >= 0.0f); m_ratio = ratio; }
|
||||||
|
@ -276,12 +276,31 @@ namespace libtorrent
|
||||||
bool want_more_peers() const;
|
bool want_more_peers() const;
|
||||||
bool try_connect_peer();
|
bool try_connect_peer();
|
||||||
|
|
||||||
|
peer_connection* connection_for(tcp::endpoint const& a)
|
||||||
|
{
|
||||||
|
peer_iterator i = m_connections.find(a);
|
||||||
|
if (i == m_connections.end()) return 0;
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
void connection_for(address const& a, std::vector<peer_connection*>& pc)
|
||||||
|
{
|
||||||
|
for (peer_iterator i = m_connections.begin()
|
||||||
|
, end(m_connections.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
if (i->first.address() == a) pc.push_back(i->second);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// the number of peers that belong to this torrent
|
// the number of peers that belong to this torrent
|
||||||
int num_peers() const { return (int)m_connections.size(); }
|
int num_peers() const { return (int)m_connections.size(); }
|
||||||
int num_seeds() const;
|
int num_seeds() const;
|
||||||
|
|
||||||
typedef std::set<peer_connection*>::iterator peer_iterator;
|
typedef std::map<tcp::endpoint, peer_connection*>::iterator peer_iterator;
|
||||||
typedef std::set<peer_connection*>::const_iterator const_peer_iterator;
|
typedef std::map<tcp::endpoint, peer_connection*>::const_iterator const_peer_iterator;
|
||||||
|
|
||||||
const_peer_iterator begin() const { return m_connections.begin(); }
|
const_peer_iterator begin() const { return m_connections.begin(); }
|
||||||
const_peer_iterator end() const { return m_connections.end(); }
|
const_peer_iterator end() const { return m_connections.end(); }
|
||||||
|
@ -476,7 +495,11 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
return m_picker.get() != 0;
|
return m_picker.get() != 0;
|
||||||
}
|
}
|
||||||
policy& get_policy() { return m_policy; }
|
policy& get_policy()
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(m_policy);
|
||||||
|
return *m_policy;
|
||||||
|
}
|
||||||
piece_manager& filesystem();
|
piece_manager& filesystem();
|
||||||
torrent_info const& torrent_file() const
|
torrent_info const& torrent_file() const
|
||||||
{ return *m_torrent_file; }
|
{ return *m_torrent_file; }
|
||||||
|
@ -610,7 +633,7 @@ namespace libtorrent
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
public:
|
public:
|
||||||
#endif
|
#endif
|
||||||
std::set<peer_connection*> m_connections;
|
std::map<tcp::endpoint, peer_connection*> m_connections;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
|
@ -666,6 +689,8 @@ namespace libtorrent
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
||||||
|
boost::shared_ptr<policy> m_policy;
|
||||||
|
|
||||||
// a back reference to the session
|
// a back reference to the session
|
||||||
// this torrent belongs to.
|
// this torrent belongs to.
|
||||||
aux::session_impl& m_ses;
|
aux::session_impl& m_ses;
|
||||||
|
@ -777,8 +802,6 @@ namespace libtorrent
|
||||||
// total_done - m_initial_done <= total_payload_download
|
// total_done - m_initial_done <= total_payload_download
|
||||||
size_type m_initial_done;
|
size_type m_initial_done;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
policy m_policy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ptime torrent::next_announce() const
|
inline ptime torrent::next_announce() const
|
||||||
|
|
|
@ -184,7 +184,6 @@ namespace libtorrent
|
||||||
|
|
||||||
typedef boost::mutex mutex_t;
|
typedef boost::mutex mutex_t;
|
||||||
mutable mutex_t m_mutex;
|
mutable mutex_t m_mutex;
|
||||||
bool m_abort;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT tracker_connection
|
struct TORRENT_EXPORT tracker_connection
|
||||||
|
@ -203,7 +202,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 close();
|
void close();
|
||||||
address const& bind_interface() const { return m_bind_interface; }
|
address const& bind_interface() const { return m_bind_interface; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -74,8 +74,6 @@ namespace libtorrent
|
||||||
, boost::weak_ptr<request_callback> c
|
, boost::weak_ptr<request_callback> c
|
||||||
, session_settings const& stn);
|
, session_settings const& stn);
|
||||||
|
|
||||||
void close();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum action_t
|
enum action_t
|
||||||
|
|
|
@ -582,8 +582,9 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(buf);
|
TORRENT_ASSERT(buf);
|
||||||
TORRENT_ASSERT(size > 0);
|
TORRENT_ASSERT(size > 0);
|
||||||
|
TORRENT_ASSERT(!m_rc4_encrypted || m_encrypted);
|
||||||
|
|
||||||
if (m_encrypted && m_rc4_encrypted)
|
if (m_rc4_encrypted)
|
||||||
m_RC4_handler->encrypt(buf, size);
|
m_RC4_handler->encrypt(buf, size);
|
||||||
|
|
||||||
peer_connection::send_buffer(buf, size);
|
peer_connection::send_buffer(buf, size);
|
||||||
|
@ -591,7 +592,9 @@ namespace libtorrent
|
||||||
|
|
||||||
buffer::interval bt_peer_connection::allocate_send_buffer(int size)
|
buffer::interval bt_peer_connection::allocate_send_buffer(int size)
|
||||||
{
|
{
|
||||||
if (m_encrypted && m_rc4_encrypted)
|
TORRENT_ASSERT(!m_rc4_encrypted || m_encrypted);
|
||||||
|
|
||||||
|
if (m_rc4_encrypted)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_enc_send_buffer.left() == 0);
|
TORRENT_ASSERT(m_enc_send_buffer.left() == 0);
|
||||||
m_enc_send_buffer = peer_connection::allocate_send_buffer(size);
|
m_enc_send_buffer = peer_connection::allocate_send_buffer(size);
|
||||||
|
@ -606,7 +609,9 @@ namespace libtorrent
|
||||||
|
|
||||||
void bt_peer_connection::setup_send()
|
void bt_peer_connection::setup_send()
|
||||||
{
|
{
|
||||||
if (m_encrypted && m_rc4_encrypted && m_enc_send_buffer.left())
|
TORRENT_ASSERT(!m_rc4_encrypted || m_encrypted);
|
||||||
|
|
||||||
|
if (m_rc4_encrypted && m_enc_send_buffer.left())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_enc_send_buffer.begin);
|
TORRENT_ASSERT(m_enc_send_buffer.begin);
|
||||||
TORRENT_ASSERT(m_enc_send_buffer.end);
|
TORRENT_ASSERT(m_enc_send_buffer.end);
|
||||||
|
@ -1203,11 +1208,11 @@ namespace libtorrent
|
||||||
// there is supposed to be a remote listen port
|
// there is supposed to be a remote listen port
|
||||||
if (entry* listen_port = root.find_key("p"))
|
if (entry* listen_port = root.find_key("p"))
|
||||||
{
|
{
|
||||||
if (listen_port->type() == entry::int_t
|
if (listen_port->type() == entry::int_t)
|
||||||
&& peer_info_struct() != 0)
|
|
||||||
{
|
{
|
||||||
t->get_policy().update_peer_port(listen_port->integer()
|
tcp::endpoint adr(remote().address()
|
||||||
, peer_info_struct(), peer_info::incoming);
|
, (unsigned short)listen_port->integer());
|
||||||
|
t->get_policy().peer_from_tracker(adr, pid(), peer_info::incoming, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// there should be a version too
|
// there should be a version too
|
||||||
|
|
|
@ -86,11 +86,6 @@ namespace libtorrent
|
||||||
try_connect();
|
try_connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void connection_queue::close()
|
|
||||||
{
|
|
||||||
m_timer.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void connection_queue::limit(int limit)
|
void connection_queue::limit(int limit)
|
||||||
{ m_half_open_limit = limit; }
|
{ m_half_open_limit = limit; }
|
||||||
|
|
||||||
|
@ -116,15 +111,9 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (!free_slots())
|
if (!free_slots() || m_queue.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_queue.empty())
|
|
||||||
{
|
|
||||||
m_timer.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<entry>::iterator i = std::find_if(m_queue.begin()
|
std::list<entry>::iterator i = std::find_if(m_queue.begin()
|
||||||
, m_queue.end(), boost::bind(&entry::connecting, _1) == false);
|
, m_queue.end(), boost::bind(&entry::connecting, _1) == false);
|
||||||
while (i != m_queue.end())
|
while (i != m_queue.end())
|
||||||
|
|
|
@ -344,7 +344,6 @@ namespace libtorrent
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_current.storage = 0;
|
m_current.storage = 0;
|
||||||
m_current.callback.clear();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (j.buffer && free_buffer)
|
if (j.buffer && free_buffer)
|
||||||
|
|
|
@ -126,7 +126,6 @@ namespace libtorrent
|
||||||
return &i->second;
|
return &i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
const entry& entry::operator[](char const* key) const
|
const entry& entry::operator[](char const* key) const
|
||||||
{
|
{
|
||||||
dictionary_type::const_iterator i = dict().find(key);
|
dictionary_type::const_iterator i = dict().find(key);
|
||||||
|
@ -139,7 +138,6 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
return (*this)[key.c_str()];
|
return (*this)[key.c_str()];
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
entry::entry(dictionary_type const& v)
|
entry::entry(dictionary_type const& v)
|
||||||
{
|
{
|
||||||
|
|
|
@ -489,9 +489,7 @@ namespace libtorrent
|
||||||
, boost::lexical_cast<std::string>(m_port));
|
, boost::lexical_cast<std::string>(m_port));
|
||||||
m_name_lookup.async_resolve(q, m_strand.wrap(
|
m_name_lookup.async_resolve(q, m_strand.wrap(
|
||||||
boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2)));
|
boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2)));
|
||||||
set_timeout(req.event == tracker_request::stopped
|
set_timeout(m_settings.tracker_completion_timeout
|
||||||
? m_settings.stop_tracker_timeout
|
|
||||||
: m_settings.tracker_completion_timeout
|
|
||||||
, m_settings.tracker_receive_timeout);
|
, m_settings.tracker_receive_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,23 +503,6 @@ namespace libtorrent
|
||||||
fail_timeout();
|
fail_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_tracker_connection::close()
|
|
||||||
{
|
|
||||||
asio::error_code ec;
|
|
||||||
m_socket.close(ec);
|
|
||||||
m_name_lookup.cancel();
|
|
||||||
if (m_connection_ticket > -1) m_cc.done(m_connection_ticket);
|
|
||||||
m_connection_ticket = -1;
|
|
||||||
m_timed_out = true;
|
|
||||||
tracker_connection::close();
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
boost::shared_ptr<request_callback> cb = requester();
|
|
||||||
std::stringstream msg;
|
|
||||||
msg << "http_tracker_connection::close() " << m_man.num_requests();
|
|
||||||
if (cb) cb->debug_log(msg.str());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void http_tracker_connection::name_lookup(asio::error_code const& error
|
void http_tracker_connection::name_lookup(asio::error_code const& error
|
||||||
, tcp::resolver::iterator i) try
|
, tcp::resolver::iterator i) try
|
||||||
{
|
{
|
||||||
|
@ -778,6 +759,7 @@ namespace libtorrent
|
||||||
if (m_parser.status_code() != 200)
|
if (m_parser.status_code() != 200)
|
||||||
{
|
{
|
||||||
fail(m_parser.status_code(), m_parser.message().c_str());
|
fail(m_parser.status_code(), m_parser.message().c_str());
|
||||||
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +821,6 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(false);
|
TORRENT_ASSERT(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_entry http_tracker_connection::extract_peer_info(const entry& info)
|
peer_entry http_tracker_connection::extract_peer_info(const entry& info)
|
||||||
|
|
|
@ -504,10 +504,11 @@ namespace libtorrent { namespace
|
||||||
// extension and that has metadata
|
// extension and that has metadata
|
||||||
int peers = 0;
|
int peers = 0;
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
for (torrent::peer_iterator i = m_torrent.begin()
|
typedef std::map<tcp::endpoint, peer_connection*> conn_map;
|
||||||
|
for (conn_map::iterator i = m_torrent.begin()
|
||||||
, end(m_torrent.end()); i != end; ++i)
|
, end(m_torrent.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
bt_peer_connection* c = dynamic_cast<bt_peer_connection*>(*i);
|
bt_peer_connection* c = dynamic_cast<bt_peer_connection*>(i->second);
|
||||||
if (c == 0) continue;
|
if (c == 0) continue;
|
||||||
metadata_peer_plugin* p
|
metadata_peer_plugin* p
|
||||||
= c->supports_extension<metadata_peer_plugin>();
|
= c->supports_extension<metadata_peer_plugin>();
|
||||||
|
|
|
@ -390,6 +390,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_peer_info->connection == 0);
|
TORRENT_ASSERT(m_peer_info->connection == 0);
|
||||||
|
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
|
if (t) TORRENT_ASSERT(t->connection_for(remote()) != this);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1393,7 +1394,7 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
m_ses.connection_failed(self(), remote(), j.str.c_str());
|
m_ses.connection_failed(m_socket, remote(), j.str.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1943,7 +1944,7 @@ namespace libtorrent
|
||||||
(*m_ses.m_logger) << "CONNECTION TIMED OUT: " << m_remote.address().to_string()
|
(*m_ses.m_logger) << "CONNECTION TIMED OUT: " << m_remote.address().to_string()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
#endif
|
#endif
|
||||||
m_ses.connection_failed(self(), m_remote, "timed out");
|
m_ses.connection_failed(m_socket, m_remote, "timed out");
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::disconnect()
|
void peer_connection::disconnect()
|
||||||
|
@ -2289,7 +2290,7 @@ namespace libtorrent
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
(*m_logger) << "**ERROR**: " << e.what() << "\n";
|
(*m_logger) << "**ERROR**: " << e.what() << "\n";
|
||||||
#endif
|
#endif
|
||||||
m_ses.connection_failed(self(), remote(), e.what());
|
m_ses.connection_failed(m_socket, remote(), e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2339,7 +2340,7 @@ namespace libtorrent
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
m_ses.connection_failed(self(), remote(), j.str.c_str());
|
m_ses.connection_failed(m_socket, remote(), j.str.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2675,7 +2676,7 @@ namespace libtorrent
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
m_ses.connection_failed(self(), remote(), e.what());
|
m_ses.connection_failed(m_socket, remote(), e.what());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2690,14 +2691,14 @@ namespace libtorrent
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
m_ses.connection_failed(self(), remote(), e.what());
|
m_ses.connection_failed(m_socket, remote(), e.what());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
// all exceptions should derive from std::exception
|
// all exceptions should derive from std::exception
|
||||||
TORRENT_ASSERT(false);
|
TORRENT_ASSERT(false);
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
m_ses.connection_failed(self(), remote(), "connection failed for unknown reason");
|
m_ses.connection_failed(m_socket, remote(), "connection failed for unknown reason");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool peer_connection::can_write() const
|
bool peer_connection::can_write() const
|
||||||
|
@ -2778,7 +2779,7 @@ namespace libtorrent
|
||||||
(*m_ses.m_logger) << "CONNECTION FAILED: " << m_remote.address().to_string()
|
(*m_ses.m_logger) << "CONNECTION FAILED: " << m_remote.address().to_string()
|
||||||
<< ": " << e.message() << "\n";
|
<< ": " << e.message() << "\n";
|
||||||
#endif
|
#endif
|
||||||
m_ses.connection_failed(self(), m_remote, e.message().c_str());
|
m_ses.connection_failed(m_socket, m_remote, e.message().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2798,14 +2799,14 @@ namespace libtorrent
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
m_ses.connection_failed(self(), remote(), ex.what());
|
m_ses.connection_failed(m_socket, remote(), ex.what());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
// all exceptions should derive from std::exception
|
// all exceptions should derive from std::exception
|
||||||
TORRENT_ASSERT(false);
|
TORRENT_ASSERT(false);
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
m_ses.connection_failed(self(), remote(), "connection failed for unkown reason");
|
m_ses.connection_failed(m_socket, remote(), "connection failed for unkown reason");
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------
|
// --------------------------
|
||||||
|
@ -2855,14 +2856,14 @@ namespace libtorrent
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
m_ses.connection_failed(self(), remote(), e.what());
|
m_ses.connection_failed(m_socket, remote(), e.what());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
// all exceptions should derive from std::exception
|
// all exceptions should derive from std::exception
|
||||||
TORRENT_ASSERT(false);
|
TORRENT_ASSERT(false);
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
m_ses.connection_failed(self(), remote(), "connection failed for unknown reason");
|
m_ses.connection_failed(m_socket, remote(), "connection failed for unknown reason");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2879,18 +2880,26 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
if (!t) return;
|
if (!t)
|
||||||
|
{
|
||||||
|
typedef session_impl::torrent_map torrent_map;
|
||||||
|
torrent_map& m = m_ses.m_torrents;
|
||||||
|
for (torrent_map::iterator i = m.begin(), end(m.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
torrent& t = *i->second;
|
||||||
|
TORRENT_ASSERT(t.connection_for(m_remote) != this);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_peer_info)
|
TORRENT_ASSERT(t->connection_for(remote()) != 0 || m_in_constructor);
|
||||||
|
|
||||||
|
if (!m_in_constructor && t->connection_for(remote()) != this
|
||||||
|
&& !m_ses.settings().allow_multiple_connections_per_ip)
|
||||||
{
|
{
|
||||||
policy::const_iterator i;
|
TORRENT_ASSERT(false);
|
||||||
for (i = t->get_policy().begin_peer();
|
|
||||||
i != t->get_policy().end_peer(); ++i)
|
|
||||||
{
|
|
||||||
if (&i->second == m_peer_info) break;
|
|
||||||
}
|
|
||||||
TORRENT_ASSERT(i != t->get_policy().end_peer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->has_picker() && !t->is_aborted())
|
if (t->has_picker() && !t->is_aborted())
|
||||||
{
|
{
|
||||||
// make sure that pieces that have completed the download
|
// make sure that pieces that have completed the download
|
||||||
|
|
|
@ -82,13 +82,13 @@ namespace
|
||||||
// want to trade it's surplus uploads for downloads itself
|
// want to trade it's surplus uploads for downloads itself
|
||||||
// (and we should not consider it free). If the share diff is
|
// (and we should not consider it free). If the share diff is
|
||||||
// negative, there's no free download to get from this peer.
|
// negative, there's no free download to get from this peer.
|
||||||
size_type diff = (*i)->share_diff();
|
size_type diff = i->second->share_diff();
|
||||||
TORRENT_ASSERT(diff < (std::numeric_limits<size_type>::max)());
|
TORRENT_ASSERT(diff < (std::numeric_limits<size_type>::max)());
|
||||||
if ((*i)->is_peer_interested() || diff <= 0)
|
if (i->second->is_peer_interested() || diff <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TORRENT_ASSERT(diff > 0);
|
TORRENT_ASSERT(diff > 0);
|
||||||
(*i)->add_free_upload(-diff);
|
i->second->add_free_upload(-diff);
|
||||||
accumulator += diff;
|
accumulator += diff;
|
||||||
TORRENT_ASSERT(accumulator > 0);
|
TORRENT_ASSERT(accumulator > 0);
|
||||||
}
|
}
|
||||||
|
@ -109,10 +109,10 @@ namespace
|
||||||
size_type total_diff = 0;
|
size_type total_diff = 0;
|
||||||
for (torrent::peer_iterator i = start; i != end; ++i)
|
for (torrent::peer_iterator i = start; i != end; ++i)
|
||||||
{
|
{
|
||||||
size_type d = (*i)->share_diff();
|
size_type d = i->second->share_diff();
|
||||||
TORRENT_ASSERT(d < (std::numeric_limits<size_type>::max)());
|
TORRENT_ASSERT(d < (std::numeric_limits<size_type>::max)());
|
||||||
total_diff += d;
|
total_diff += d;
|
||||||
if (!(*i)->is_peer_interested() || (*i)->share_diff() >= 0) continue;
|
if (!i->second->is_peer_interested() || i->second->share_diff() >= 0) continue;
|
||||||
++num_peers;
|
++num_peers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ namespace
|
||||||
|
|
||||||
for (torrent::peer_iterator i = start; i != end; ++i)
|
for (torrent::peer_iterator i = start; i != end; ++i)
|
||||||
{
|
{
|
||||||
peer_connection* p = *i;
|
peer_connection* p = i->second;
|
||||||
if (!p->is_peer_interested() || p->share_diff() >= 0) continue;
|
if (!p->is_peer_interested() || p->share_diff() >= 0) continue;
|
||||||
p->add_free_upload(upload_share);
|
p->add_free_upload(upload_share);
|
||||||
free_upload -= upload_share;
|
free_upload -= upload_share;
|
||||||
|
@ -904,7 +904,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(!c.is_local());
|
TORRENT_ASSERT(!c.is_local());
|
||||||
|
|
||||||
// INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
// if the connection comes from the tracker,
|
// if the connection comes from the tracker,
|
||||||
// it's probably just a NAT-check. Ignore the
|
// it's probably just a NAT-check. Ignore the
|
||||||
|
@ -932,11 +932,10 @@ namespace libtorrent
|
||||||
|
|
||||||
if (m_torrent->settings().allow_multiple_connections_per_ip)
|
if (m_torrent->settings().allow_multiple_connections_per_ip)
|
||||||
{
|
{
|
||||||
tcp::endpoint remote = c.remote();
|
i = std::find_if(
|
||||||
std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
|
m_peers.begin()
|
||||||
i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
|
, m_peers.end()
|
||||||
|
, match_peer_connection(c));
|
||||||
if (i == range.second) i = m_peers.end();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -978,6 +977,8 @@ namespace libtorrent
|
||||||
i = m_peers.insert(std::make_pair(c.remote().address(), p));
|
i = m_peers.insert(std::make_pair(c.remote().address(), p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_ASSERT(m_torrent->connection_for(c.remote()) == &c);
|
||||||
|
|
||||||
c.set_peer_info(&i->second);
|
c.set_peer_info(&i->second);
|
||||||
TORRENT_ASSERT(i->second.connection == 0);
|
TORRENT_ASSERT(i->second.connection == 0);
|
||||||
c.add_stat(i->second.prev_amount_download, i->second.prev_amount_upload);
|
c.add_stat(i->second.prev_amount_download, i->second.prev_amount_upload);
|
||||||
|
@ -990,38 +991,7 @@ namespace libtorrent
|
||||||
// m_last_optimistic_disconnect = time_now();
|
// m_last_optimistic_disconnect = time_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void policy::update_peer_port(int port, policy::peer* p, int src)
|
policy::peer* policy::peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid
|
||||||
{
|
|
||||||
TORRENT_ASSERT(p != 0);
|
|
||||||
if (p->ip.port() == port) return;
|
|
||||||
|
|
||||||
if (m_torrent->settings().allow_multiple_connections_per_ip)
|
|
||||||
{
|
|
||||||
tcp::endpoint remote(p->ip.address(), port);
|
|
||||||
std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
|
|
||||||
iterator i = std::find_if(range.first, range.second
|
|
||||||
, match_peer_endpoint(remote));
|
|
||||||
if (i != m_peers.end())
|
|
||||||
{
|
|
||||||
policy::peer& pp = i->second;
|
|
||||||
if (pp.connection)
|
|
||||||
{
|
|
||||||
throw protocol_error("duplicate connection");
|
|
||||||
}
|
|
||||||
if (m_torrent->has_picker())
|
|
||||||
m_torrent->picker().clear_peer(&i->second);
|
|
||||||
m_peers.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(m_peers.count(p->ip.address()) == 1);
|
|
||||||
}
|
|
||||||
p->ip.port(port);
|
|
||||||
p->source |= src;
|
|
||||||
}
|
|
||||||
|
|
||||||
policy::peer* policy::peer_from_tracker(tcp::endpoint const& remote, peer_id const& pid
|
|
||||||
, int src, char flags)
|
, int src, char flags)
|
||||||
{
|
{
|
||||||
// too expensive
|
// too expensive
|
||||||
|
@ -1052,7 +1022,9 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
|
std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
|
||||||
i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
|
i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
|
||||||
if (i == range.second) i = m_peers.end();
|
|
||||||
|
if (i == range.second)
|
||||||
|
i = std::find_if(m_peers.begin(), m_peers.end(), match_peer_id(pid));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1094,6 +1066,9 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
i->second.type = peer::connectable;
|
i->second.type = peer::connectable;
|
||||||
|
|
||||||
|
// in case we got the ip from a remote connection, port is
|
||||||
|
// not known, so save it. Client may also have changed port
|
||||||
|
// for some reason.
|
||||||
i->second.ip = remote;
|
i->second.ip = remote;
|
||||||
i->second.source |= src;
|
i->second.source |= src;
|
||||||
|
|
||||||
|
@ -1306,7 +1281,10 @@ namespace libtorrent
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!m_torrent->connect_to_peer(&p->second))
|
p->second.connected = time_now();
|
||||||
|
p->second.connection = m_torrent->connect_to_peer(&p->second);
|
||||||
|
TORRENT_ASSERT(p->second.connection == m_torrent->connection_for(p->second.ip));
|
||||||
|
if (p->second.connection == 0)
|
||||||
{
|
{
|
||||||
++p->second.failcount;
|
++p->second.failcount;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1418,7 +1396,6 @@ namespace libtorrent
|
||||||
void policy::check_invariant() const
|
void policy::check_invariant() const
|
||||||
{
|
{
|
||||||
if (m_torrent->is_aborted()) return;
|
if (m_torrent->is_aborted()) return;
|
||||||
|
|
||||||
int connected_peers = 0;
|
int connected_peers = 0;
|
||||||
|
|
||||||
int total_connections = 0;
|
int total_connections = 0;
|
||||||
|
@ -1437,14 +1414,20 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(unique_test.count(p.ip) == 0);
|
TORRENT_ASSERT(unique_test.count(p.ip) == 0);
|
||||||
unique_test.insert(p.ip);
|
unique_test.insert(p.ip);
|
||||||
TORRENT_ASSERT(i->first == p.ip.address());
|
|
||||||
// TORRENT_ASSERT(p.connection == 0 || p.ip == p.connection->remote());
|
|
||||||
}
|
}
|
||||||
++total_connections;
|
++total_connections;
|
||||||
if (!p.connection)
|
if (!p.connection)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!m_torrent->settings().allow_multiple_connections_per_ip)
|
||||||
|
{
|
||||||
|
std::vector<peer_connection*> conns;
|
||||||
|
m_torrent->connection_for(p.ip.address(), conns);
|
||||||
|
TORRENT_ASSERT(std::find_if(conns.begin(), conns.end()
|
||||||
|
, boost::bind(std::equal_to<peer_connection*>(), _1, p.connection))
|
||||||
|
!= conns.end());
|
||||||
|
}
|
||||||
if (p.optimistically_unchoked)
|
if (p.optimistically_unchoked)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(p.connection);
|
TORRENT_ASSERT(p.connection);
|
||||||
|
@ -1461,10 +1444,10 @@ namespace libtorrent
|
||||||
for (torrent::const_peer_iterator i = m_torrent->begin();
|
for (torrent::const_peer_iterator i = m_torrent->begin();
|
||||||
i != m_torrent->end(); ++i)
|
i != m_torrent->end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i)->is_disconnecting()) continue;
|
if (i->second->is_disconnecting()) continue;
|
||||||
// ignore web_peer_connections since they are not managed
|
// ignore web_peer_connections since they are not managed
|
||||||
// by the policy class
|
// by the policy class
|
||||||
if (dynamic_cast<web_peer_connection*>(*i)) continue;
|
if (dynamic_cast<web_peer_connection*>(i->second)) continue;
|
||||||
++num_torrent_peers;
|
++num_torrent_peers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -547,8 +547,8 @@ namespace detail
|
||||||
, fingerprint const& cl_fprint
|
, fingerprint const& cl_fprint
|
||||||
, char const* listen_interface)
|
, char const* listen_interface)
|
||||||
: m_send_buffers(send_buffer_size)
|
: m_send_buffers(send_buffer_size)
|
||||||
, m_files(40)
|
|
||||||
, m_strand(m_io_service)
|
, m_strand(m_io_service)
|
||||||
|
, m_files(40)
|
||||||
, m_half_open(m_io_service)
|
, m_half_open(m_io_service)
|
||||||
, m_download_channel(m_io_service, peer_connection::download_channel)
|
, m_download_channel(m_io_service, peer_connection::download_channel)
|
||||||
, m_upload_channel(m_io_service, peer_connection::upload_channel)
|
, m_upload_channel(m_io_service, peer_connection::upload_channel)
|
||||||
|
@ -675,17 +675,6 @@ namespace detail
|
||||||
if (m_dht) m_dht->stop();
|
if (m_dht) m_dht->stop();
|
||||||
#endif
|
#endif
|
||||||
m_timer.cancel();
|
m_timer.cancel();
|
||||||
|
|
||||||
// close the listen sockets
|
|
||||||
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
|
|
||||||
, end(m_listen_sockets.end()); i != end; ++i)
|
|
||||||
{
|
|
||||||
i->sock->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_logger) << time_now_string() << " aborting all torrents\n";
|
|
||||||
#endif
|
|
||||||
// abort all torrents
|
// abort all torrents
|
||||||
for (torrent_map::iterator i = m_torrents.begin()
|
for (torrent_map::iterator i = m_torrents.begin()
|
||||||
, end(m_torrents.end()); i != end; ++i)
|
, end(m_torrents.end()); i != end; ++i)
|
||||||
|
@ -693,65 +682,7 @@ namespace detail
|
||||||
i->second->abort();
|
i->second->abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
m_io_service.stop();
|
||||||
(*m_logger) << time_now_string() << " aborting all tracker requests\n";
|
|
||||||
#endif
|
|
||||||
m_tracker_manager.abort_all_requests();
|
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_logger) << time_now_string() << " sending event=stopped to trackers\n";
|
|
||||||
int counter = 0;
|
|
||||||
#endif
|
|
||||||
for (torrent_map::iterator i = m_torrents.begin();
|
|
||||||
i != m_torrents.end(); ++i)
|
|
||||||
{
|
|
||||||
torrent& t = *i->second;
|
|
||||||
|
|
||||||
if ((!t.is_paused() || t.should_request())
|
|
||||||
&& !t.trackers().empty())
|
|
||||||
{
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
++counter;
|
|
||||||
#endif
|
|
||||||
tracker_request req = t.generate_tracker_request();
|
|
||||||
TORRENT_ASSERT(req.event == tracker_request::stopped);
|
|
||||||
req.listen_port = 0;
|
|
||||||
if (!m_listen_sockets.empty())
|
|
||||||
req.listen_port = m_listen_sockets.front().external_port;
|
|
||||||
req.key = m_key;
|
|
||||||
std::string login = i->second->tracker_login();
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
boost::shared_ptr<tracker_logger> tl(new tracker_logger(*this));
|
|
||||||
m_tracker_loggers.push_back(tl);
|
|
||||||
m_tracker_manager.queue_request(m_strand, m_half_open, req, login
|
|
||||||
, m_listen_interface.address(), tl);
|
|
||||||
#else
|
|
||||||
m_tracker_manager.queue_request(m_strand, m_half_open, req, login
|
|
||||||
, m_listen_interface.address());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_logger) << time_now_string() << " sent " << counter << " tracker stop requests\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_logger) << time_now_string() << " aborting all connections (" << m_connections.size() << ")\n";
|
|
||||||
#endif
|
|
||||||
// abort all connections
|
|
||||||
while (!m_connections.empty())
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
int conn = m_connections.size();
|
|
||||||
#endif
|
|
||||||
(*m_connections.begin())->disconnect();
|
|
||||||
TORRENT_ASSERT(conn == m_connections.size() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
(*m_logger) << time_now_string() << " shutting down connection queue\n";
|
|
||||||
#endif
|
|
||||||
m_half_open.close();
|
|
||||||
|
|
||||||
mutex::scoped_lock l2(m_checker_impl.m_mutex);
|
mutex::scoped_lock l2(m_checker_impl.m_mutex);
|
||||||
// abort the checker thread
|
// abort the checker thread
|
||||||
|
@ -1047,7 +978,7 @@ namespace detail
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't allow more connections than the max setting
|
// don't allow more connections than the max setting
|
||||||
if (num_connections() > max_connections())
|
if (m_connections.size() > max_connections())
|
||||||
{
|
{
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
(*m_logger) << "number of connections limit exceeded (conns: "
|
(*m_logger) << "number of connections limit exceeded (conns: "
|
||||||
|
@ -1079,7 +1010,7 @@ namespace detail
|
||||||
c->m_in_constructor = false;
|
c->m_in_constructor = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_connections.insert(c);
|
m_connections.insert(std::make_pair(s, c));
|
||||||
}
|
}
|
||||||
catch (std::exception& exc)
|
catch (std::exception& exc)
|
||||||
{
|
{
|
||||||
|
@ -1088,7 +1019,7 @@ namespace detail
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void session_impl::connection_failed(boost::intrusive_ptr<peer_connection> const& peer
|
void session_impl::connection_failed(boost::shared_ptr<socket_type> const& s
|
||||||
, tcp::endpoint const& a, char const* message)
|
, tcp::endpoint const& a, char const* message)
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
try
|
try
|
||||||
|
@ -1099,7 +1030,7 @@ namespace detail
|
||||||
// too expensive
|
// too expensive
|
||||||
// INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
connection_map::iterator p = m_connections.find(peer);
|
connection_map::iterator p = m_connections.find(s);
|
||||||
|
|
||||||
// the connection may have been disconnected in the receive or send phase
|
// the connection may have been disconnected in the receive or send phase
|
||||||
if (p == m_connections.end()) return;
|
if (p == m_connections.end()) return;
|
||||||
|
@ -1108,15 +1039,15 @@ namespace detail
|
||||||
m_alerts.post_alert(
|
m_alerts.post_alert(
|
||||||
peer_error_alert(
|
peer_error_alert(
|
||||||
a
|
a
|
||||||
, (*p)->pid()
|
, p->second->pid()
|
||||||
, message));
|
, message));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||||
(*(*p)->m_logger) << "*** CONNECTION FAILED " << message << "\n";
|
(*p->second->m_logger) << "*** CONNECTION FAILED " << message << "\n";
|
||||||
#endif
|
#endif
|
||||||
(*p)->set_failed();
|
p->second->set_failed();
|
||||||
(*p)->disconnect();
|
p->second->disconnect();
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -1133,10 +1064,10 @@ namespace detail
|
||||||
// INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
TORRENT_ASSERT(p->is_disconnecting());
|
TORRENT_ASSERT(p->is_disconnecting());
|
||||||
connection_map::iterator i = m_connections.find(p);
|
connection_map::iterator i = m_connections.find(p->get_socket());
|
||||||
if (i != m_connections.end())
|
if (i != m_connections.end())
|
||||||
{
|
{
|
||||||
if (!(*i)->is_choked()) --m_num_unchoked;
|
if (!i->second->is_choked()) --m_num_unchoked;
|
||||||
m_connections.erase(i);
|
m_connections.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1195,7 +1126,7 @@ namespace detail
|
||||||
for (connection_map::iterator i = m_connections.begin()
|
for (connection_map::iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end; ++i)
|
, end(m_connections.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
if ((*i)->is_connecting())
|
if (i->second->is_connecting())
|
||||||
++num_half_open;
|
++num_half_open;
|
||||||
else
|
else
|
||||||
++num_complete_connections;
|
++num_complete_connections;
|
||||||
|
@ -1283,7 +1214,7 @@ namespace detail
|
||||||
++i;
|
++i;
|
||||||
// if this socket has timed out
|
// if this socket has timed out
|
||||||
// close it.
|
// close it.
|
||||||
peer_connection& c = *j->get();
|
peer_connection& c = *j->second;
|
||||||
if (c.has_timed_out())
|
if (c.has_timed_out())
|
||||||
{
|
{
|
||||||
if (m_alerts.should_post(alert::debug))
|
if (m_alerts.should_post(alert::debug))
|
||||||
|
@ -1350,7 +1281,7 @@ namespace detail
|
||||||
for (connection_map::iterator i = m_connections.begin()
|
for (connection_map::iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end; ++i)
|
, end(m_connections.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
peer_connection* p = i->get();
|
peer_connection* p = i->second.get();
|
||||||
torrent* t = p->associated_torrent().lock().get();
|
torrent* t = p->associated_torrent().lock().get();
|
||||||
if (!p->peer_info_struct()
|
if (!p->peer_info_struct()
|
||||||
|| t == 0
|
|| t == 0
|
||||||
|
@ -1360,7 +1291,7 @@ namespace detail
|
||||||
|| (p->share_diff() < -free_upload_amount
|
|| (p->share_diff() < -free_upload_amount
|
||||||
&& !t->is_seed()))
|
&& !t->is_seed()))
|
||||||
{
|
{
|
||||||
if (!(*i)->is_choked() && t)
|
if (!i->second->is_choked() && t)
|
||||||
{
|
{
|
||||||
policy::peer* pi = p->peer_info_struct();
|
policy::peer* pi = p->peer_info_struct();
|
||||||
if (pi && pi->optimistically_unchoked)
|
if (pi && pi->optimistically_unchoked)
|
||||||
|
@ -1369,11 +1300,11 @@ namespace detail
|
||||||
// force a new optimistic unchoke
|
// force a new optimistic unchoke
|
||||||
m_optimistic_unchoke_time_scaler = 0;
|
m_optimistic_unchoke_time_scaler = 0;
|
||||||
}
|
}
|
||||||
t->choke_peer(*(*i));
|
t->choke_peer(*i->second);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
peers.push_back(i->get());
|
peers.push_back(i->second.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort the peers that are eligible for unchoke by download rate and secondary
|
// sort the peers that are eligible for unchoke by download rate and secondary
|
||||||
|
@ -1445,7 +1376,7 @@ namespace detail
|
||||||
for (connection_map::iterator i = m_connections.begin()
|
for (connection_map::iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end; ++i)
|
, end(m_connections.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
peer_connection* p = i->get();
|
peer_connection* p = i->second.get();
|
||||||
TORRENT_ASSERT(p);
|
TORRENT_ASSERT(p);
|
||||||
policy::peer* pi = p->peer_info_struct();
|
policy::peer* pi = p->peer_info_struct();
|
||||||
if (!pi) continue;
|
if (!pi) continue;
|
||||||
|
@ -1476,21 +1407,21 @@ namespace detail
|
||||||
{
|
{
|
||||||
if (current_optimistic_unchoke != m_connections.end())
|
if (current_optimistic_unchoke != m_connections.end())
|
||||||
{
|
{
|
||||||
torrent* t = (*current_optimistic_unchoke)->associated_torrent().lock().get();
|
torrent* t = current_optimistic_unchoke->second->associated_torrent().lock().get();
|
||||||
TORRENT_ASSERT(t);
|
TORRENT_ASSERT(t);
|
||||||
(*current_optimistic_unchoke)->peer_info_struct()->optimistically_unchoked = false;
|
current_optimistic_unchoke->second->peer_info_struct()->optimistically_unchoked = false;
|
||||||
t->choke_peer(*current_optimistic_unchoke->get());
|
t->choke_peer(*current_optimistic_unchoke->second);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
++m_num_unchoked;
|
++m_num_unchoked;
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent* t = (*optimistic_unchoke_candidate)->associated_torrent().lock().get();
|
torrent* t = optimistic_unchoke_candidate->second->associated_torrent().lock().get();
|
||||||
TORRENT_ASSERT(t);
|
TORRENT_ASSERT(t);
|
||||||
bool ret = t->unchoke_peer(*optimistic_unchoke_candidate->get());
|
bool ret = t->unchoke_peer(*optimistic_unchoke_candidate->second);
|
||||||
TORRENT_ASSERT(ret);
|
TORRENT_ASSERT(ret);
|
||||||
(*optimistic_unchoke_candidate)->peer_info_struct()->optimistically_unchoked = true;
|
optimistic_unchoke_candidate->second->peer_info_struct()->optimistically_unchoked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1553,11 +1484,96 @@ namespace detail
|
||||||
}
|
}
|
||||||
while (!m_abort);
|
while (!m_abort);
|
||||||
|
|
||||||
|
deadline_timer tracker_timer(m_io_service);
|
||||||
|
// this will remove the port mappings
|
||||||
|
if (m_natpmp.get())
|
||||||
|
m_natpmp->close();
|
||||||
|
if (m_upnp.get())
|
||||||
|
m_upnp->close();
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
(*m_logger) << time_now_string() << " locking mutex\n";
|
(*m_logger) << time_now_string() << " locking mutex\n";
|
||||||
#endif
|
#endif
|
||||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << time_now_string() << " aborting all tracker requests\n";
|
||||||
|
#endif
|
||||||
|
m_tracker_manager.abort_all_requests();
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << time_now_string() << " sending stopped to all torrent's trackers\n";
|
||||||
|
#endif
|
||||||
|
for (std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i =
|
||||||
|
m_torrents.begin(); i != m_torrents.end(); ++i)
|
||||||
|
{
|
||||||
|
i->second->abort();
|
||||||
|
// generate a tracker request in case the torrent is not paused
|
||||||
|
// (in which case it's not currently announced with the tracker)
|
||||||
|
// or if the torrent itself thinks we should request. Do not build
|
||||||
|
// a request in case the torrent doesn't have any trackers
|
||||||
|
if ((!i->second->is_paused() || i->second->should_request())
|
||||||
|
&& !i->second->trackers().empty())
|
||||||
|
{
|
||||||
|
tracker_request req = i->second->generate_tracker_request();
|
||||||
|
TORRENT_ASSERT(!m_listen_sockets.empty());
|
||||||
|
req.listen_port = 0;
|
||||||
|
if (!m_listen_sockets.empty())
|
||||||
|
req.listen_port = m_listen_sockets.front().external_port;
|
||||||
|
req.key = m_key;
|
||||||
|
std::string login = i->second->tracker_login();
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
boost::shared_ptr<tracker_logger> tl(new tracker_logger(*this));
|
||||||
|
m_tracker_loggers.push_back(tl);
|
||||||
|
m_tracker_manager.queue_request(m_strand, m_half_open, req, login
|
||||||
|
, m_listen_interface.address(), tl);
|
||||||
|
#else
|
||||||
|
m_tracker_manager.queue_request(m_strand, m_half_open, req, login
|
||||||
|
, m_listen_interface.address());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the listen sockets
|
||||||
|
m_listen_sockets.clear();
|
||||||
|
|
||||||
|
ptime start(time_now());
|
||||||
|
l.unlock();
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << time_now_string() << " waiting for trackers to respond ("
|
||||||
|
<< m_settings.stop_tracker_timeout << " seconds timeout)\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (time_now() - start < seconds(
|
||||||
|
m_settings.stop_tracker_timeout)
|
||||||
|
&& !m_tracker_manager.empty())
|
||||||
|
{
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << time_now_string() << " " << m_tracker_manager.num_requests()
|
||||||
|
<< " tracker requests pending\n";
|
||||||
|
#endif
|
||||||
|
tracker_timer.expires_from_now(milliseconds(100));
|
||||||
|
tracker_timer.async_wait(m_strand.wrap(
|
||||||
|
bind(&io_service::stop, &m_io_service)));
|
||||||
|
|
||||||
|
m_io_service.reset();
|
||||||
|
m_io_service.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << time_now_string() << " tracker shutdown complete, locking mutex\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
l.lock();
|
||||||
|
TORRENT_ASSERT(m_abort);
|
||||||
|
m_abort = true;
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << time_now_string() << " cleaning up connections\n";
|
||||||
|
#endif
|
||||||
|
while (!m_connections.empty())
|
||||||
|
m_connections.begin()->second->disconnect();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (torrent_map::iterator i = m_torrents.begin();
|
for (torrent_map::iterator i = m_torrents.begin();
|
||||||
i != m_torrents.end(); ++i)
|
i != m_torrents.end(); ++i)
|
||||||
|
@ -2085,8 +2101,8 @@ namespace detail
|
||||||
|
|
||||||
entry session_impl::dht_state() const
|
entry session_impl::dht_state() const
|
||||||
{
|
{
|
||||||
|
TORRENT_ASSERT(m_dht);
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
if (!m_dht) return entry();
|
|
||||||
return m_dht->state();
|
return m_dht->state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2122,10 +2138,16 @@ namespace detail
|
||||||
|
|
||||||
session_impl::~session_impl()
|
session_impl::~session_impl()
|
||||||
{
|
{
|
||||||
|
abort();
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
(*m_logger) << time_now_string() << "\n\n *** shutting down session *** \n\n";
|
(*m_logger) << time_now_string() << "\n\n *** shutting down session *** \n\n";
|
||||||
#endif
|
#endif
|
||||||
abort();
|
// lock the main thread and abort it
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
m_abort = true;
|
||||||
|
m_io_service.stop();
|
||||||
|
l.unlock();
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
(*m_logger) << time_now_string() << " waiting for main thread\n";
|
(*m_logger) << time_now_string() << " waiting for main thread\n";
|
||||||
|
@ -2366,20 +2388,19 @@ namespace detail
|
||||||
for (connection_map::const_iterator i = m_connections.begin();
|
for (connection_map::const_iterator i = m_connections.begin();
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(*i);
|
TORRENT_ASSERT(i->second);
|
||||||
boost::shared_ptr<torrent> t = (*i)->associated_torrent().lock();
|
boost::shared_ptr<torrent> t = i->second->associated_torrent().lock();
|
||||||
|
|
||||||
peer_connection* p = i->get();
|
if (!i->second->is_choked()) ++unchokes;
|
||||||
if (!p->is_choked()) ++unchokes;
|
if (i->second->peer_info_struct()
|
||||||
if (p->peer_info_struct()
|
&& i->second->peer_info_struct()->optimistically_unchoked)
|
||||||
&& p->peer_info_struct()->optimistically_unchoked)
|
|
||||||
{
|
{
|
||||||
++num_optimistic;
|
++num_optimistic;
|
||||||
TORRENT_ASSERT(!p->is_choked());
|
TORRENT_ASSERT(!i->second->is_choked());
|
||||||
}
|
}
|
||||||
if (t && p->peer_info_struct())
|
if (t && i->second->peer_info_struct())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(t->get_policy().has_connection(p));
|
TORRENT_ASSERT(t->get_policy().has_connection(boost::get_pointer(i->second)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(num_optimistic == 0 || num_optimistic == 1);
|
TORRENT_ASSERT(num_optimistic == 0 || num_optimistic == 1);
|
||||||
|
|
|
@ -116,11 +116,11 @@ namespace
|
||||||
, tor(t)
|
, tor(t)
|
||||||
{ TORRENT_ASSERT(t != 0); }
|
{ TORRENT_ASSERT(t != 0); }
|
||||||
|
|
||||||
bool operator()(session_impl::connection_map::value_type const& c) const
|
bool operator()(const session_impl::connection_map::value_type& c) const
|
||||||
{
|
{
|
||||||
tcp::endpoint const& sender = c->remote();
|
tcp::endpoint sender = c.first->remote_endpoint();
|
||||||
if (sender.address() != ip.address()) return false;
|
if (sender.address() != ip.address()) return false;
|
||||||
if (tor != c->associated_torrent().lock().get()) return false;
|
if (tor != c.second->associated_torrent().lock().get()) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +132,9 @@ namespace
|
||||||
{
|
{
|
||||||
peer_by_id(const peer_id& i): pid(i) {}
|
peer_by_id(const peer_id& i): pid(i) {}
|
||||||
|
|
||||||
bool operator()(session_impl::connection_map::value_type const& p) const
|
bool operator()(const std::pair<tcp::endpoint, peer_connection*>& p) const
|
||||||
{
|
{
|
||||||
if (p->pid() != pid) return false;
|
if (p.second->pid() != pid) return false;
|
||||||
// have a special case for all zeros. We can have any number
|
// have a special case for all zeros. We can have any number
|
||||||
// of peers with that pid, since it's used to indicate no pid.
|
// of peers with that pid, since it's used to indicate no pid.
|
||||||
if (std::count(pid.begin(), pid.end(), 0) == 20) return false;
|
if (std::count(pid.begin(), pid.end(), 0) == 20) return false;
|
||||||
|
@ -178,6 +178,7 @@ namespace libtorrent
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
, m_last_dht_announce(time_now() - minutes(15))
|
, m_last_dht_announce(time_now() - minutes(15))
|
||||||
#endif
|
#endif
|
||||||
|
, m_policy()
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_checker(checker)
|
, m_checker(checker)
|
||||||
, m_picker(0)
|
, m_picker(0)
|
||||||
|
@ -202,8 +203,8 @@ namespace libtorrent
|
||||||
, m_max_uploads((std::numeric_limits<int>::max)())
|
, m_max_uploads((std::numeric_limits<int>::max)())
|
||||||
, m_num_uploads(0)
|
, m_num_uploads(0)
|
||||||
, m_max_connections((std::numeric_limits<int>::max)())
|
, m_max_connections((std::numeric_limits<int>::max)())
|
||||||
, m_policy(this)
|
|
||||||
{
|
{
|
||||||
|
m_policy.reset(new policy(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent::torrent(
|
torrent::torrent(
|
||||||
|
@ -238,6 +239,7 @@ namespace libtorrent
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
, m_last_dht_announce(time_now() - minutes(15))
|
, m_last_dht_announce(time_now() - minutes(15))
|
||||||
#endif
|
#endif
|
||||||
|
, m_policy()
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_checker(checker)
|
, m_checker(checker)
|
||||||
, m_picker(0)
|
, m_picker(0)
|
||||||
|
@ -261,7 +263,6 @@ namespace libtorrent
|
||||||
, m_max_uploads((std::numeric_limits<int>::max)())
|
, m_max_uploads((std::numeric_limits<int>::max)())
|
||||||
, m_num_uploads(0)
|
, m_num_uploads(0)
|
||||||
, m_max_connections((std::numeric_limits<int>::max)())
|
, m_max_connections((std::numeric_limits<int>::max)())
|
||||||
, m_policy(this)
|
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
@ -272,6 +273,8 @@ namespace libtorrent
|
||||||
m_trackers.push_back(announce_entry(tracker_url));
|
m_trackers.push_back(announce_entry(tracker_url));
|
||||||
m_torrent_file->add_tracker(tracker_url);
|
m_torrent_file->add_tracker(tracker_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_policy.reset(new policy(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::start()
|
void torrent::start()
|
||||||
|
@ -314,7 +317,7 @@ namespace libtorrent
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
(*(*i)->m_logger) << "*** DESTRUCTING TORRENT\n";
|
(*i->second->m_logger) << "*** DESTRUCTING TORRENT\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -563,7 +566,7 @@ namespace libtorrent
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_policy.peer_from_tracker(a, i->pid, peer_info::tracker, 0);
|
m_policy->peer_from_tracker(a, i->pid, peer_info::tracker, 0);
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
{
|
{
|
||||||
|
@ -611,7 +614,7 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_policy.peer_from_tracker(*host, pid, peer_info::tracker, 0);
|
m_policy->peer_from_tracker(*host, pid, peer_info::tracker, 0);
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
{};
|
{};
|
||||||
|
@ -741,7 +744,7 @@ namespace libtorrent
|
||||||
std::map<piece_block, int> downloading_piece;
|
std::map<piece_block, int> downloading_piece;
|
||||||
for (const_peer_iterator i = begin(); i != end(); ++i)
|
for (const_peer_iterator i = begin(); i != end(); ++i)
|
||||||
{
|
{
|
||||||
peer_connection* pc = *i;
|
peer_connection* pc = i->second;
|
||||||
boost::optional<piece_block_progress> p
|
boost::optional<piece_block_progress> p
|
||||||
= pc->downloading_piece_progress();
|
= pc->downloading_piece_progress();
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -882,7 +885,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_policy.piece_finished(index, passed_hash_check);
|
m_policy->piece_finished(index, passed_hash_check);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
}
|
}
|
||||||
|
@ -922,7 +925,7 @@ namespace libtorrent
|
||||||
// resets the download queue. So, we cannot do the
|
// resets the download queue. So, we cannot do the
|
||||||
// invariant check here since it assumes:
|
// invariant check here since it assumes:
|
||||||
// (total_done == m_torrent_file->total_size()) => is_seed()
|
// (total_done == m_torrent_file->total_size()) => is_seed()
|
||||||
INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
TORRENT_ASSERT(m_storage);
|
TORRENT_ASSERT(m_storage);
|
||||||
TORRENT_ASSERT(m_storage->refcount() > 0);
|
TORRENT_ASSERT(m_storage->refcount() > 0);
|
||||||
|
@ -961,6 +964,17 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
policy::peer* p = static_cast<policy::peer*>(*i);
|
policy::peer* p = static_cast<policy::peer*>(*i);
|
||||||
if (p == 0) continue;
|
if (p == 0) continue;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (!settings().allow_multiple_connections_per_ip)
|
||||||
|
{
|
||||||
|
std::vector<peer_connection*> conns;
|
||||||
|
connection_for(p->ip.address(), conns);
|
||||||
|
TORRENT_ASSERT(p->connection == 0
|
||||||
|
|| std::find_if(conns.begin(), conns.end()
|
||||||
|
, boost::bind(std::equal_to<peer_connection*>(), _1, p->connection))
|
||||||
|
!= conns.end());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (p->connection) p->connection->received_invalid_data(index);
|
if (p->connection) p->connection->received_invalid_data(index);
|
||||||
|
|
||||||
// either, we have received too many failed hashes
|
// either, we have received too many failed hashes
|
||||||
|
@ -1025,7 +1039,7 @@ namespace libtorrent
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
(*(*i)->m_logger) << "*** ABORTING TORRENT\n";
|
(*i->second->m_logger) << "*** ABORTING TORRENT\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1094,7 +1108,7 @@ namespace libtorrent
|
||||||
|
|
||||||
m_picker->we_have(index);
|
m_picker->we_have(index);
|
||||||
for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||||
try { (*i)->announce_piece(index); } catch (std::exception&) {}
|
try { i->second->announce_piece(index); } catch (std::exception&) {}
|
||||||
|
|
||||||
for (std::set<void*>::iterator i = peers.begin()
|
for (std::set<void*>::iterator i = peers.begin()
|
||||||
, end(peers.end()); i != end; ++i)
|
, end(peers.end()); i != end; ++i)
|
||||||
|
@ -1265,7 +1279,7 @@ namespace libtorrent
|
||||||
void torrent::update_peer_interest()
|
void torrent::update_peer_interest()
|
||||||
{
|
{
|
||||||
for (peer_iterator i = begin(); i != end(); ++i)
|
for (peer_iterator i = begin(); i != end(); ++i)
|
||||||
(*i)->update_interest();
|
i->second->update_interest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::filter_piece(int index, bool filter)
|
void torrent::filter_piece(int index, bool filter)
|
||||||
|
@ -1447,7 +1461,7 @@ namespace libtorrent
|
||||||
for (peer_iterator i = m_connections.begin()
|
for (peer_iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end; ++i)
|
, end(m_connections.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
(*i)->cancel_request(block);
|
i->second->cancel_request(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,7 +1471,7 @@ namespace libtorrent
|
||||||
|
|
||||||
TORRENT_ASSERT(p != 0);
|
TORRENT_ASSERT(p != 0);
|
||||||
|
|
||||||
peer_iterator i = m_connections.find(p);
|
peer_iterator i = m_connections.find(p->remote());
|
||||||
if (i == m_connections.end())
|
if (i == m_connections.end())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(false);
|
TORRENT_ASSERT(false);
|
||||||
|
@ -1495,9 +1509,8 @@ namespace libtorrent
|
||||||
if (!p->is_choked())
|
if (!p->is_choked())
|
||||||
--m_num_uploads;
|
--m_num_uploads;
|
||||||
|
|
||||||
m_policy.connection_closed(*p);
|
m_policy->connection_closed(*p);
|
||||||
p->set_peer_info(0);
|
p->set_peer_info(0);
|
||||||
TORRENT_ASSERT(i != m_connections.end());
|
|
||||||
m_connections.erase(i);
|
m_connections.erase(i);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -1650,6 +1663,14 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer_iterator conn = m_connections.find(a);
|
||||||
|
if (conn != m_connections.end())
|
||||||
|
{
|
||||||
|
if (dynamic_cast<web_peer_connection*>(conn->second) == 0
|
||||||
|
|| conn->second->is_disconnecting()) conn->second->disconnect();
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<socket_type> s(new socket_type);
|
boost::shared_ptr<socket_type> s(new socket_type);
|
||||||
|
|
||||||
bool ret = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy(), *s);
|
bool ret = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy(), *s);
|
||||||
|
@ -1681,8 +1702,10 @@ namespace libtorrent
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// add the newly connected peer to this torrent's peer list
|
// add the newly connected peer to this torrent's peer list
|
||||||
m_connections.insert(boost::get_pointer(c));
|
TORRENT_ASSERT(m_connections.find(a) == m_connections.end());
|
||||||
m_ses.m_connections.insert(c);
|
m_connections.insert(
|
||||||
|
std::make_pair(a, boost::get_pointer(c)));
|
||||||
|
m_ses.m_connections.insert(std::make_pair(s, c));
|
||||||
|
|
||||||
m_ses.m_half_open.enqueue(
|
m_ses.m_half_open.enqueue(
|
||||||
bind(&peer_connection::connect, c, _1)
|
bind(&peer_connection::connect, c, _1)
|
||||||
|
@ -1698,7 +1721,7 @@ namespace libtorrent
|
||||||
// TODO: post an error alert!
|
// TODO: post an error alert!
|
||||||
// std::map<tcp::endpoint, peer_connection*>::iterator i = m_connections.find(a);
|
// std::map<tcp::endpoint, peer_connection*>::iterator i = m_connections.find(a);
|
||||||
// if (i != m_connections.end()) m_connections.erase(i);
|
// if (i != m_connections.end()) m_connections.erase(i);
|
||||||
m_ses.connection_failed(c, a, e.what());
|
m_ses.connection_failed(s, a, e.what());
|
||||||
c->disconnect();
|
c->disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1843,19 +1866,19 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool torrent::connect_to_peer(policy::peer* peerinfo) throw()
|
peer_connection* torrent::connect_to_peer(policy::peer* peerinfo)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
TORRENT_ASSERT(peerinfo);
|
TORRENT_ASSERT(peerinfo);
|
||||||
TORRENT_ASSERT(peerinfo->connection == 0);
|
TORRENT_ASSERT(peerinfo->connection == 0);
|
||||||
peerinfo->connected = time_now();
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// this asserts that we don't have duplicates in the policy's peer list
|
// this asserts that we don't have duplicates in the policy's peer list
|
||||||
peer_iterator i_ = std::find_if(m_connections.begin(), m_connections.end()
|
peer_iterator i_ = m_connections.find(peerinfo->ip);
|
||||||
, bind(&peer_connection::remote, _1) == peerinfo->ip);
|
|
||||||
TORRENT_ASSERT(i_ == m_connections.end()
|
TORRENT_ASSERT(i_ == m_connections.end()
|
||||||
|| dynamic_cast<bt_peer_connection*>(*i_) == 0);
|
|| i_->second->is_disconnecting()
|
||||||
|
|| dynamic_cast<bt_peer_connection*>(i_->second) == 0
|
||||||
|
|| m_ses.settings().allow_multiple_connections_per_ip);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TORRENT_ASSERT(want_more_peers());
|
TORRENT_ASSERT(want_more_peers());
|
||||||
|
@ -1876,8 +1899,6 @@ namespace libtorrent
|
||||||
c->m_in_constructor = false;
|
c->m_in_constructor = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#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()
|
||||||
, end(m_extensions.end()); i != end; ++i)
|
, end(m_extensions.end()); i != end; ++i)
|
||||||
|
@ -1887,9 +1908,14 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(m_connections.find(a) == m_connections.end());
|
||||||
|
|
||||||
// add the newly connected peer to this torrent's peer list
|
// add the newly connected peer to this torrent's peer list
|
||||||
m_connections.insert(boost::get_pointer(c));
|
m_connections.insert(
|
||||||
m_ses.m_connections.insert(c);
|
std::make_pair(a, boost::get_pointer(c)));
|
||||||
|
m_ses.m_connections.insert(std::make_pair(s, c));
|
||||||
|
|
||||||
int timeout = settings().peer_connect_timeout;
|
int timeout = settings().peer_connect_timeout;
|
||||||
if (peerinfo) timeout += 3 * peerinfo->failcount;
|
if (peerinfo) timeout += 3 * peerinfo->failcount;
|
||||||
|
@ -1901,15 +1927,16 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
std::set<peer_connection*>::iterator i
|
TORRENT_ASSERT(false);
|
||||||
= m_connections.find(boost::get_pointer(c));
|
// TODO: post an error alert!
|
||||||
|
std::map<tcp::endpoint, peer_connection*>::iterator i = m_connections.find(a);
|
||||||
if (i != m_connections.end()) m_connections.erase(i);
|
if (i != m_connections.end()) m_connections.erase(i);
|
||||||
m_ses.connection_failed(c, a, e.what());
|
m_ses.connection_failed(s, a, e.what());
|
||||||
c->disconnect();
|
c->disconnect();
|
||||||
return false;
|
throw;
|
||||||
}
|
}
|
||||||
peerinfo->connection = c.get();
|
if (c->is_disconnecting()) throw protocol_error("failed to connect");
|
||||||
return true;
|
return c.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::set_metadata(entry const& metadata)
|
void torrent::set_metadata(entry const& metadata)
|
||||||
|
@ -1953,7 +1980,25 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(p != 0);
|
TORRENT_ASSERT(p != 0);
|
||||||
TORRENT_ASSERT(!p->is_local());
|
TORRENT_ASSERT(!p->is_local());
|
||||||
|
|
||||||
if (m_ses.m_connections.find(p) == m_ses.m_connections.end())
|
std::map<tcp::endpoint, peer_connection*>::iterator c
|
||||||
|
= m_connections.find(p->remote());
|
||||||
|
if (c != m_connections.end())
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(p != c->second);
|
||||||
|
// we already have a peer_connection to this ip.
|
||||||
|
// It may currently be waiting for completing a
|
||||||
|
// connection attempt that might fail. So,
|
||||||
|
// prioritize this current connection since
|
||||||
|
// it has already succeeded.
|
||||||
|
if (!c->second->is_connecting())
|
||||||
|
{
|
||||||
|
throw protocol_error("already connected to peer");
|
||||||
|
}
|
||||||
|
c->second->disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_ses.m_connections.find(p->get_socket())
|
||||||
|
== m_ses.m_connections.end())
|
||||||
{
|
{
|
||||||
throw protocol_error("peer is not properly constructed");
|
throw protocol_error("peer is not properly constructed");
|
||||||
}
|
}
|
||||||
|
@ -1963,8 +2008,9 @@ namespace libtorrent
|
||||||
throw protocol_error("session is closing");
|
throw protocol_error("session is closing");
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_ASSERT(m_connections.find(p) == m_connections.end());
|
TORRENT_ASSERT(m_connections.find(p->remote()) == m_connections.end());
|
||||||
peer_iterator ci = m_connections.insert(p).first;
|
peer_iterator ci = m_connections.insert(
|
||||||
|
std::make_pair(p->remote(), p)).first;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// if new_connection throws, we have to remove the
|
// if new_connection throws, we have to remove the
|
||||||
|
@ -1978,9 +2024,9 @@ namespace libtorrent
|
||||||
if (pp) p->add_extension(pp);
|
if (pp) p->add_extension(pp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
TORRENT_ASSERT(m_connections.find(p) == ci);
|
TORRENT_ASSERT(connection_for(p->remote()) == p);
|
||||||
TORRENT_ASSERT(*ci == p);
|
TORRENT_ASSERT(ci->second == p);
|
||||||
m_policy.new_connection(**ci);
|
m_policy->new_connection(*ci->second);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -1990,7 +2036,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(p->remote() == p->get_socket()->remote_endpoint());
|
TORRENT_ASSERT(p->remote() == p->get_socket()->remote_endpoint());
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_policy.check_invariant();
|
m_policy->check_invariant();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2009,19 +2055,19 @@ namespace libtorrent
|
||||||
|
|
||||||
while (!m_connections.empty())
|
while (!m_connections.empty())
|
||||||
{
|
{
|
||||||
peer_connection* p = *m_connections.begin();
|
peer_connection& p = *m_connections.begin()->second;
|
||||||
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
|
TORRENT_ASSERT(p.associated_torrent().lock().get() == this);
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||||
if (m_abort)
|
if (m_abort)
|
||||||
(*p->m_logger) << "*** CLOSING CONNECTION 'aborting'\n";
|
(*p.m_logger) << "*** CLOSING CONNECTION 'aborting'\n";
|
||||||
else
|
else
|
||||||
(*p->m_logger) << "*** CLOSING CONNECTION 'pausing'\n";
|
(*p.m_logger) << "*** CLOSING CONNECTION 'pausing'\n";
|
||||||
#endif
|
#endif
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::size_t size = m_connections.size();
|
std::size_t size = m_connections.size();
|
||||||
#endif
|
#endif
|
||||||
p->disconnect();
|
p.disconnect();
|
||||||
TORRENT_ASSERT(m_connections.size() <= size);
|
TORRENT_ASSERT(m_connections.size() <= size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2112,14 +2158,13 @@ namespace libtorrent
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
peer_connection* p = *i;
|
TORRENT_ASSERT(i->second->associated_torrent().lock().get() == this);
|
||||||
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
|
if (i->second->is_seed())
|
||||||
if (p->is_seed())
|
|
||||||
{
|
{
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||||
(*p->m_logger) << "*** SEED, CLOSING CONNECTION\n";
|
(*i->second->m_logger) << "*** SEED, CLOSING CONNECTION\n";
|
||||||
#endif
|
#endif
|
||||||
seeds.push_back(p);
|
seeds.push_back(i->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::for_each(seeds.begin(), seeds.end()
|
std::for_each(seeds.begin(), seeds.end()
|
||||||
|
@ -2320,21 +2365,23 @@ namespace libtorrent
|
||||||
m_connections_initialized = true;
|
m_connections_initialized = true;
|
||||||
// all peer connections have to initialize themselves now that the metadata
|
// all peer connections have to initialize themselves now that the metadata
|
||||||
// is available
|
// is available
|
||||||
for (torrent::peer_iterator i = m_connections.begin()
|
typedef std::map<tcp::endpoint, peer_connection*> conn_map;
|
||||||
|
for (conn_map::iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end;)
|
, end(m_connections.end()); i != end;)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
(*i)->on_metadata();
|
i->second->on_metadata();
|
||||||
(*i)->init();
|
i->second->init();
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
// the connection failed, close it
|
// the connection failed, close it
|
||||||
torrent::peer_iterator j = i;
|
conn_map::iterator j = i;
|
||||||
++j;
|
++j;
|
||||||
m_ses.connection_failed(*i, (*i)->remote(), e.what());
|
m_ses.connection_failed(i->second->get_socket()
|
||||||
|
, i->first, e.what());
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2405,7 +2452,7 @@ namespace libtorrent
|
||||||
std::map<piece_block, int> num_requests;
|
std::map<piece_block, int> num_requests;
|
||||||
for (const_peer_iterator i = begin(); i != end(); ++i)
|
for (const_peer_iterator i = begin(); i != end(); ++i)
|
||||||
{
|
{
|
||||||
peer_connection const& p = *(*i);
|
peer_connection const& p = *i->second;
|
||||||
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
|
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
|
||||||
, end(p.request_queue().end()); i != end; ++i)
|
, end(p.request_queue().end()); i != end; ++i)
|
||||||
++num_requests[*i];
|
++num_requests[*i];
|
||||||
|
@ -2437,12 +2484,12 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_abort || m_have_pieces.empty());
|
TORRENT_ASSERT(m_abort || m_have_pieces.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (policy::const_iterator i = m_policy.begin_peer()
|
/* for (policy::const_iterator i = m_policy->begin_peer()
|
||||||
, end(m_policy.end_peer()); i != end; ++i)
|
, end(m_policy->end_peer()); i != end; ++i)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(i->second.ip.address() == i->first);
|
TORRENT_ASSERT(i->connection == const_cast<torrent*>(this)->connection_for(i->ip));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
size_type total_done = quantized_bytes_done();
|
size_type total_done = quantized_bytes_done();
|
||||||
if (m_torrent_file->is_valid())
|
if (m_torrent_file->is_valid())
|
||||||
{
|
{
|
||||||
|
@ -2525,19 +2572,17 @@ namespace libtorrent
|
||||||
void torrent::set_peer_upload_limit(tcp::endpoint ip, int limit)
|
void torrent::set_peer_upload_limit(tcp::endpoint ip, int limit)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(limit >= -1);
|
TORRENT_ASSERT(limit >= -1);
|
||||||
peer_iterator i = std::find_if(m_connections.begin(), m_connections.end()
|
peer_connection* p = connection_for(ip);
|
||||||
, bind(&peer_connection::remote, _1) == ip);
|
if (p == 0) return;
|
||||||
if (i == m_connections.end()) return;
|
p->set_upload_limit(limit);
|
||||||
(*i)->set_upload_limit(limit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::set_peer_download_limit(tcp::endpoint ip, int limit)
|
void torrent::set_peer_download_limit(tcp::endpoint ip, int limit)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(limit >= -1);
|
TORRENT_ASSERT(limit >= -1);
|
||||||
peer_iterator i = std::find_if(m_connections.begin(), m_connections.end()
|
peer_connection* p = connection_for(ip);
|
||||||
, bind(&peer_connection::remote, _1) == ip);
|
if (p == 0) return;
|
||||||
if (i == m_connections.end()) return;
|
p->set_download_limit(limit);
|
||||||
(*i)->set_download_limit(limit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::set_upload_limit(int limit)
|
void torrent::set_upload_limit(int limit)
|
||||||
|
@ -2576,7 +2621,7 @@ namespace libtorrent
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
(*(*i)->m_logger) << "*** DELETING FILES IN TORRENT\n";
|
(*i->second->m_logger) << "*** DELETING FILES IN TORRENT\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2611,7 +2656,7 @@ namespace libtorrent
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
(*(*i)->m_logger) << "*** PAUSING TORRENT\n";
|
(*i->second->m_logger) << "*** PAUSING TORRENT\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2685,7 +2730,7 @@ namespace libtorrent
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
web_peer_connection* p
|
web_peer_connection* p
|
||||||
= dynamic_cast<web_peer_connection*>(*i);
|
= dynamic_cast<web_peer_connection*>(i->second);
|
||||||
if (!p) continue;
|
if (!p) continue;
|
||||||
web_seeds.insert(p->url());
|
web_seeds.insert(p->url());
|
||||||
}
|
}
|
||||||
|
@ -2708,7 +2753,7 @@ namespace libtorrent
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end();)
|
i != m_connections.end();)
|
||||||
{
|
{
|
||||||
peer_connection* p = *i;
|
peer_connection* p = i->second;
|
||||||
++i;
|
++i;
|
||||||
m_stat += p->statistics();
|
m_stat += p->statistics();
|
||||||
// updates the peer connection's ul/dl bandwidth
|
// updates the peer connection's ul/dl bandwidth
|
||||||
|
@ -2733,14 +2778,14 @@ namespace libtorrent
|
||||||
if (m_time_scaler <= 0)
|
if (m_time_scaler <= 0)
|
||||||
{
|
{
|
||||||
m_time_scaler = 10;
|
m_time_scaler = 10;
|
||||||
m_policy.pulse();
|
m_policy->pulse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool torrent::try_connect_peer()
|
bool torrent::try_connect_peer()
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(want_more_peers());
|
TORRENT_ASSERT(want_more_peers());
|
||||||
return m_policy.connect_one_peer();
|
return m_policy->connect_one_peer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::async_verify_piece(int piece_index, boost::function<void(bool)> const& f)
|
void torrent::async_verify_piece(int piece_index, boost::function<void(bool)> const& f)
|
||||||
|
@ -2824,7 +2869,8 @@ namespace libtorrent
|
||||||
torrent_status st;
|
torrent_status st;
|
||||||
|
|
||||||
st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end(),
|
st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end(),
|
||||||
!boost::bind(&peer_connection::is_connecting, _1));
|
!boost::bind(&peer_connection::is_connecting
|
||||||
|
, boost::bind(&std::map<tcp::endpoint,peer_connection*>::value_type::second, _1)));
|
||||||
|
|
||||||
st.storage_mode = m_storage_mode;
|
st.storage_mode = m_storage_mode;
|
||||||
|
|
||||||
|
@ -2951,7 +2997,9 @@ namespace libtorrent
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
return (int)std::count_if(m_connections.begin(), m_connections.end()
|
return (int)std::count_if(m_connections.begin(), m_connections.end()
|
||||||
, boost::bind(&peer_connection::is_seed, _1));
|
, boost::bind(&peer_connection::is_seed
|
||||||
|
, boost::bind(&std::map<tcp::endpoint
|
||||||
|
, peer_connection*>::value_type::second, _1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::tracker_request_timed_out(
|
void torrent::tracker_request_timed_out(
|
||||||
|
@ -3007,7 +3055,7 @@ namespace libtorrent
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
void torrent::debug_log(const std::string& line)
|
void torrent::debug_log(const std::string& line)
|
||||||
{
|
{
|
||||||
(*m_ses.m_logger) << time_now_string() << " " << line << "\n";
|
(*m_ses.m_logger) << line << "\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -908,7 +908,7 @@ namespace libtorrent
|
||||||
for (torrent::const_peer_iterator i = t->begin();
|
for (torrent::const_peer_iterator i = t->begin();
|
||||||
i != t->end(); ++i)
|
i != t->end(); ++i)
|
||||||
{
|
{
|
||||||
peer_connection* peer = *i;
|
peer_connection* peer = i->second;
|
||||||
|
|
||||||
// incoming peers that haven't finished the handshake should
|
// incoming peers that haven't finished the handshake should
|
||||||
// not be included in this list
|
// not be included in this list
|
||||||
|
|
|
@ -296,20 +296,18 @@ namespace libtorrent
|
||||||
, m_timeout(str.io_service())
|
, m_timeout(str.io_service())
|
||||||
, m_completion_timeout(0)
|
, m_completion_timeout(0)
|
||||||
, m_read_timeout(0)
|
, m_read_timeout(0)
|
||||||
, m_abort(false)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void timeout_handler::set_timeout(int completion_timeout, int read_timeout)
|
void timeout_handler::set_timeout(int completion_timeout, int read_timeout)
|
||||||
{
|
{
|
||||||
m_completion_timeout = completion_timeout;
|
m_completion_timeout = completion_timeout;
|
||||||
m_read_timeout = read_timeout;
|
m_read_timeout = read_timeout;
|
||||||
m_start_time = m_read_time = time_now();
|
m_start_time = time_now();
|
||||||
|
m_read_time = time_now();
|
||||||
|
|
||||||
if (m_abort) return;
|
m_timeout.expires_at((std::min)(
|
||||||
|
m_read_time + seconds(m_read_timeout)
|
||||||
int timeout = (std::min)(
|
, m_start_time + seconds(m_completion_timeout)));
|
||||||
m_read_timeout, (std::min)(m_completion_timeout, m_read_timeout));
|
|
||||||
m_timeout.expires_at(m_read_time + seconds(timeout));
|
|
||||||
m_timeout.async_wait(m_strand.wrap(bind(
|
m_timeout.async_wait(m_strand.wrap(bind(
|
||||||
&timeout_handler::timeout_callback, self(), _1)));
|
&timeout_handler::timeout_callback, self(), _1)));
|
||||||
}
|
}
|
||||||
|
@ -321,7 +319,6 @@ namespace libtorrent
|
||||||
|
|
||||||
void timeout_handler::cancel()
|
void timeout_handler::cancel()
|
||||||
{
|
{
|
||||||
m_abort = true;
|
|
||||||
m_completion_timeout = 0;
|
m_completion_timeout = 0;
|
||||||
m_timeout.cancel();
|
m_timeout.cancel();
|
||||||
}
|
}
|
||||||
|
@ -344,11 +341,9 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_abort) return;
|
m_timeout.expires_at((std::min)(
|
||||||
|
m_read_time + seconds(m_read_timeout)
|
||||||
int timeout = (std::min)(
|
, m_start_time + seconds(m_completion_timeout)));
|
||||||
m_read_timeout, (std::min)(m_completion_timeout, m_read_timeout));
|
|
||||||
m_timeout.expires_at(m_read_time + seconds(timeout));
|
|
||||||
m_timeout.async_wait(m_strand.wrap(
|
m_timeout.async_wait(m_strand.wrap(
|
||||||
bind(&timeout_handler::timeout_callback, self(), _1)));
|
bind(&timeout_handler::timeout_callback, self(), _1)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,9 +96,7 @@ namespace libtorrent
|
||||||
m_name_lookup.async_resolve(q
|
m_name_lookup.async_resolve(q
|
||||||
, m_strand.wrap(boost::bind(
|
, m_strand.wrap(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(m_settings.tracker_completion_timeout
|
||||||
? m_settings.stop_tracker_timeout
|
|
||||||
: m_settings.tracker_completion_timeout
|
|
||||||
, m_settings.tracker_receive_timeout);
|
, m_settings.tracker_receive_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,20 +156,11 @@ namespace libtorrent
|
||||||
|
|
||||||
void udp_tracker_connection::on_timeout()
|
void udp_tracker_connection::on_timeout()
|
||||||
{
|
{
|
||||||
asio::error_code ec;
|
m_socket.close();
|
||||||
m_socket.close(ec);
|
|
||||||
m_name_lookup.cancel();
|
m_name_lookup.cancel();
|
||||||
fail_timeout();
|
fail_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void udp_tracker_connection::close()
|
|
||||||
{
|
|
||||||
asio::error_code ec;
|
|
||||||
m_socket.close(ec);
|
|
||||||
m_name_lookup.cancel();
|
|
||||||
tracker_connection::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void udp_tracker_connection::send_udp_connect()
|
void udp_tracker_connection::send_udp_connect()
|
||||||
{
|
{
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
@ -479,7 +468,6 @@ namespace libtorrent
|
||||||
, complete, incomplete);
|
, complete, incomplete);
|
||||||
|
|
||||||
m_man.remove_request(this);
|
m_man.remove_request(this);
|
||||||
close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -555,7 +543,6 @@ namespace libtorrent
|
||||||
if (!cb)
|
if (!cb)
|
||||||
{
|
{
|
||||||
m_man.remove_request(this);
|
m_man.remove_request(this);
|
||||||
close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +551,6 @@ namespace libtorrent
|
||||||
, complete, incomplete);
|
, complete, incomplete);
|
||||||
|
|
||||||
m_man.remove_request(this);
|
m_man.remove_request(this);
|
||||||
close();
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace libtorrent { namespace
|
||||||
|
|
||||||
struct ut_pex_plugin: torrent_plugin
|
struct ut_pex_plugin: torrent_plugin
|
||||||
{
|
{
|
||||||
ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(55) {}
|
ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(0) {}
|
||||||
|
|
||||||
virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection* pc);
|
virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection* pc);
|
||||||
|
|
||||||
|
@ -113,20 +113,18 @@ namespace libtorrent { namespace
|
||||||
for (torrent::peer_iterator i = m_torrent.begin()
|
for (torrent::peer_iterator i = m_torrent.begin()
|
||||||
, end(m_torrent.end()); i != end; ++i)
|
, end(m_torrent.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
peer_connection* peer = *i;
|
if (!send_peer(*i->second)) continue;
|
||||||
if (!send_peer(*peer)) continue;
|
|
||||||
|
|
||||||
tcp::endpoint const& remote = peer->remote();
|
m_old_peers.insert(i->first);
|
||||||
m_old_peers.insert(remote);
|
|
||||||
|
|
||||||
std::set<tcp::endpoint>::iterator di = dropped.find(remote);
|
std::set<tcp::endpoint>::iterator di = dropped.find(i->first);
|
||||||
if (di == dropped.end())
|
if (di == dropped.end())
|
||||||
{
|
{
|
||||||
// don't write too big of a package
|
// don't write too big of a package
|
||||||
if (num_added >= max_peer_entries) break;
|
if (num_added >= max_peer_entries) break;
|
||||||
|
|
||||||
// only send proper bittorrent peers
|
// only send proper bittorrent peers
|
||||||
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(peer);
|
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(i->second);
|
||||||
if (!p) continue;
|
if (!p) continue;
|
||||||
|
|
||||||
// no supported flags to set yet
|
// no supported flags to set yet
|
||||||
|
@ -137,14 +135,14 @@ namespace libtorrent { namespace
|
||||||
flags |= p->supports_encryption() ? 1 : 0;
|
flags |= p->supports_encryption() ? 1 : 0;
|
||||||
#endif
|
#endif
|
||||||
// i->first was added since the last time
|
// i->first was added since the last time
|
||||||
if (remote.address().is_v4())
|
if (i->first.address().is_v4())
|
||||||
{
|
{
|
||||||
detail::write_endpoint(remote, pla_out);
|
detail::write_endpoint(i->first, pla_out);
|
||||||
detail::write_uint8(flags, plf_out);
|
detail::write_uint8(flags, plf_out);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
detail::write_endpoint(remote, pla6_out);
|
detail::write_endpoint(i->first, pla6_out);
|
||||||
detail::write_uint8(flags, plf6_out);
|
detail::write_uint8(flags, plf6_out);
|
||||||
}
|
}
|
||||||
++num_added;
|
++num_added;
|
||||||
|
@ -185,7 +183,7 @@ namespace libtorrent { namespace
|
||||||
: m_torrent(t)
|
: m_torrent(t)
|
||||||
, m_pc(pc)
|
, m_pc(pc)
|
||||||
, m_tp(tp)
|
, m_tp(tp)
|
||||||
, m_1_minute(55)
|
, m_1_minute(0)
|
||||||
, m_message_index(0)
|
, m_message_index(0)
|
||||||
, m_first_time(true)
|
, m_first_time(true)
|
||||||
{}
|
{}
|
||||||
|
@ -329,14 +327,13 @@ namespace libtorrent { namespace
|
||||||
for (torrent::peer_iterator i = m_torrent.begin()
|
for (torrent::peer_iterator i = m_torrent.begin()
|
||||||
, end(m_torrent.end()); i != end; ++i)
|
, end(m_torrent.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
peer_connection* peer = *i;
|
if (!send_peer(*i->second)) continue;
|
||||||
if (!send_peer(*peer)) continue;
|
|
||||||
|
|
||||||
// don't write too big of a package
|
// don't write too big of a package
|
||||||
if (num_added >= max_peer_entries) break;
|
if (num_added >= max_peer_entries) break;
|
||||||
|
|
||||||
// only send proper bittorrent peers
|
// only send proper bittorrent peers
|
||||||
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(peer);
|
bt_peer_connection* p = dynamic_cast<bt_peer_connection*>(i->second);
|
||||||
if (!p) continue;
|
if (!p) continue;
|
||||||
|
|
||||||
// no supported flags to set yet
|
// no supported flags to set yet
|
||||||
|
@ -346,16 +343,15 @@ namespace libtorrent { namespace
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
flags |= p->supports_encryption() ? 1 : 0;
|
flags |= p->supports_encryption() ? 1 : 0;
|
||||||
#endif
|
#endif
|
||||||
tcp::endpoint const& remote = peer->remote();
|
|
||||||
// i->first was added since the last time
|
// i->first was added since the last time
|
||||||
if (remote.address().is_v4())
|
if (i->first.address().is_v4())
|
||||||
{
|
{
|
||||||
detail::write_endpoint(remote, pla_out);
|
detail::write_endpoint(i->first, pla_out);
|
||||||
detail::write_uint8(flags, plf_out);
|
detail::write_uint8(flags, plf_out);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
detail::write_endpoint(remote, pla6_out);
|
detail::write_endpoint(i->first, pla6_out);
|
||||||
detail::write_uint8(flags, plf6_out);
|
detail::write_uint8(flags, plf6_out);
|
||||||
}
|
}
|
||||||
++num_added;
|
++num_added;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue