*** empty log message ***
This commit is contained in:
parent
b6c826c6af
commit
abbedbf104
|
@ -1305,10 +1305,8 @@ tells which piece is on which slot. If piece index is -2 it
|
|||
means it is free, that there's no piece there. If it is -1,
|
||||
means the slot isn't allocated on disk yet. The pieces have
|
||||
to meet the following requirement:</p>
|
||||
<ul class="last simple">
|
||||
<li>if there's a slot at the position of the piece index,
|
||||
the piece must be located in that slot.</li>
|
||||
</ul>
|
||||
<p class="last">If there's a slot at the position of the piece index,
|
||||
the piece must be located in that slot.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">peers</span></tt></td>
|
||||
|
|
|
@ -1104,6 +1104,29 @@ as severity level ``debug``.
|
|||
};
|
||||
|
||||
|
||||
invalid_request_alert
|
||||
---------------------
|
||||
|
||||
Thie is a debug alert that is generated by an incoming invalid piece request.
|
||||
|
||||
::
|
||||
|
||||
struct invalid_request_alert: alert
|
||||
{
|
||||
invalid_request_alert(
|
||||
const peer_request& r
|
||||
, const torrent_handle& h
|
||||
, const peer_id& send
|
||||
, const std::string& msg);
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const;
|
||||
|
||||
torrent_handle handle;
|
||||
peer_id sender;
|
||||
peer_request request;
|
||||
};
|
||||
|
||||
|
||||
|
||||
chat_message_alert
|
||||
------------------
|
||||
|
@ -1372,7 +1395,7 @@ The file format is a bencoded dictionary containing the following fields:
|
|||
| | means the slot isn't allocated on disk yet. The pieces have |
|
||||
| | to meet the following requirement: |
|
||||
| | |
|
||||
| | * if there's a slot at the position of the piece index, |
|
||||
| | If there's a slot at the position of the piece index, |
|
||||
| | the piece must be located in that slot. |
|
||||
+----------------------+--------------------------------------------------------------+
|
||||
| ``peers`` | list of dictionaries. Each dictionary has the following |
|
||||
|
@ -1398,6 +1421,7 @@ The file format is a bencoded dictionary containing the following fields:
|
|||
| | | | blocks that have been downloaded in this | |
|
||||
| | | | piece. | |
|
||||
| | +-------------+--------------------------------------------+ |
|
||||
| | |
|
||||
+----------------------+--------------------------------------------------------------+
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
|
@ -186,9 +187,9 @@ std::string add_suffix(float val)
|
|||
int i;
|
||||
for (i = 0; i < num_prefix; ++i)
|
||||
{
|
||||
if (fabs(val) < 1024.f)
|
||||
if (fabs(val) < 1000.f)
|
||||
return to_string(val, i==0?7:6) + prefix[i];
|
||||
val /= 1024.f;
|
||||
val /= 1000.f;
|
||||
}
|
||||
return to_string(val, 6) + prefix[i];
|
||||
}
|
||||
|
@ -233,11 +234,13 @@ int main(int argc, char* argv[])
|
|||
torrent_info t(e);
|
||||
t.print(std::cout);
|
||||
|
||||
boost::filesystem::path save_path("");
|
||||
entry resume_data;
|
||||
try
|
||||
{
|
||||
// TODO: use a torrent-specific name here
|
||||
std::ifstream resume_file("test.fastresume", std::ios_base::binary);
|
||||
std::stringstream s;
|
||||
s << t.name() << ".fastresume";
|
||||
boost::filesystem::ifstream resume_file(save_path / s.str(), std::ios_base::binary);
|
||||
resume_file.unsetf(std::ios_base::skipws);
|
||||
resume_data = bdecode(std::istream_iterator<char>(resume_file)
|
||||
, std::istream_iterator<char>());
|
||||
|
@ -245,7 +248,7 @@ int main(int argc, char* argv[])
|
|||
catch (invalid_encoding&)
|
||||
{}
|
||||
|
||||
handles.push_back(ses.add_torrent(t, "", resume_data));
|
||||
handles.push_back(ses.add_torrent(t, save_path, resume_data));
|
||||
handles.back().set_max_uploads(7);
|
||||
handles.back().set_ratio(1);
|
||||
}
|
||||
|
@ -265,11 +268,18 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
if (c == 'q')
|
||||
{
|
||||
entry data = handles.front().write_resume_data();
|
||||
// TODO: use a torrent-specific name here
|
||||
std::ofstream out("test.fastresume", std::ios_base::binary);
|
||||
for (std::vector<torrent_handle>::iterator i = handles.begin();
|
||||
i != handles.end();
|
||||
++i)
|
||||
{
|
||||
torrent_handle h = *i;
|
||||
entry data = h.write_resume_data();
|
||||
std::stringstream s;
|
||||
s << h.get_torrent_info().name() << ".fastresume";
|
||||
boost::filesystem::ofstream out(h.save_path() / s.str(), std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,6 @@ namespace libtorrent
|
|||
peer_id sender;
|
||||
};
|
||||
|
||||
// TODO: document
|
||||
struct invalid_request_alert: alert
|
||||
{
|
||||
invalid_request_alert(
|
||||
|
|
|
@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <bitset>
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
|
||||
|
@ -166,10 +168,13 @@ namespace libtorrent
|
|||
// the hash-check yet
|
||||
int unverified_blocks() const;
|
||||
|
||||
void get_downloaders(std::vector<address>& d, int index);
|
||||
void get_downloaders(std::vector<address>& d, int index) const;
|
||||
|
||||
const std::vector<downloading_piece>& get_download_queue() const
|
||||
{ return m_downloads; }
|
||||
|
||||
boost::optional<address> get_downloader(piece_block block) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// used in debug mode
|
||||
void integrity_check(const torrent* t = 0) const;
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace libtorrent
|
|||
{
|
||||
file_allocation_failed(const char* error_msg): m_msg(error_msg) {}
|
||||
virtual const char* what() const throw() { return m_msg.c_str(); }
|
||||
virtual ~file_allocation_failed() {}
|
||||
virtual ~file_allocation_failed() throw() {}
|
||||
std::string m_msg;
|
||||
};
|
||||
|
||||
|
|
|
@ -173,6 +173,13 @@ namespace libtorrent
|
|||
// decreased in the piece_picker
|
||||
void remove_peer(peer_connection* p);
|
||||
|
||||
peer_connection* connection_for(const address& a)
|
||||
{
|
||||
peer_iterator i = m_connections.find(a);
|
||||
if (i == m_connections.end()) return 0;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
// the number of peers that belong to this torrent
|
||||
int num_peers() const { return m_connections.size(); }
|
||||
|
||||
|
@ -180,11 +187,11 @@ namespace libtorrent
|
|||
// to a peer with the given peer_id
|
||||
bool has_peer(const peer_id& id) const;
|
||||
|
||||
typedef std::vector<peer_connection*>::iterator peer_iterator;
|
||||
typedef std::vector<peer_connection*>::const_iterator peer_const_iterator;
|
||||
typedef std::map<address, peer_connection*>::iterator peer_iterator;
|
||||
typedef std::map<address, peer_connection*>::const_iterator const_peer_iterator;
|
||||
|
||||
peer_const_iterator begin() const { return m_connections.begin(); }
|
||||
peer_const_iterator end() const { return m_connections.end(); }
|
||||
const_peer_iterator begin() const { return m_connections.begin(); }
|
||||
const_peer_iterator end() const { return m_connections.end(); }
|
||||
|
||||
peer_iterator begin() { return m_connections.begin(); }
|
||||
peer_iterator end() { return m_connections.end(); }
|
||||
|
@ -311,7 +318,10 @@ namespace libtorrent
|
|||
// from the tracker
|
||||
int m_duration;
|
||||
|
||||
std::vector<peer_connection*> m_connections;
|
||||
// TODO: this should be a map, mapping address
|
||||
// to peer_connection*
|
||||
std::map<address, peer_connection*> m_connections;
|
||||
// std::vector<peer_connection*> m_connections;
|
||||
|
||||
// this is the upload and download statistics for the whole torrent.
|
||||
// it's updated from all its peers once every second.
|
||||
|
|
|
@ -33,7 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "libtorrent/peer_connection.hpp"
|
||||
|
@ -620,8 +619,8 @@ namespace libtorrent
|
|||
&& i->block_index == p.start / m_torrent->block_size())
|
||||
break;
|
||||
|
||||
(*m_logger) << " <== SKIPPED_PIECE [ piece: " << i->piece_index << " | "
|
||||
"b: " << i->block_index << " ]\n";
|
||||
(*m_logger) << " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | "
|
||||
"b: " << i->block_index << " ] ***\n";
|
||||
if (m_torrent->alerts().should_post(alert::debug))
|
||||
{
|
||||
std::stringstream s;
|
||||
|
@ -640,6 +639,9 @@ namespace libtorrent
|
|||
piece_picker& picker = m_torrent->picker();
|
||||
piece_block block_finished(p.piece, p.start / m_torrent->block_size());
|
||||
|
||||
// if the block we got is already finished, then ignore it
|
||||
if (picker.is_finished(block_finished)) return;
|
||||
|
||||
std::deque<piece_block>::iterator b
|
||||
= std::find(
|
||||
m_download_queue.begin()
|
||||
|
@ -654,12 +656,31 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
// TODO: cancel the block from the
|
||||
// cancel the block from the
|
||||
// peer that has taken over it.
|
||||
boost::optional<address> peer = m_torrent->picker().get_downloader(block_finished);
|
||||
if (peer)
|
||||
{
|
||||
peer_connection* pc = m_torrent->connection_for(*peer);
|
||||
if (pc && pc != this)
|
||||
{
|
||||
pc->send_cancel(block_finished);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_torrent->alerts().should_post(alert::debug))
|
||||
{
|
||||
m_torrent->alerts().post_alert(
|
||||
peer_error_alert(
|
||||
m_peer_id
|
||||
, "got a block that was not requested"));
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << " *** The block we just got was not requested ***\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// if the block we got is already finished, then ignore it
|
||||
if (picker.is_finished(block_finished)) return;
|
||||
|
||||
m_torrent->filesystem().write(&m_recv_buffer[9], p.piece, p.start, p.length);
|
||||
|
||||
|
@ -1026,7 +1047,6 @@ namespace libtorrent
|
|||
send_buffer_updated();
|
||||
}
|
||||
|
||||
// TODO: rename to send_choke?
|
||||
void peer_connection::send_choke()
|
||||
{
|
||||
if (m_choked) return;
|
||||
|
|
|
@ -152,11 +152,11 @@ namespace libtorrent
|
|||
if (t != 0)
|
||||
{
|
||||
int actual_peer_count = 0;
|
||||
for (std::vector<peer_connection*>::const_iterator peer = t->begin();
|
||||
for (torrent::const_peer_iterator peer = t->begin();
|
||||
peer != t->end();
|
||||
++peer)
|
||||
{
|
||||
if ((*peer)->has_piece(index)) actual_peer_count++;
|
||||
if (peer->second->has_piece(index)) actual_peer_count++;
|
||||
}
|
||||
|
||||
assert(i->peer_count == actual_peer_count);
|
||||
|
@ -518,7 +518,11 @@ namespace libtorrent
|
|||
|
||||
if (m_piece_map[block.piece_index].downloading == 0) return false;
|
||||
std::vector<downloading_piece>::const_iterator i
|
||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
|
||||
= std::find_if(
|
||||
m_downloads.begin()
|
||||
, m_downloads.end()
|
||||
, has_index(block.piece_index));
|
||||
|
||||
assert(i != m_downloads.end());
|
||||
return i->requested_blocks[block.block_index];
|
||||
}
|
||||
|
@ -632,9 +636,9 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
*/
|
||||
void piece_picker::get_downloaders(std::vector<address>& d, int index)
|
||||
void piece_picker::get_downloaders(std::vector<address>& d, int index) const
|
||||
{
|
||||
std::vector<downloading_piece>::iterator i
|
||||
std::vector<downloading_piece>::const_iterator i
|
||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index));
|
||||
assert(i != m_downloads.end());
|
||||
|
||||
|
@ -645,6 +649,26 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
boost::optional<address> piece_picker::get_downloader(piece_block block) const
|
||||
{
|
||||
std::vector<downloading_piece>::const_iterator i = std::find_if(
|
||||
m_downloads.begin()
|
||||
, m_downloads.end()
|
||||
, has_index(block.piece_index));
|
||||
|
||||
if (i == m_downloads.end())
|
||||
return boost::optional<address>();
|
||||
|
||||
assert(block.block_index < max_blocks_per_piece);
|
||||
assert(block.block_index >= 0);
|
||||
|
||||
if (i->requested_blocks[block.block_index] == false
|
||||
|| i->finished_blocks[block.block_index] == true)
|
||||
return boost::optional<address>();
|
||||
|
||||
return boost::optional<address>(i->info[block.block_index].peer);
|
||||
}
|
||||
|
||||
void piece_picker::abort_download(piece_block block)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -168,15 +168,15 @@ namespace
|
|||
i != t.end();
|
||||
++i)
|
||||
{
|
||||
const std::deque<piece_block>& queue = (*i)->download_queue();
|
||||
if ((*i)->statistics().down_peak() > down_speed
|
||||
const std::deque<piece_block>& queue = i->second->download_queue();
|
||||
if (i->second->statistics().down_peak() > down_speed
|
||||
&& has_intersection(busy_pieces.begin(),
|
||||
busy_pieces.end(),
|
||||
queue.begin(),
|
||||
queue.end()))
|
||||
{
|
||||
peer = *i;
|
||||
down_speed = (*i)->statistics().down_peak();
|
||||
peer = i->second;
|
||||
down_speed = peer->statistics().down_peak();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,12 +209,12 @@ namespace
|
|||
// want to trade it's surplus uploads for downloads itself
|
||||
// (and we should consider it free). If the share diff is
|
||||
// negative, there's no free download to get from this peer.
|
||||
int diff = (*i)->share_diff();
|
||||
if ((*i)->is_peer_interested() || diff <= 0)
|
||||
int diff = i->second->share_diff();
|
||||
if (i->second->is_peer_interested() || diff <= 0)
|
||||
continue;
|
||||
|
||||
assert(diff > 0);
|
||||
(*i)->add_free_upload(-diff);
|
||||
i->second->add_free_upload(-diff);
|
||||
accumulator += diff;
|
||||
assert(accumulator > 0);
|
||||
}
|
||||
|
@ -235,8 +235,8 @@ namespace
|
|||
int total_diff = 0;
|
||||
for (torrent::peer_iterator i = start; i != end; ++i)
|
||||
{
|
||||
total_diff += (*i)->share_diff();
|
||||
if (!(*i)->is_peer_interested() || (*i)->share_diff() >= 0) continue;
|
||||
total_diff += i->second->share_diff();
|
||||
if (!i->second->is_peer_interested() || i->second->share_diff() >= 0) continue;
|
||||
++num_peers;
|
||||
}
|
||||
|
||||
|
@ -254,8 +254,9 @@ namespace
|
|||
|
||||
for (torrent::peer_iterator i = start; i != end; ++i)
|
||||
{
|
||||
if (!(*i)->is_peer_interested() || (*i)->share_diff() >= 0) continue;
|
||||
(*i)->add_free_upload(upload_share);
|
||||
peer_connection* p = i->second;
|
||||
if (!p->is_peer_interested() || p->share_diff() >= 0) continue;
|
||||
p->add_free_upload(upload_share);
|
||||
free_upload -= upload_share;
|
||||
}
|
||||
return free_upload;
|
||||
|
|
|
@ -43,7 +43,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/filesystem/convenience.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#include "libtorrent/storage.hpp"
|
||||
|
@ -437,6 +436,8 @@ namespace libtorrent {
|
|||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
check_invariant();
|
||||
|
||||
p.clear();
|
||||
std::vector<int>::const_reverse_iterator last;
|
||||
for (last = m_slot_to_piece.rbegin();
|
||||
|
@ -453,6 +454,9 @@ namespace libtorrent {
|
|||
{
|
||||
p.push_back(*i);
|
||||
}
|
||||
|
||||
check_invariant();
|
||||
|
||||
}
|
||||
|
||||
void piece_manager::export_piece_map(
|
||||
|
@ -462,22 +466,30 @@ namespace libtorrent {
|
|||
}
|
||||
|
||||
// TODO: daniel, make sure this function does everything it needs to do
|
||||
void piece_manager::impl::mark_failed(int index)
|
||||
void piece_manager::impl::mark_failed(int piece_index)
|
||||
{
|
||||
// synchronization ------------------------------------------------------
|
||||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
assert(index >= 0 && index < m_piece_to_slot.size());
|
||||
assert(m_piece_to_slot[index] >= 0);
|
||||
#ifndef NDEBUG
|
||||
check_invariant();
|
||||
#endif
|
||||
assert(piece_index >= 0 && piece_index < m_piece_to_slot.size());
|
||||
assert(m_piece_to_slot[piece_index] >= 0);
|
||||
|
||||
int slot = m_slot_to_piece[m_piece_to_slot[index]];
|
||||
int slot_index = m_piece_to_slot[piece_index];
|
||||
|
||||
assert(slot >= 0);
|
||||
assert(slot_index >= 0);
|
||||
|
||||
m_slot_to_piece[slot_index] = -2;
|
||||
m_piece_to_slot[piece_index] = -1;
|
||||
m_free_slots.push_back(slot_index);
|
||||
|
||||
#ifndef NDEBUG
|
||||
check_invariant();
|
||||
#endif
|
||||
|
||||
m_slot_to_piece[m_piece_to_slot[index]] = -2;
|
||||
m_piece_to_slot[index] = -1;
|
||||
m_free_slots.push_back(slot);
|
||||
}
|
||||
|
||||
void piece_manager::mark_failed(int index)
|
||||
|
@ -809,6 +821,9 @@ namespace libtorrent {
|
|||
{
|
||||
assert(slot_index >= 0);
|
||||
assert(slot_index < m_slot_to_piece.size());
|
||||
|
||||
check_invariant();
|
||||
|
||||
return slot_index;
|
||||
}
|
||||
|
||||
|
|
124
src/torrent.cpp
124
src/torrent.cpp
|
@ -167,16 +167,6 @@ namespace
|
|||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const peer_connection* p) const
|
||||
{
|
||||
if (p->get_peer_id() != id) return false;
|
||||
if (tor != p->associated_torrent()) return false;
|
||||
// have a special case for all zeros. We can have any number
|
||||
// of peers with that id, since it's used to indicate no id.
|
||||
if (std::count(id.begin(), id.end(), 0) == 20) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const peer_id& id;
|
||||
const torrent* tor;
|
||||
};
|
||||
|
@ -196,6 +186,23 @@ namespace
|
|||
const torrent* tor;
|
||||
};
|
||||
|
||||
|
||||
struct peer_by_id
|
||||
{
|
||||
peer_by_id(const peer_id& i): id(i) {}
|
||||
|
||||
bool operator()(const std::pair<address, peer_connection*>& p) const
|
||||
{
|
||||
if (p.second->get_peer_id() != id) return false;
|
||||
// have a special case for all zeros. We can have any number
|
||||
// of peers with that id, since it's used to indicate no id.
|
||||
if (std::count(id.begin(), id.end(), 0) == 20) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const peer_id& id;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace libtorrent
|
||||
|
@ -313,7 +320,7 @@ namespace libtorrent
|
|||
{
|
||||
assert(std::count_if(m_connections.begin()
|
||||
, m_connections.end()
|
||||
, find_peer_by_id(id, this)) <= 1);
|
||||
, peer_by_id(id)) <= 1);
|
||||
|
||||
// pretend that we are connected to
|
||||
// ourself to avoid real connections
|
||||
|
@ -323,7 +330,7 @@ namespace libtorrent
|
|||
return std::find_if(
|
||||
m_connections.begin()
|
||||
, m_connections.end()
|
||||
, find_peer_by_id(id, this))
|
||||
, peer_by_id(id))
|
||||
!= m_connections.end();
|
||||
}
|
||||
|
||||
|
@ -360,20 +367,19 @@ namespace libtorrent
|
|||
|
||||
// decrease the trust point of all peers that sent
|
||||
// parts of this piece.
|
||||
// TODO: implement this loop more efficient
|
||||
for (std::vector<peer_connection*>::iterator i = m_connections.begin();
|
||||
i != m_connections.end();
|
||||
for (std::vector<address>::iterator i = downloaders.begin();
|
||||
i != downloaders.end();
|
||||
++i)
|
||||
{
|
||||
if (std::find(downloaders.begin(), downloaders.end(), (*i)->get_socket()->sender())
|
||||
== downloaders.end()) continue;
|
||||
peer_iterator p = m_connections.find(*i);
|
||||
if (p == m_connections.end()) continue;
|
||||
p->second->received_invalid_data();
|
||||
|
||||
(*i)->received_invalid_data();
|
||||
if ((*i)->trust_points() <= -5)
|
||||
if (p->second->trust_points() <= -5)
|
||||
{
|
||||
// we don't trust this peer anymore
|
||||
// ban it.
|
||||
m_policy->ban_peer(*(*i));
|
||||
m_policy->ban_peer(*p->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,22 +407,20 @@ namespace libtorrent
|
|||
|
||||
// increase the trust point of all peers that sent
|
||||
// parts of this piece.
|
||||
// TODO: implement this loop more efficient
|
||||
for (std::vector<peer_connection*>::iterator i = m_connections.begin();
|
||||
i != m_connections.end();
|
||||
for (std::vector<address>::iterator i = downloaders.begin();
|
||||
i != downloaders.end();
|
||||
++i)
|
||||
{
|
||||
if (std::find(downloaders.begin(), downloaders.end(), (*i)->get_socket()->sender())
|
||||
!= downloaders.end())
|
||||
{
|
||||
(*i)->received_valid_data();
|
||||
peer_iterator p = m_connections.find(*i);
|
||||
if (p == m_connections.end()) continue;
|
||||
p->second->received_valid_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_picker.we_have(index);
|
||||
for (std::vector<peer_connection*>::iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||
(*i)->announce_piece(index);
|
||||
for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||
i->second->announce_piece(index);
|
||||
|
||||
// TODO: if we became a seed, disconnect from all other seeds
|
||||
}
|
||||
|
||||
std::string torrent::generate_tracker_request(int port)
|
||||
|
@ -489,7 +493,7 @@ namespace libtorrent
|
|||
|
||||
void torrent::remove_peer(peer_connection* p)
|
||||
{
|
||||
std::vector<peer_connection*>::iterator i = std::find(m_connections.begin(), m_connections.end(), p);
|
||||
peer_iterator i = m_connections.find(p->get_socket()->sender());
|
||||
assert(i != m_connections.end());
|
||||
|
||||
// if the peer_connection was downloading any pieces
|
||||
|
@ -540,18 +544,20 @@ namespace libtorrent
|
|||
, this
|
||||
, s
|
||||
, id));
|
||||
|
||||
if (m_ses.m_upload_rate != -1) c->set_send_quota(0);
|
||||
|
||||
detail::session_impl::connection_map::iterator p =
|
||||
m_ses.m_connections.insert(std::make_pair(s, c)).first;
|
||||
|
||||
// add the newly connected peer to this torrent's peer list
|
||||
assert(std::find(
|
||||
m_connections.begin()
|
||||
, m_connections.end()
|
||||
, boost::get_pointer(p->second))
|
||||
assert(m_connections.find(p->second->get_socket()->sender())
|
||||
== m_connections.end());
|
||||
|
||||
m_connections.push_back(boost::get_pointer(p->second));
|
||||
m_connections.insert(
|
||||
std::make_pair(
|
||||
p->second->get_socket()->sender()
|
||||
, boost::get_pointer(p->second)));
|
||||
|
||||
m_ses.m_selector.monitor_readability(s);
|
||||
m_ses.m_selector.monitor_errors(s);
|
||||
|
@ -561,8 +567,10 @@ namespace libtorrent
|
|||
|
||||
void torrent::attach_peer(peer_connection* p)
|
||||
{
|
||||
assert(std::find(m_connections.begin(), m_connections.end(), p) == m_connections.end());
|
||||
m_connections.push_back(p);
|
||||
assert(m_connections.find(p->get_socket()->sender()) == m_connections.end());
|
||||
|
||||
m_connections.insert(std::make_pair(p->get_socket()->sender(), p));
|
||||
|
||||
detail::session_impl::connection_map::iterator i
|
||||
= m_ses.m_connections.find(p->get_socket());
|
||||
assert(i != m_ses.m_connections.end());
|
||||
|
@ -572,29 +580,25 @@ namespace libtorrent
|
|||
|
||||
void torrent::close_all_connections()
|
||||
{
|
||||
for (detail::session_impl::connection_map::iterator i = m_ses.m_connections.begin();
|
||||
i != m_ses.m_connections.end();)
|
||||
for (peer_iterator i = m_connections.begin();
|
||||
i != m_connections.end();)
|
||||
{
|
||||
if (i->second->associated_torrent() == this)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
std::size_t num_connections = m_connections.size();
|
||||
peer_connection* pc = boost::get_pointer(i->second);
|
||||
#endif
|
||||
assert(std::find(m_connections.begin(), m_connections.end(), pc) != m_connections.end());
|
||||
detail::session_impl::connection_map::iterator j = i;
|
||||
assert(i->second->associated_torrent() == this);
|
||||
|
||||
detail::session_impl::connection_map::iterator j =
|
||||
m_ses.m_connections.find(i->second->get_socket());
|
||||
|
||||
assert(j != m_ses.m_connections.end());
|
||||
|
||||
// in the destructor of the peer_connection
|
||||
// it will remove itself from this torrent
|
||||
// and from the list we're iterating over.
|
||||
// so we need to increment the iterator riht
|
||||
// away.
|
||||
++i;
|
||||
|
||||
m_ses.m_connections.erase(j);
|
||||
assert(m_connections.size() + 1 == num_connections);
|
||||
assert(std::find(m_connections.begin(), m_connections.end(), pc) == m_connections.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(std::find(m_connections.begin(), m_connections.end(), boost::get_pointer(i->second)) == m_connections.end());
|
||||
++i;
|
||||
}
|
||||
}
|
||||
assert(m_connections.empty());
|
||||
}
|
||||
|
||||
|
||||
|
@ -659,11 +663,11 @@ namespace libtorrent
|
|||
m_policy->pulse();
|
||||
}
|
||||
|
||||
for (std::vector<peer_connection*>::iterator i = m_connections.begin();
|
||||
for (peer_iterator i = m_connections.begin();
|
||||
i != m_connections.end();
|
||||
++i)
|
||||
{
|
||||
peer_connection* p = (*i);
|
||||
peer_connection* p = i->second;
|
||||
const stat& s = p->statistics();
|
||||
m_stat += s;
|
||||
p->second_tick();
|
||||
|
|
|
@ -243,15 +243,15 @@ namespace libtorrent
|
|||
ret.dict()["peers"] = entry::list_type();
|
||||
entry::list_type& peer_list = ret.dict()["peers"].list();
|
||||
|
||||
for (torrent::peer_const_iterator i = t->begin();
|
||||
for (torrent::const_peer_iterator i = t->begin();
|
||||
i != t->end();
|
||||
++i)
|
||||
{
|
||||
// we cannot save remote connection
|
||||
// since we don't know their listen port
|
||||
if (!(*i)->is_local()) continue;
|
||||
if (!i->second->is_local()) continue;
|
||||
|
||||
address ip = (*i)->get_socket()->sender();
|
||||
address ip = i->second->get_socket()->sender();
|
||||
entry::dictionary_type peer;
|
||||
peer["ip"] = ip.as_string();
|
||||
peer["port"] = ip.port();
|
||||
|
@ -360,11 +360,11 @@ namespace libtorrent
|
|||
const torrent* t = m_ses->find_torrent(m_info_hash);
|
||||
if (t == 0) return;
|
||||
|
||||
for (std::vector<peer_connection*>::const_iterator i = t->begin();
|
||||
for (torrent::const_peer_iterator i = t->begin();
|
||||
i != t->end();
|
||||
++i)
|
||||
{
|
||||
peer_connection* peer = *i;
|
||||
peer_connection* peer = i->second;
|
||||
|
||||
// peers that hasn't finished the handshake should
|
||||
// not be included in this list
|
||||
|
|
Loading…
Reference in New Issue