added source to peer_info, which is a bitmask of the sources where the peer has been acquired from

This commit is contained in:
Arvid Norberg 2007-04-10 21:23:13 +00:00
parent 009b10e9bf
commit 3ed24da320
17 changed files with 167 additions and 65 deletions

View File

@ -1188,7 +1188,7 @@ Its declaration looks like this::
entry write_resume_data() const;
void force_reannounce() const;
void connect_peer(asio::ip::tcp::endpoint const& adr) const;
void connect_peer(asio::ip::tcp::endpoint const& adr, int source = 0) const;
void set_tracker_login(std::string const& username
, std::string const& password) const;
@ -1361,13 +1361,15 @@ connect_peer()
::
void connect_peer(asio::ip::tcp::endpoint const& adr) const;
void connect_peer(asio::ip::tcp::endpoint const& adr, int source = 0) const;
``connect_peer()`` is a way to manually connect to peers that one believe is a part of the
torrent. If the peer does not respond, or is not a member of this torrent, it will simply
be disconnected. No harm can be done by using this other than an unnecessary connection
attempt is made. If the torrent is uninitialized or in queued or checking mode, this
will throw invalid_handle_.
will throw invalid_handle_. The second (optional) argument will be bitwised ORed into
the source mask of this peer. Typically this is one of the source flags in peer_info_.
i.e. ``tracker``, ``pex``, ``dht`` etc.
name()
@ -1907,7 +1909,19 @@ It contains the following fields::
connecting = 0x80,
queued = 0x100
};
unsigned int flags;
enum peer_source_flags
{
tracker = 0x1,
dht = 0x2,
pex = 0x4,
lsd = 0x8
};
int source;
asio::ip::tcp::endpoint ip;
float up_speed;
float down_speed;
@ -1978,6 +1992,23 @@ any combination of the enums above. The following table describes each flag:
__ extension_protocol.html
``source`` is a combination of flags describing from which sources this peer
was received. The flags are:
+------------------------+--------------------------------------------------------+
| ``tracker`` | The peer was received from the tracker. |
+------------------------+--------------------------------------------------------+
| ``dht`` | The peer was received from the kademlia DHT. |
+------------------------+--------------------------------------------------------+
| ``pex`` | The peer was received from the peer exchange |
| | extension. |
+------------------------+--------------------------------------------------------+
| ``lsd`` | The peer was received from the local service |
| | discovery (The peer is on the local network). |
+------------------------+--------------------------------------------------------+
| ``resume_data`` | The peer was added from the fast resume data. |
+------------------------+--------------------------------------------------------+
The ``ip`` field is the IP-address to this peer. The type is an asio endpoint. For
more info, see the asio_ documentation.

View File

@ -245,7 +245,7 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
{
using namespace libtorrent;
#ifndef ANSI_TERMINAL_COLORS
out << " down (total) up (total) q r flags block progress country client \n";
out << " down (total) up (total) q r flags source block progress country client \n";
#endif
for (std::vector<peer_info>::const_iterator i = peers.begin();
@ -267,7 +267,13 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
<< ((i->flags & peer_info::remote_interested)?'i':'.')
<< ((i->flags & peer_info::remote_choked)?'c':'.')
<< ((i->flags & peer_info::supports_extensions)?'e':'.')
<< ((i->flags & peer_info::local_connection)?'l':'r') << " ";
<< ((i->flags & peer_info::local_connection)?'l':'r') << " "
<< ((i->source & peer_info::tracker)?"T":"_")
<< ((i->source & peer_info::pex)?"P":"_")
<< ((i->source & peer_info::dht)?"D":"_")
<< ((i->source & peer_info::lsd)?"L":"_")
<< ((i->source & peer_info::resume_data)?"R":"_")
<< " ";
if (i->downloading_piece_index >= 0)
{

View File

@ -91,13 +91,15 @@ namespace libtorrent
aux::session_impl& ses
, boost::weak_ptr<torrent> t
, boost::shared_ptr<stream_socket> s
, tcp::endpoint const& remote);
, tcp::endpoint const& remote
, policy::peer* peerinfo);
// with this constructor we have been contacted and we still don't
// know which torrent the connection belongs to
bt_peer_connection(
aux::session_impl& ses
, boost::shared_ptr<stream_socket> s);
, boost::shared_ptr<stream_socket> s
, policy::peer* peerinfo);
~bt_peer_connection();

