diff --git a/docs/manual.html b/docs/manual.html
index 58f5896e5..4ed7e59bc 100755
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -205,7 +205,7 @@ class session: public boost::noncopyable
torrent_handle add_torrent(
const torrent_info& t
- , const std::string& save_path
+ , const boost::filesystem::path& save_path
, const entry& resume_data = entry());
void remove_torrent(const torrent_handle& h);
diff --git a/docs/manual.rst b/docs/manual.rst
index 64038f49c..8c5143a45 100755
--- a/docs/manual.rst
+++ b/docs/manual.rst
@@ -153,7 +153,7 @@ The ``session`` class has the following synopsis::
torrent_handle add_torrent(
const torrent_info& t
- , const std::string& save_path
+ , const boost::filesystem::path& save_path
, const entry& resume_data = entry());
void remove_torrent(const torrent_handle& h);
diff --git a/examples/client_test.cpp b/examples/client_test.cpp
index 459fe0624..7851418e4 100755
--- a/examples/client_test.cpp
+++ b/examples/client_test.cpp
@@ -259,7 +259,7 @@ int main(int argc, char* argv[])
{}
handles.push_back(ses.add_torrent(t, save_path, resume_data));
- handles.back().set_max_connections(5);
+ handles.back().set_max_connections(60);
handles.back().set_max_uploads(-1);
handles.back().set_ratio(1.02);
}
diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp
index 33994daa0..018b5bb58 100755
--- a/include/libtorrent/peer_connection.hpp
+++ b/include/libtorrent/peer_connection.hpp
@@ -96,6 +96,15 @@ namespace libtorrent
return ret;
}
+ template
+ inline unsigned short read_ushort(InIt& start)
+ {
+ unsigned short val = 0;
+ val |= static_cast(*start) << 8; ++start;
+ val |= static_cast(*start); ++start;
+ return val;
+ }
+
// reads an integer to a byte stream
// and converts it from native endianess
template
@@ -113,6 +122,13 @@ namespace libtorrent
write_uint(static_cast(val), start);
}
+ template
+ void write_ushort(unsigned short val, OutIt& start)
+ {
+ *start = static_cast((val >> 8) & 0xff); ++start;
+ *start = static_cast((val) & 0xff); ++start;
+ }
+
template
inline void write_uchar(unsigned char val, OutIt& start)
{
diff --git a/include/libtorrent/peer_id.hpp b/include/libtorrent/peer_id.hpp
index 691b6ff15..b1deb1027 100755
--- a/include/libtorrent/peer_id.hpp
+++ b/include/libtorrent/peer_id.hpp
@@ -46,7 +46,7 @@ namespace libtorrent
enum { number_size = 20 };
public:
- void set_to_all_zero()
+ void clear()
{
std::fill(m_number,m_number+number_size,0);
}
diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp
index 1fa72d566..5aaa41f37 100755
--- a/include/libtorrent/torrent.hpp
+++ b/include/libtorrent/torrent.hpp
@@ -82,7 +82,7 @@ namespace libtorrent
~torrent();
- void abort() { m_abort = true; m_event = event_stopped; }
+ void abort() { m_abort = true; m_event = tracker_request::stopped; }
bool is_aborted() const { return m_abort; }
// is called every second by session.
@@ -172,7 +172,7 @@ namespace libtorrent
// this is a callback called by the tracker_connection class
// when this torrent got a response from its tracker request
- virtual void tracker_response(const entry& e);
+ virtual void tracker_response(std::vector& e, int interval);
virtual void tracker_request_timed_out();
virtual void tracker_request_error(int response_code, const char* str);
@@ -210,7 +210,11 @@ namespace libtorrent
void announce_piece(int index);
void disconnect_all();
- void disconnect_seeds();
+
+ // this is called wheh the torrent has completed
+ // the download. It will post an event, disconnect
+ // all seeds and let the tracker know we're finished.
+ void completed();
piece_picker& picker() { return m_picker; }
@@ -254,14 +258,6 @@ namespace libtorrent
void try_next_tracker();
- enum event_id
- {
- event_started = 0,
- event_stopped,
- event_completed,
- event_none
- };
-
// the size of a request block
// each piece is divided into these
// blocks when requested
@@ -271,7 +267,7 @@ namespace libtorrent
// been aborted.
bool m_abort;
- event_id m_event;
+ tracker_request::event_t m_event;
void parse_response(const entry& e, std::vector& peer_list);
diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp
index 353fe4c45..7f4491544 100755
--- a/src/peer_connection.cpp
+++ b/src/peer_connection.cpp
@@ -705,14 +705,7 @@ namespace libtorrent
if (!was_seed && m_torrent->is_seed())
{
assert(verified);
- if (m_torrent->alerts().should_post(alert::info))
- {
- m_torrent->alerts().post_alert(torrent_finished_alert(
- m_torrent->get_handle()
- , "torrent is finished downloading"));
- }
-
- m_torrent->disconnect_seeds();
+ m_torrent->completed();
}
}
diff --git a/src/torrent.cpp b/src/torrent.cpp
index 4848e7840..c79cf35d5 100755
--- a/src/torrent.cpp
+++ b/src/torrent.cpp
@@ -94,39 +94,6 @@ namespace
return default_block_size;
}
-
- peer_entry extract_peer_info(const entry& e)
- {
- peer_entry ret;
-
- const entry::dictionary_type& info = e.dict();
-
- // extract peer id (if any)
- entry::dictionary_type::const_iterator i = info.find("peer id");
- if (i != info.end())
- {
- if (i->second.string().length() != 20) throw std::runtime_error("invalid response from tracker");
- std::copy(i->second.string().begin(), i->second.string().end(), ret.id.begin());
- }
- else
- {
- // if there's no peer_id, just initialize it to a bunch of zeroes
- std::fill_n(ret.id.begin(), 20, 0);
- }
-
- // extract ip
- i = info.find("ip");
- if (i == info.end()) throw std::runtime_error("invalid response from tracker");
- ret.ip = i->second.string();
-
- // extract port
- i = info.find("port");
- if (i == info.end()) throw std::runtime_error("invalid response from tracker");
- ret.port = i->second.integer();
-
- return ret;
- }
-
/*
struct find_peer_by_id
{
@@ -242,7 +209,7 @@ namespace libtorrent
, const boost::filesystem::path& save_path)
: m_block_size(calculate_block_size(torrent_file))
, m_abort(false)
- , m_event(event_started)
+ , m_event(tracker_request::started)
, m_torrent_file(torrent_file)
, m_storage(m_torrent_file, save_path)
, m_next_request(boost::posix_time::second_clock::local_time())
@@ -268,60 +235,48 @@ namespace libtorrent
if (m_ses.m_abort) m_abort = true;
}
- void torrent::tracker_response(const entry& e)
+ void torrent::tracker_response(
+ std::vector& peer_list
+ , int interval)
{
- std::vector peer_list;
- try
- {
- // parse the response
- parse_response(e, peer_list);
+ m_last_working_tracker
+ = m_torrent_file.prioritize_tracker(m_currently_trying_tracker);
+ m_next_request = boost::posix_time::second_clock::local_time()
+ + boost::posix_time::seconds(m_duration);
+ m_currently_trying_tracker = 0;
- m_last_working_tracker
- = m_torrent_file.prioritize_tracker(m_currently_trying_tracker);
- m_next_request = boost::posix_time::second_clock::local_time()
- + boost::posix_time::seconds(m_duration);
- m_currently_trying_tracker = 0;
+ m_duration = interval;
- // connect to random peers from the list
- std::random_shuffle(peer_list.begin(), peer_list.end());
+ // connect to random peers from the list
+ std::random_shuffle(peer_list.begin(), peer_list.end());
#ifndef NDEBUG
- std::stringstream s;
- s << "interval: " << m_duration << "\n";
- s << "peers:\n";
- for (std::vector::const_iterator i = peer_list.begin();
- i != peer_list.end();
- ++i)
- {
- s << " " << std::setfill(' ') << std::setw(16) << i->ip
- << " " << std::setw(5) << std::dec << i->port << " "
- << i->id << " " << identify_client(i->id) << "\n";
- }
- debug_log(s.str());
+ std::stringstream s;
+ s << "interval: " << m_duration << "\n";
+ s << "peers:\n";
+ for (std::vector::const_iterator i = peer_list.begin();
+ i != peer_list.end();
+ ++i)
+ {
+ s << " " << std::setfill(' ') << std::setw(16) << i->ip
+ << " " << std::setw(5) << std::dec << i->port << " "
+ << i->id << " " << identify_client(i->id) << "\n";
+ }
+ debug_log(s.str());
#endif
- // for each of the peers we got from the tracker
- for (std::vector::iterator i = peer_list.begin();
- i != peer_list.end();
- ++i)
- {
- // don't make connections to ourself
- if (i->id == m_ses.get_peer_id())
- continue;
-
- address a(i->ip, i->port);
-
- m_policy->peer_from_tracker(a, i->id);
- }
-
- }
- catch(type_error& e)
+ // for each of the peers we got from the tracker
+ for (std::vector::iterator i = peer_list.begin();
+ i != peer_list.end();
+ ++i)
{
- tracker_request_error(-1, e.what());
- }
- catch(std::runtime_error& e)
- {
- tracker_request_error(-1, e.what());
+ // don't make connections to ourself
+ if (i->id == m_ses.get_peer_id())
+ continue;
+
+ address a(i->ip, i->port);
+
+ m_policy->peer_from_tracker(a, i->id);
}
m_got_tracker_response = true;
@@ -494,43 +449,11 @@ namespace libtorrent
req.uploaded = m_stat.total_payload_upload();
req.left = bytes_left();
req.listen_port = port;
- if (m_event != event_none)
- {
- const char* event_string[] = {"started", "stopped", "completed"};
- req.event += event_string[m_event];
- m_event = event_none;
- }
+ req.event = m_event;
req.url = m_torrent_file.trackers()[m_currently_trying_tracker].url;
return req;
}
- void torrent::parse_response(const entry& e, std::vector& peer_list)
- {
- entry::dictionary_type::const_iterator i = e.dict().find("failure reason");
- if (i != e.dict().end())
- {
- throw std::runtime_error(i->second.string().c_str());
- }
-
- const entry::dictionary_type& msg = e.dict();
- i = msg.find("interval");
- if (i == msg.end()) throw std::runtime_error("invalid response from tracker (no interval)");
-
- m_duration = i->second.integer();
-
- i = msg.find("peers");
- if (i == msg.end()) throw std::runtime_error("invalid response from tracker (no peers)");
-
- peer_list.clear();
-
- const entry::list_type& l = i->second.list();
- for(entry::list_type::const_iterator i = l.begin(); i != l.end(); ++i)
- {
- peer_entry p = extract_peer_info(*i);
- peer_list.push_back(p);
- }
- }
-
void torrent::remove_peer(peer_connection* p)
{
peer_iterator i = m_connections.find(p->get_socket()->sender());
@@ -626,8 +549,17 @@ namespace libtorrent
}
}
- void torrent::disconnect_seeds()
+ void torrent::completed()
{
+ if (alerts().should_post(alert::info))
+ {
+ alerts().post_alert(torrent_finished_alert(
+ get_handle()
+ , "torrent is finished downloading"));
+ }
+
+
+ // disconnect all seeds
for (peer_iterator i = m_connections.begin();
i != m_connections.end();
++i)
@@ -636,6 +568,11 @@ namespace libtorrent
if (i->second->is_seed())
i->second->disconnect();
}
+
+ // make the next tracker request
+ // be a completed-event
+ m_event = tracker_request::completed;
+ force_tracker_request();
}