View File

@ -71,6 +71,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/bandwidth_manager.hpp"
#include "libtorrent/policy.hpp"
// TODO: each time a block is 'taken over'
// from another peer. That peer must be given
@ -117,16 +118,27 @@ namespace libtorrent
, boost::weak_ptr<torrent> t
, boost::shared_ptr<stream_socket> s
, tcp::endpoint const& remote
, tcp::endpoint const& proxy);
, tcp::endpoint const& proxy
, policy::peer* peerinfo);
// with this constructor we have been contacted and we still don't
// know which torrent the connection belongs to
peer_connection(
aux::session_impl& ses
, boost::shared_ptr<stream_socket> s);
, boost::shared_ptr<stream_socket> s
, policy::peer* peerinfo);
virtual ~peer_connection();
void set_peer_info(policy::peer* pi)
{
assert(m_peer_info == 0);
m_peer_info = pi;
}
policy::peer* peer_info_struct() const
{ return m_peer_info; }
#ifndef TORRENT_DISABLE_EXTENSIONS
void add_extension(boost::shared_ptr<peer_plugin>);
#endif
@ -640,6 +652,11 @@ namespace libtorrent
int m_upload_limit;
int m_download_limit;
// this peer's peer info struct. This may
// be 0, in case the connection is incoming
// and hasn't been added to a torrent yet.
policy::peer* m_peer_info;
#ifndef NDEBUG
public:
bool m_in_constructor;

View File

@ -56,7 +56,20 @@ namespace libtorrent
connecting = 0x80,
queued = 0x100
};
unsigned int flags;
enum peer_source_flags
{
tracker = 0x1,
dht = 0x2,
pex = 0x4,
lsd = 0x8,
resume_data = 0x10
};
int source;
tcp::endpoint ip;
float up_speed;
float down_speed;

View File

@ -84,9 +84,9 @@ namespace libtorrent
void pulse();
// this is called once for every peer we get from
// the tracker
// the tracker, pex, lsd or dht.
void peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid
, char flags = 0);
, int source, char flags);
// called when an incoming connection is accepted
void new_connection(peer_connection& c);
@ -135,7 +135,7 @@ namespace libtorrent
{
enum connection_type { not_connectable,connectable };
peer(const tcp::endpoint& ip, connection_type t);
peer(const tcp::endpoint& ip, connection_type t, int src);
size_type total_download() const;
size_type total_upload() const;
@ -176,6 +176,10 @@ namespace libtorrent
// is set to true if this peer has been banned
bool banned;
// a bitmap combining the peer_source flags
// from peer_info.
int source;
// if the peer is connected now, this
// will refer to a valid peer_connection
peer_connection* connection;
@ -191,7 +195,8 @@ namespace libtorrent
return m_num_unchoked;
}
typedef std::vector<peer>::iterator iterator;
typedef std::list<peer>::iterator iterator;
typedef std::list<peer>::const_iterator const_iterator;
iterator begin_peer() { return m_peers.begin(); }
iterator end_peer() { return m_peers.end(); }
@ -231,7 +236,7 @@ namespace libtorrent
};
std::vector<peer> m_peers;
std::list<peer> m_peers;
torrent* m_torrent;

View File

@ -181,7 +181,6 @@ namespace libtorrent
void filter_files(std::vector<bool> const& files);
// ============ end deprecation =============
void set_piece_priority(int index, int priority);
int piece_priority(int index) const;
@ -190,7 +189,6 @@ namespace libtorrent
void prioritize_files(std::vector<int> const& files);
torrent_status status() const;
void file_progress(std::vector<float>& fp) const;
@ -198,7 +196,7 @@ namespace libtorrent
tcp::endpoint const& get_interface() const { return m_net_interface; }
void connect_to_url_seed(std::string const& url);
peer_connection& connect_to_peer(tcp::endpoint const& a);
peer_connection& connect_to_peer(policy::peer* peerinfo);
void set_ratio(float ratio)
{ assert(ratio >= 0.0f); m_ratio = ratio; }

View File

@ -311,7 +311,7 @@ namespace libtorrent
void set_peer_download_limit(tcp::endpoint ip, int limit) const;
// manually connect a peer
void connect_peer(tcp::endpoint const& adr) const;
void connect_peer(tcp::endpoint const& adr, int source = 0) const;
// valid ratios are 0 (infinite ratio) or [ 1.0 , inf )
// the ratio is uploaded / downloaded. less than 1 is not allowed

View File

@ -98,7 +98,8 @@ namespace libtorrent
, boost::shared_ptr<stream_socket> s
, tcp::endpoint const& remote
, tcp::endpoint const& proxy
, std::string const& url);
, std::string const& url
, policy::peer* peerinfo);
~web_peer_connection();

View File

@ -79,8 +79,10 @@ namespace libtorrent
session_impl& ses
, boost::weak_ptr<torrent> tor
, shared_ptr<stream_socket> s
, tcp::endpoint const& remote)
: peer_connection(ses, tor, s, remote, tcp::endpoint())
, tcp::endpoint const& remote
, policy::peer* peerinfo)
: peer_connection(ses, tor, s, remote
, tcp::endpoint(), peerinfo)
, m_state(read_protocol_length)
#ifndef TORRENT_DISABLE_EXTENSIONS
, m_supports_extensions(false)
@ -117,8 +119,9 @@ namespace libtorrent
bt_peer_connection::bt_peer_connection(
session_impl& ses
, boost::shared_ptr<stream_socket> s)
: peer_connection(ses, s)
, boost::shared_ptr<stream_socket> s
, policy::peer* peerinfo)
: peer_connection(ses, s, peerinfo)
, m_state(read_protocol_length)
#ifndef TORRENT_DISABLE_EXTENSIONS
, m_supports_extensions(false)
@ -240,6 +243,16 @@ namespace libtorrent
p.client = m_client_version;
p.connection_type = peer_info::standard_bittorrent;
if (peer_info_struct())
{
p.source = peer_info_struct()->source;
}
else
{
assert(!is_local());
p.source = 0;
}
}
bool bt_peer_connection::in_handshake() const
@ -692,7 +705,7 @@ namespace libtorrent
{
tcp::endpoint adr(remote().address()
, (unsigned short)listen_port->integer());
t->get_policy().peer_from_tracker(adr, pid());
t->get_policy().peer_from_tracker(adr, pid(), 0, 0);
}
}
// there should be a version too

View File

@ -49,6 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/version.hpp"
#include "libtorrent/extensions.hpp"
#include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/policy.hpp"
using boost::bind;
using boost::shared_ptr;
@ -77,7 +78,8 @@ namespace libtorrent
, boost::weak_ptr<torrent> tor
, shared_ptr<stream_socket> s
, tcp::endpoint const& remote
, tcp::endpoint const& proxy)
, tcp::endpoint const& proxy
, policy::peer* peerinfo)
:
#ifndef NDEBUG
m_last_choke(time_now() - hours(1))
@ -122,6 +124,7 @@ namespace libtorrent
, m_refs(0)
, m_upload_limit(resource_request::inf)
, m_download_limit(resource_request::inf)
, m_peer_info(peerinfo)
#ifndef NDEBUG
, m_in_constructor(true)
#endif
@ -143,7 +146,8 @@ namespace libtorrent
peer_connection::peer_connection(
session_impl& ses
, boost::shared_ptr<stream_socket> s)
, boost::shared_ptr<stream_socket> s
, policy::peer* peerinfo)
:
#ifndef NDEBUG
m_last_choke(time_now() - hours(1))
@ -185,6 +189,7 @@ namespace libtorrent
, m_refs(0)
, m_upload_limit(resource_request::inf)
, m_download_limit(resource_request::inf)
, m_peer_info(peerinfo)
#ifndef NDEBUG
, m_in_constructor(true)
#endif

View File

@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include <boost/bind.hpp>
#include <boost/utility.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
@ -393,7 +394,7 @@ namespace libtorrent
// TODO: make this selection better
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
peer_connection* c = i->connection;
@ -440,7 +441,7 @@ namespace libtorrent
// TODO: make this selection better
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
peer_connection* c = i->connection;
@ -466,7 +467,7 @@ namespace libtorrent
ptime local_time = time_now();
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
peer_connection* c = i->connection;
@ -502,7 +503,7 @@ namespace libtorrent
ptime ptime(now);
policy::peer* candidate = 0;
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
if (i->connection) continue;
@ -545,7 +546,7 @@ namespace libtorrent
peer* second_candidate = 0;
size_type lowest_share_diff = 0; // not valid when secondCandidate==0
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
peer_connection* c = i->connection;
@ -588,7 +589,7 @@ namespace libtorrent
peer* candidate = 0;
ptime last_unchoke = time_now();
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
peer_connection* c = i->connection;
@ -652,7 +653,7 @@ namespace libtorrent
// that are currently in the process of disconnecting
int num_connected_peers = 0;
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
if (i->connection && !i->connection->is_disconnecting())
@ -784,7 +785,7 @@ namespace libtorrent
if (m_torrent->ratio() != 0)
{
// choke peers that have leeched too much without giving anything back
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
peer_connection* c = i->connection;
@ -849,7 +850,7 @@ namespace libtorrent
{
INVARIANT_CHECK;
std::vector<peer>::iterator i = std::find_if(
iterator i = std::find_if(
m_peers.begin()
, m_peers.end()
, match_peer_connection(c));
@ -873,7 +874,7 @@ namespace libtorrent
{
INVARIANT_CHECK;
std::vector<peer>::iterator i = std::find_if(
iterator i = std::find_if(
m_peers.begin()
, m_peers.end()
, match_peer_connection(c));
@ -912,7 +913,7 @@ namespace libtorrent
}
#endif
std::vector<peer>::iterator i;
iterator i;
if (m_torrent->settings().allow_multiple_connections_per_ip)
{
@ -959,11 +960,12 @@ namespace libtorrent
assert((c.proxy() == tcp::endpoint() && c.remote() == c.get_socket()->remote_endpoint())
|| c.proxy() == c.get_socket()->remote_endpoint());
peer p(c.remote(), peer::not_connectable);
peer p(c.remote(), peer::not_connectable, 0);
m_peers.push_back(p);
i = m_peers.end()-1;
i = boost::prior(m_peers.end());
}
c.set_peer_info(&*i);
assert(i->connection == 0);
c.add_stat(i->prev_amount_download, i->prev_amount_upload);
i->prev_amount_download = 0;
@ -975,7 +977,7 @@ namespace libtorrent
}
void policy::peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid
, char flags)
, int src, char flags)
{
INVARIANT_CHECK;
@ -985,7 +987,7 @@ namespace libtorrent
try
{
std::vector<peer>::iterator i;
iterator i;
if (m_torrent->settings().allow_multiple_connections_per_ip)
{
@ -1005,11 +1007,11 @@ namespace libtorrent
{
// we don't have any info about this peer.
// add a new entry
peer p(remote, peer::connectable);
peer p(remote, peer::connectable, src);
m_peers.push_back(p);
// the iterator is invalid
// because of the push_back()
i = m_peers.end() - 1;
i = boost::prior(m_peers.end());
if (flags & 0x02) p.seed = true;
just_added = true;
}
@ -1021,6 +1023,8 @@ namespace libtorrent
// not known, so save it. Client may also have changed port
// for some reason.
i->ip = remote;
i->source |= src;
if (flags & 0x02) i->seed = true;
if (i->connection)
@ -1042,6 +1046,7 @@ namespace libtorrent
if (i->banned) return;
// TODO: move the connecting of peers somewhere else!
if (m_torrent->num_peers() < m_torrent->m_connections_quota.given
&& !m_torrent->is_paused())
{
@ -1050,7 +1055,7 @@ namespace libtorrent
// if this peer was just added, and it
// failed to connect. Remove it from the list
// (to keep it in sync with the session's list)
assert(i == m_peers.end() - 1);
assert(i == boost::prior(m_peers.end()));
m_peers.erase(i);
}
}
@ -1082,7 +1087,7 @@ namespace libtorrent
if (successfully_verified)
{
// have all peers update their interested-flag
for (std::vector<peer>::iterator i = m_peers.begin();
for (iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
if (i->connection == 0) continue;
@ -1221,7 +1226,7 @@ namespace libtorrent
try
{
assert(!p->connection);
p->connection = &m_torrent->connect_to_peer(p->ip);
p->connection = &m_torrent->connect_to_peer(p);
assert(p->connection);
p->connection->add_stat(p->prev_amount_download, p->prev_amount_upload);
p->prev_amount_download = 0;
@ -1258,7 +1263,7 @@ namespace libtorrent
bool unchoked = false;
bool erase = false;
std::vector<peer>::iterator i = std::find_if(
iterator i = std::find_if(
m_peers.begin()
, m_peers.end()
, match_peer_connection(c));
@ -1345,7 +1350,7 @@ namespace libtorrent
int nonempty_connections = 0;
for (std::vector<peer>::const_iterator i = m_peers.begin();
for (const_iterator i = m_peers.begin();
i != m_peers.end(); ++i)
{
++total_connections;
@ -1389,7 +1394,7 @@ namespace libtorrent
}
#endif
policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t)
policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src)
: ip(ip_)
, type(t)
, failcount(0)
@ -1399,6 +1404,7 @@ namespace libtorrent
, prev_amount_upload(0)
, prev_amount_download(0)
, banned(false)
, source(src)
, connection(0)
{
assert(connected < time_now());

View File

@ -215,7 +215,8 @@ namespace libtorrent { namespace detail
for (std::vector<tcp::endpoint>::const_iterator i = t->peers.begin();
i != t->peers.end(); ++i)
{
t->torrent_ptr->get_policy().peer_from_tracker(*i, id);
t->torrent_ptr->get_policy().peer_from_tracker(*i, id
, peer_info::resume_data, 0);
}
}
else
@ -337,7 +338,8 @@ namespace libtorrent { namespace detail
for (std::vector<tcp::endpoint>::const_iterator i = processing->peers.begin();
i != processing->peers.end(); ++i)
{
processing->torrent_ptr->get_policy().peer_from_tracker(*i, id);
processing->torrent_ptr->get_policy().peer_from_tracker(*i, id
, peer_info::resume_data, 0);
}
}
else
@ -772,7 +774,7 @@ namespace libtorrent { namespace detail
}
boost::intrusive_ptr<peer_connection> c(
new bt_peer_connection(*this, s));
new bt_peer_connection(*this, s, 0));
#ifndef NDEBUG
c->m_in_constructor = false;
#endif
@ -1513,7 +1515,7 @@ namespace libtorrent { namespace detail
(*m_logger) << time_now_string()
<< ": added peer from local discovery: " << peer << "\n";
#endif
t->get_policy().peer_from_tracker(peer, peer_id(0));
t->get_policy().peer_from_tracker(peer, peer_id(0), peer_info::lsd, 0);
}
void session_impl::on_port_mapping(int tcp_port, int udp_port

View File

@ -468,7 +468,8 @@ namespace libtorrent
get_handle(), peers.size(), "Got peers from DHT"));
}
std::for_each(peers.begin(), peers.end(), bind(
&policy::peer_from_tracker, boost::ref(m_policy), _1, peer_id(0), 0));
&policy::peer_from_tracker, boost::ref(m_policy), _1, peer_id(0)
, peer_info::dht, 0));
}
#endif
@ -565,7 +566,7 @@ namespace libtorrent
continue;
}
m_policy->peer_from_tracker(a, i->pid);
m_policy->peer_from_tracker(a, i->pid, peer_info::tracker, 0);
}
catch (std::exception&)
{
@ -607,7 +608,7 @@ namespace libtorrent
return;
}
m_policy->peer_from_tracker(*host, pid);
m_policy->peer_from_tracker(*host, pid, peer_info::tracker, 0);
}
catch (std::exception&)
{};
@ -1425,7 +1426,7 @@ namespace libtorrent
boost::shared_ptr<stream_socket> s(new stream_socket(m_ses.m_io_service));
boost::intrusive_ptr<peer_connection> c(new web_peer_connection(
m_ses, shared_from_this(), s, a, proxy, url));
m_ses, shared_from_this(), s, a, proxy, url, 0));
#ifndef NDEBUG
c->m_in_constructor = false;
@ -1791,10 +1792,10 @@ namespace libtorrent
}
}
peer_connection& torrent::connect_to_peer(const tcp::endpoint& a)
peer_connection& torrent::connect_to_peer(policy::peer* peerinfo)
{
INVARIANT_CHECK;
tcp::endpoint const& a(peerinfo->ip);
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
throw protocol_error(a.address().to_string() + " blocked by ip filter");
@ -1803,7 +1804,7 @@ namespace libtorrent
boost::shared_ptr<stream_socket> s(new stream_socket(m_ses.m_io_service));
boost::intrusive_ptr<peer_connection> c(new bt_peer_connection(
m_ses, shared_from_this(), s, a));
m_ses, shared_from_this(), s, a, peerinfo));
#ifndef NDEBUG
c->m_in_constructor = false;

View File

@ -626,7 +626,7 @@ namespace libtorrent
, bind(&torrent::save_path, _1));
}
void torrent_handle::connect_peer(tcp::endpoint const& adr) const
void torrent_handle::connect_peer(tcp::endpoint const& adr, int source) const
{
INVARIANT_CHECK;
@ -650,7 +650,7 @@ namespace libtorrent
peer_id id;
std::fill(id.begin(), id.end(), 0);
t->get_policy().peer_from_tracker(adr, id);
t->get_policy().peer_from_tracker(adr, id, source, 0);
}
void torrent_handle::force_reannounce(

View File

@ -217,7 +217,7 @@ namespace libtorrent { namespace
{
tcp::endpoint adr = detail::read_v4_endpoint<tcp::endpoint>(in);
char flags = detail::read_uint8(fin);
p.peer_from_tracker(adr, pid, flags);
p.peer_from_tracker(adr, pid, peer_info::pex, flags);
}
return true;
}

View File

@ -62,8 +62,9 @@ namespace libtorrent
, boost::shared_ptr<stream_socket> s
, tcp::endpoint const& remote
, tcp::endpoint const& proxy
, std::string const& url)
: peer_connection(ses, t, s, remote, proxy)
, std::string const& url
, policy::peer* peerinfo)
: peer_connection(ses, t, s, remote, proxy, peerinfo)
, m_url(url)
, m_first_request(true)
{
@ -587,6 +588,7 @@ namespace libtorrent
p.client = m_server_string;
p.connection_type = peer_info::web_seed;
p.source = 0;
}
bool web_peer_connection::in_handshake() const