downloading |
The torrent is being downloaded. This is the state
most torrents will be in most of the time. The progress
@@ -499,6 +597,9 @@ is a pure seeder. |
next_announce is the time until the torrent will announce itself to the tracker.
total_download and total_upload is the number of bytes downloaded and
uploaded to all peers, accumulated, this session only.
+total_payload_download and total_payload_upload counts the amount of bytes
+send and received this session, but only the actual oayload data (i.e the interesting
+data), these counters ignore any protocol overhead.
pieces is the bitmask that representw which pieces we have (set to true) and
the pieces we don't have.
download_rate and upload_rate are the total rates for all peers for this
@@ -792,12 +893,35 @@ sure not to clash with anybody else. Here are some taken id's:
version of your client. All these numbers must be within the range [0, 9].
to_string() will generate the actual string put in the peer-id, and return it.
+
+
+
The alert class is used to pass messages of events from the libtorrent code
+to the user. It is a base class that specific messages are derived from. This
+is its synopsis:
+
+class alert
+{
+public:
+
+ enum severity_t { debug, info, warning, critital, fatal, none };
+
+ alert(severity_t severity, const std::string& msg);
+
+ virtual ~alert() {}
+
+ const std::string& msg() const;
+ severity_t severity() const;
+
+ virtual std::auto_ptr<alert> clone() const = 0;
+};
+
+
-
+
There are a number of exceptions that can be thrown from different places in libtorrent,
here's a complete list with description.
-
+
This exception is thrown when querying information from a torrent_handle that hasn't
been initialized or that has become invalid.
@@ -808,7 +932,7 @@ struct invalid_handle: std::exception
-
+
This is thrown by session::add_torrent() if the torrent already has been added to
the session.
@@ -819,7 +943,7 @@ struct duplicate_torrent: std::exception
-
+
This is thrown by bdecode() if the input data is not a valid bencoding.
struct invalid_encoding: std::exception
@@ -829,7 +953,7 @@ struct invalid_encoding: std::exception
-
+
This is thrown from the accessors of entry if the data type of the entry doesn't
match the type you want to extract from it.
@@ -840,7 +964,7 @@ struct type_error: std::runtime_error
-
+
This exception is thrown from the constructor of torrent_info if the given bencoded information
doesn't meet the requirements on what information has to be present in a torrent file.
@@ -852,9 +976,9 @@ struct invalid_torrent_file: std::exception
-
+
-
+
This is an example of a program that will take a torrent-file as a parameter and
print information about it to std out:
@@ -918,7 +1042,7 @@ int main(int argc, char* argv[])
-
+
This is a simple client. It doesn't have much output to keep it simple:
#include <iostream>
@@ -971,12 +1095,12 @@ int main(int argc, char* argv[])
-
+
There's a mailing list.
You can usually find me as hydri in #btports @ irc.freenode.net.
-
+
Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003
Contributions by Magnus Jonsson
Thanks to Reimond Retz for bugfixes, suggestions and testing
diff --git a/docs/index.rst b/docs/index.rst
index b9da169f4..41fdde376 100755
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -49,8 +49,7 @@ __ http://home.elp.rr.com/tur/multitracker-spec.txt
Functions that are yet to be implemented:
- * more generous optimistic unchoke
- * better choke/unchoke algorithm
+ * choke/unchoke policy for seed-mode
* fast resume
* number of connections limit
* better handling of peers that send bad data
@@ -139,6 +138,10 @@ The ``session`` class has the following synopsis::
void set_http_settings(const http_settings& settings);
void set_upload_rate_limit(int bytes_per_second);
+
+ std::auto_ptr
pop_alert();
+ void set_severity_level(alert::severity_t s);
+
};
Once it's created, it will spawn the main thread that will do all the work.
@@ -182,6 +185,84 @@ increase the port number by one and try again. If it still fails it will continu
increasing the port number until it succeeds or has failed 9 ports. *This will
change in the future to give more control of the listen-port.*
+The ``pop_alert()`` function is the interface for retrieving alerts, warnings and
+errors from libtorrent. If there hasn't occured any errors (matching your severity
+level) ``pop_alert()`` will return a zero pointer. If there has been some error, it will
+return a pointer to an alert object describing it. You can then use the query the
+alert_ object for information about the error or message. To retrieve any alerts, you
+have to select a severity level using ``set_severity_level()``. It defaults to
+``alert::none``, which means that you don't get any messages at all, ever. You have
+the following levels to select among:
+
++--------------+----------------------------------------------------------+
+| ``none`` | No alert will ever have this severity level, which |
+| | effectively filters all messages. |
+| | |
++--------------+----------------------------------------------------------+
+| ``fatal`` | Fatal errors will have this severity level. Examples can |
+| | be disk full or something else that will make it |
+| | impossible to continue normal execution. |
+| | |
++--------------+----------------------------------------------------------+
+| ``critical`` | Signals errors that requires user interaction. |
+| | |
++--------------+----------------------------------------------------------+
+| ``warning`` | Messages with the warning severity can be a tracker that |
+| | times out or responds with invalid data. It will be |
+| | retried automatically, and the possible next tracker in |
+| | a multitracker sequence will be tried. It does not |
+| | require any user interaction. |
+| | |
++--------------+----------------------------------------------------------+
+| ``info`` | Events that can be considered normal, but still deserves |
+| | an event. This could be a piece hash that fails. |
+| | |
++--------------+----------------------------------------------------------+
+| ``debug`` | This will include alot of debug events that can be used |
+| | both for debugging libtorrent but also when debugging |
+| | other clients that are connected to libtorrent. It will |
+| | report strange behaviors among the connected peers. |
+| | |
++--------------+----------------------------------------------------------+
+
+When setting a severity level, you will receive messages of that severity and all
+messages that are more sever. If you set ``alert::none`` (the default) you will not recieve
+any events at all.
+
+When you get an alert, you can use ``typeid()`` or ``dynamic_cast<>`` to get more detailed
+information on exactly which type it is. i.e. what kind of error it is. You can also use a
+dispatcher mechanism that's available in libtorrent.
+
+TODO: describe the type dispatching mechanism
+
+The currently available alert types are:
+
+ * tracker_alert
+ * hash_failed_alert
+
+You can try a ``dynamic_cast`` to these types to get more message-pecific information. Here
+are their definitions::
+
+ struct tracker_alert: alert
+ {
+ tracker_alert(const torrent_handle& h, const std::string& msg);
+ virtual std::auto_ptr clone() const;
+
+ torrent_handle handle;
+ };
+
+ struct hash_failed_alert: alert
+ {
+ hash_failed_alert(
+ const torrent_handle& h
+ , int index
+ , const std::string& msg);
+
+ virtual std::auto_ptr clone() const;
+
+ torrent_handle handle;
+ int piece_index;
+ };
@@ -471,6 +552,7 @@ It contains the following fields::
invalid_handle,
queued_for_checking,
checking_files,
+ connecting_to_tracker,
downloading,
seeding
};
@@ -478,10 +560,16 @@ It contains the following fields::
state_t state;
float progress;
boost::posix_time::time_duration next_announce;
+
std::size_t total_download;
std::size_t total_upload;
+
+ std::size_t total_payload_download;
+ std::size_t total_payload_upload;
+
float download_rate;
float upload_rate;
+
std::vector pieces;
std::size_t total_done;
};
@@ -490,28 +578,40 @@ It contains the following fields::
torrent's current task. It may be checking files or downloading. The torrent's
current task is in the ``state`` member, it will be one of the following:
-+-----------------------+----------------------------------------------------------+
-|``queued_for_checking``|The torrent is in the queue for being checked. But there |
-| |currently is another torrent that are being checked. |
-| |This torrent will wait for its turn. |
-+-----------------------+----------------------------------------------------------+
-|``checking_files`` |The torrent has not started its download yet, and is |
-| |currently checking existing files. |
-+-----------------------+----------------------------------------------------------+
-|``downloading`` |The torrent is being downloaded. This is the state |
-| |most torrents will be in most of the time. The progress |
-| |meter will tell how much of the files that has been |
-| |downloaded. |
-+-----------------------+----------------------------------------------------------+
-|``seeding`` |In this state the torrent has finished downloading and |
-| |is a pure seeder. |
-+-----------------------+----------------------------------------------------------+
++--------------------------+----------------------------------------------------------+
+|``queued_for_checking`` |The torrent is in the queue for being checked. But there |
+| |currently is another torrent that are being checked. |
+| |This torrent will wait for its turn. |
+| | |
++--------------------------+----------------------------------------------------------+
+|``checking_files`` |The torrent has not started its download yet, and is |
+| |currently checking existing files. |
+| | |
++--------------------------+----------------------------------------------------------+
+|``connecting_to_tracker`` |The torrent has sent a request to the tracker and is |
+| |currently waiting for a response |
+| | |
++--------------------------+----------------------------------------------------------+
+|``downloading`` |The torrent is being downloaded. This is the state |
+| |most torrents will be in most of the time. The progress |
+| |meter will tell how much of the files that has been |
+| |downloaded. |
+| | |
++--------------------------+----------------------------------------------------------+
+|``seeding`` |In this state the torrent has finished downloading and |
+| |is a pure seeder. |
+| | |
++--------------------------+----------------------------------------------------------+
``next_announce`` is the time until the torrent will announce itself to the tracker.
``total_download`` and ``total_upload`` is the number of bytes downloaded and
uploaded to all peers, accumulated, *this session* only.
+``total_payload_download`` and ``total_payload_upload`` counts the amount of bytes
+send and received this session, but only the actual oayload data (i.e the interesting
+data), these counters ignore any protocol overhead.
+
``pieces`` is the bitmask that representw which pieces we have (set to true) and
the pieces we don't have.
@@ -840,6 +940,32 @@ version of your client. All these numbers must be within the range [0, 9].
``to_string()`` will generate the actual string put in the peer-id, and return it.
+alert
+-----
+
+The ``alert`` class is used to pass messages of events from the libtorrent code
+to the user. It is a base class that specific messages are derived from. This
+is its synopsis::
+
+ class alert
+ {
+ public:
+
+ enum severity_t { debug, info, warning, critital, fatal, none };
+
+ alert(severity_t severity, const std::string& msg);
+
+ virtual ~alert() {}
+
+ const std::string& msg() const;
+ severity_t severity() const;
+
+ virtual std::auto_ptr clone() const = 0;
+ };
+
+
+
+
exceptions
----------
diff --git a/examples/client_test.cpp b/examples/client_test.cpp
index bd24f6209..ca8b0a322 100755
--- a/examples/client_test.cpp
+++ b/examples/client_test.cpp
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bencode.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/http_settings.hpp"
+#include "libtorrent/identify_client.hpp"
#ifdef WIN32
@@ -181,15 +182,18 @@ int main(int argc, char* argv[])
// settings.proxy_password = "foobar";
settings.user_agent = "example";
+ std::deque events;
+
try
{
std::vector handles;
- session s(6881);
+ session ses(6881);
// limit upload rate to 100 kB/s
- s.set_upload_rate_limit(100 * 1024);
+ ses.set_upload_rate_limit(100 * 1024);
+ ses.set_http_settings(settings);
+ ses.set_severity_level(alert::info);
- s.set_http_settings(settings);
for (int i = 0; i < argc-1; ++i)
{
try
@@ -199,8 +203,8 @@ int main(int argc, char* argv[])
entry e = bdecode(std::istream_iterator(in), std::istream_iterator());
torrent_info t(e);
t.print(std::cout);
- handles.push_back(s.add_torrent(t, ""));
- handles.back().set_max_uploads(20);
+ handles.push_back(ses.add_torrent(t, ""));
+ handles.back().set_max_uploads(40);
}
catch (std::exception& e)
{
@@ -219,6 +223,15 @@ int main(int argc, char* argv[])
if (c == 'q') break;
}
+ std::auto_ptr a;
+ a = ses.pop_alert();
+ while (a.get())
+ {
+ if (events.size() >= 6) events.pop_front();
+ events.push_front(a->msg());
+ a = ses.pop_alert();
+ }
+
std::stringstream out;
for (std::vector::iterator i = handles.begin();
i != handles.end();
@@ -234,15 +247,17 @@ int main(int argc, char* argv[])
case torrent_status::checking_files:
out << "checking ";
break;
+ case torrent_status::connecting_to_tracker:
+ out << "connecting to tracker ";
+ break;
case torrent_status::downloading:
- out << "dloading ";
+ out << "downloading ";
break;
case torrent_status::seeding:
out << "seeding ";
break;
};
- // calculate download and upload speeds
i->get_peer_info(peers);
float down = s.download_rate;
float up = s.upload_rate;
@@ -334,6 +349,13 @@ int main(int argc, char* argv[])
}
+ for (std::deque::iterator i = events.begin();
+ i != events.end();
+ ++i)
+ {
+ out << *i << "\n";
+ }
+
clear();
set_cursor(0, 0);
std::cout << out.str();
diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp
index 27cde95a0..e9cecf7d3 100755
--- a/include/libtorrent/alert.hpp
+++ b/include/libtorrent/alert.hpp
@@ -51,7 +51,7 @@ namespace libtorrent {
class alert
{
public:
- enum severity_t { info, warning, critital, fatal };
+ enum severity_t { debug, info, warning, critital, fatal, none };
alert(severity_t severity, const std::string& msg)
: m_msg(msg)
@@ -88,6 +88,8 @@ namespace libtorrent {
std::auto_ptr get();
void set_severity(alert::severity_t severity);
+ bool should_post(alert::severity_t severity) const
+ { return severity >= m_severity; }
private:
std::queue m_alerts;
diff --git a/include/libtorrent/fingerprint.hpp b/include/libtorrent/fingerprint.hpp
index 481005a6d..4c6096924 100755
--- a/include/libtorrent/fingerprint.hpp
+++ b/include/libtorrent/fingerprint.hpp
@@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_FINGERPRINT_HPP_INCLUDED
#include
+#include
#include "libtorrent/peer_id.hpp"
diff --git a/include/libtorrent/identify_client.hpp b/include/libtorrent/identify_client.hpp
new file mode 100755
index 000000000..d4a5c60f9
--- /dev/null
+++ b/include/libtorrent/identify_client.hpp
@@ -0,0 +1,45 @@
+/*
+
+Copyright (c) 2003, Arvid Norberg
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the distribution.
+ * Neither the name of the author nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
+#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
+
+#include "libtorrent/peer_id.hpp"
+
+namespace libtorrent
+{
+
+ std::string identify_client(const peer_id& p);
+
+}
+
+#endif // TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp
index f2bd6cafb..637040049 100755
--- a/include/libtorrent/peer_connection.hpp
+++ b/include/libtorrent/peer_connection.hpp
@@ -241,8 +241,8 @@ namespace libtorrent
int share_diff() const
{
return m_free_upload
- + m_statistics.total_download()
- - m_statistics.total_upload();
+ + m_statistics.total_payload_download()
+ - m_statistics.total_payload_upload();
}
#ifndef NDEBUG
diff --git a/include/libtorrent/peer_id.hpp b/include/libtorrent/peer_id.hpp
index 207b18309..608336311 100755
--- a/include/libtorrent/peer_id.hpp
+++ b/include/libtorrent/peer_id.hpp
@@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include
#include
+#include
namespace libtorrent
{
diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp
index a8683642d..8f2080b20 100755
--- a/include/libtorrent/session.hpp
+++ b/include/libtorrent/session.hpp
@@ -171,6 +171,12 @@ namespace libtorrent
// handles delayed alerts
alert_manager m_alerts;
+ // is false by default and set to true when
+ // the first incoming connection is established
+ // this is used to know if the client is behind
+ // NAT or not.
+ bool m_incoming_connection;
+
#ifndef NDEBUG
void assert_invariant();
boost::shared_ptr create_log(std::string name);
@@ -182,8 +188,6 @@ namespace libtorrent
struct http_settings;
- std::string identify_client(const peer_id& p);
-
class session: public boost::noncopyable, detail::eh_initializer
{
public:
@@ -202,7 +206,10 @@ namespace libtorrent
void set_http_settings(const http_settings& s);
void set_upload_rate_limit(int bytes_per_second);
+ // TODO: add a session_status that contain
+
std::auto_ptr pop_alert();
+ void set_severity_level(alert::severity_t s);
private:
diff --git a/include/libtorrent/stat.hpp b/include/libtorrent/stat.hpp
index ae54ca628..c61f1d391 100755
--- a/include/libtorrent/stat.hpp
+++ b/include/libtorrent/stat.hpp
@@ -45,12 +45,12 @@ namespace libtorrent
public:
stat()
- : m_downloaded(0)
- , m_uploaded(0)
+ : m_downloaded_payload(0)
+ , m_uploaded_payload(0)
, m_downloaded_protocol(0)
, m_uploaded_protocol(0)
- , m_total_download(0)
- , m_total_upload(0)
+ , m_total_download_payload(0)
+ , m_total_upload_payload(0)
, m_total_download_protocol(0)
, m_total_upload_protocol(0)
, m_peak_downloaded_per_second(0)
@@ -64,29 +64,29 @@ namespace libtorrent
void operator+=(const stat& s)
{
- m_downloaded += s.m_downloaded;
- m_total_download += s.m_downloaded;
+ m_downloaded_payload += s.m_downloaded_payload;
+ m_total_download_payload += s.m_downloaded_payload;
m_downloaded_protocol += s.m_downloaded_protocol;
m_total_download_protocol += s.m_downloaded_protocol;
- m_uploaded += s.m_uploaded;
- m_total_upload += s.m_uploaded;
+ m_uploaded_payload += s.m_uploaded_payload;
+ m_total_upload_payload += s.m_uploaded_payload;
m_uploaded_protocol += s.m_uploaded_protocol;
m_total_upload_protocol += s.m_uploaded_protocol;
}
void received_bytes(int bytes_payload, int bytes_protocol)
{
- m_downloaded += bytes_payload;
- m_total_download += bytes_payload;
+ m_downloaded_payload += bytes_payload;
+ m_total_download_payload += bytes_payload;
m_downloaded_protocol += bytes_protocol;
m_total_download_protocol += bytes_protocol;
}
void sent_bytes(int bytes_payload, int bytes_protocol)
{
- m_uploaded += bytes_payload;
- m_total_upload += bytes_payload;
+ m_uploaded_payload += bytes_payload;
+ m_total_upload_payload += bytes_payload;
m_uploaded_protocol += bytes_protocol;
m_total_upload_protocol += bytes_protocol;
@@ -102,8 +102,11 @@ namespace libtorrent
float down_peak() const { return m_peak_downloaded_per_second; }
float up_peak() const { return m_peak_uploaded_per_second; }
- unsigned int total_upload() const { return m_total_upload; }
- unsigned int total_download() const { return m_total_download; }
+ unsigned int total_payload_upload() const { return m_total_upload_payload; }
+ unsigned int total_payload_download() const { return m_total_download_payload; }
+
+ unsigned int total_protocol_upload() const { return m_total_upload_protocol; }
+ unsigned int total_protocol_download() const { return m_total_download_protocol; }
private:
@@ -116,8 +119,8 @@ namespace libtorrent
// the accumulators we are adding the downloads/upploads
// to this second. This only counts the actual payload
// and ignores the bytes sent as protocol chatter.
- unsigned int m_downloaded;
- unsigned int m_uploaded;
+ unsigned int m_downloaded_payload;
+ unsigned int m_uploaded_payload;
// the accumulators we are adding the downloads/upploads
// to this second. This only counts the protocol
@@ -127,8 +130,8 @@ namespace libtorrent
// total download/upload counters
// only counting payload data
- unsigned int m_total_download;
- unsigned int m_total_upload;
+ unsigned int m_total_download_payload;
+ unsigned int m_total_upload_payload;
// total download/upload counters
// only counting protocol chatter
diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp
index d6f7c20de..6543f834e 100755
--- a/include/libtorrent/torrent.hpp
+++ b/include/libtorrent/torrent.hpp
@@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/storage.hpp"
#include "libtorrent/url_handler.hpp"
#include "libtorrent/stat.hpp"
+#include "libtorrent/alert.hpp"
namespace libtorrent
{
@@ -58,6 +59,38 @@ namespace libtorrent
struct logger;
#endif
+ struct tracker_alert: alert
+ {
+ tracker_alert(const torrent_handle& h
+ , const std::string& msg)
+ : alert(alert::warning, msg)
+ , handle(h)
+ {}
+
+ virtual std::auto_ptr clone() const
+ { return std::auto_ptr(new tracker_alert(*this)); }
+
+ torrent_handle handle;
+ };
+
+ struct hash_failed_alert: alert
+ {
+ hash_failed_alert(
+ const torrent_handle& h
+ , int index
+ , const std::string& msg)
+ : alert(alert::info, msg)
+ , handle(h)
+ , piece_index(index)
+ {}
+
+ virtual std::auto_ptr clone() const
+ { return std::auto_ptr(new hash_failed_alert(*this)); }
+
+ torrent_handle handle;
+ int piece_index;
+ };
+
namespace detail
{
struct session_impl;
@@ -150,33 +183,9 @@ namespace libtorrent
// this is a callback called by the tracker_connection class
// when this torrent got a response from its tracker request
- void tracker_response(const entry& e);
-
- void tracker_request_timed_out()
- {
-#ifndef NDEBUG
- debug_log("*** tracker timed out");
-#endif
- // TODO: increase the retry_delay for
- // each failed attempt on the same tracker!
- // maybe we should add a counter that keeps
- // track of how many times a specific tracker
- // has timed out?
- try_next_tracker();
- }
-
- // TODO: this function should also take the
- // HTTP-response code as an argument
- // with some codes, we should just consider
- // the tracker as a failure and not retry
- // it anymore
- void tracker_request_error(const char* str)
- {
-#ifndef NDEBUG
- debug_log(std::string("*** tracker error: ") + str);
-#endif
- try_next_tracker();
- }
+ virtual void tracker_response(const entry& e);
+ virtual void tracker_request_timed_out();
+ virtual void tracker_request_error(const char* str);
// generates a request string for sending
// to the tracker
@@ -324,6 +333,11 @@ namespace libtorrent
// std::accumulate(m_have_pieces.begin(),
// m_have_pieces.end(), 0)
int m_num_pieces;
+
+ // is false by default and set to
+ // true when the first tracker reponse
+ // is received
+ bool m_got_tracker_response;
};
}
diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp
index 67a2aeecf..13c48cb7e 100755
--- a/include/libtorrent/torrent_handle.hpp
+++ b/include/libtorrent/torrent_handle.hpp
@@ -63,10 +63,23 @@ namespace libtorrent
struct torrent_status
{
+ torrent_status()
+ : state(queued_for_checking)
+ , progress(0.f)
+ , total_download(0)
+ , total_upload(0)
+ , total_payload_download(0)
+ , total_payload_upload(0)
+ , download_rate(0)
+ , upload_rate(0)
+ , total_done(0)
+ {}
+
enum state_t
{
queued_for_checking,
checking_files,
+ connecting_to_tracker,
downloading,
seeding
};
@@ -76,17 +89,23 @@ namespace libtorrent
boost::posix_time::time_duration next_announce;
// transferred this session!
+ // total, payload plus protocol
std::size_t total_download;
std::size_t total_upload;
+
+ // payload only
+ std::size_t total_payload_download;
+ std::size_t total_payload_upload;
+
+ // current transfer rate
+ // payload plus protocol
float download_rate;
float upload_rate;
+
std::vector pieces;
// the number of bytes of the file we have
std::size_t total_done;
-
- // TODO: add flag that says if there have
- // been any incoming connections
};
struct partial_piece_info
@@ -103,6 +122,8 @@ namespace libtorrent
struct torrent_handle
{
friend class session;
+ friend class torrent;
+
torrent_handle(): m_ses(0) {}
void get_peer_info(std::vector& v) const;
diff --git a/src/alert.cpp b/src/alert.cpp
index 134f7e55c..07dc8afe2 100755
--- a/src/alert.cpp
+++ b/src/alert.cpp
@@ -35,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent {
alert_manager::alert_manager()
- : m_severity(alert::warning)
+ : m_severity(alert::none)
{}
alert_manager::~alert_manager()
diff --git a/src/identify_client.cpp b/src/identify_client.cpp
new file mode 100755
index 000000000..f10824798
--- /dev/null
+++ b/src/identify_client.cpp
@@ -0,0 +1,241 @@
+/*
+
+Copyright (c) 2003, Arvid Norberg
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the distribution.
+ * Neither the name of the author nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include
+#include
+
+#include "libtorrent/identify_client.hpp"
+#include "libtorrent/fingerprint.hpp"
+
+namespace libtorrent
+{
+
+ namespace
+ {
+
+ // takes a peer id and returns a valid boost::optional
+ // object if the peer id matched the azureus style encoding
+ // the returned fingerprint contains information about the
+ // client's id
+ boost::optional parse_az_style(const peer_id& id)
+ {
+ fingerprint ret("..", 0, 0, 0, 0);
+ peer_id::const_iterator i = id.begin();
+
+ if (*i != '-') return boost::optional();
+ ++i;
+
+ for (int j = 0; j < 2; ++j)
+ {
+ if (!std::isprint(*i)) return boost::optional();
+ ret.id[j] = *i;
+ ++i;
+ }
+
+ if (!std::isdigit(*i)) return boost::optional();
+ ret.major_version = *i - '0';
+ ++i;
+
+ if (!std::isdigit(*i)) return boost::optional();
+ ret.minor_version = *i - '0';
+ ++i;
+
+ if (!std::isdigit(*i)) return boost::optional();
+ ret.revision_version = *i - '0';
+ ++i;
+
+ if (!std::isdigit(*i)) return boost::optional();
+ ret.tag_version = *i - '0';
+ ++i;
+
+ if (*i != '-') return boost::optional();
+
+ return boost::optional(ret);
+ }
+
+ // checks if a peer id can possibly contain a shadow-style
+ // identification
+ boost::optional parse_shadow_style(const peer_id& id)
+ {
+ fingerprint ret("..", 0, 0, 0, 0);
+ peer_id::const_iterator i = id.begin();
+
+ if (!std::isprint(*i)) return boost::optional();
+ ret.id[0] = *i;
+ ret.id[1] = 0;
+ ++i;
+
+ if (id[8] == 45)
+ {
+ if (!std::isdigit(*i)) return boost::optional();
+ ret.major_version = *i - '0';
+ ++i;
+
+ if (!std::isdigit(*i)) return boost::optional();
+ ret.minor_version = *i - '0';
+ ++i;
+
+ if (!std::isdigit(*i)) return boost::optional();
+ ret.revision_version = *i - '0';
+ }
+ else if (id[0] == 0)
+ {
+ if (*i > 127) return boost::optional();
+ ret.major_version = *i;
+ ++i;
+
+ if (*i > 127) return boost::optional();
+ ret.minor_version = *i;
+ ++i;
+
+ if (*i > 127) return boost::optional();
+ ret.revision_version = *i;
+ }
+ else
+ return boost::optional();
+
+
+ ret.tag_version = 0;
+ return boost::optional(ret);
+ }
+
+ } // namespace unnamed
+
+
+
+ // TODO: document
+ std::string identify_client(const peer_id& p)
+ {
+ peer_id::const_iterator PID = p.begin();
+ boost::optional f;
+
+
+ // look for azureus style id
+ f = parse_az_style(p);
+ if (f)
+ {
+ std::stringstream identity;
+
+ // azureus
+ if (std::equal(f->id, f->id+2, "AZ"))
+ identity << "Azureus ";
+
+ // BittorrentX
+ else if (std::equal(f->id, f->id+2, "BX"))
+ identity << "BittorrentX ";
+
+ // libtorrent
+ else if (std::equal(f->id, f->id+2, "LT"))
+ identity << "libtorrent ";
+
+ // unknown client
+ else
+ identity << std::string(f->id, f->id+2) << " ";
+
+ identity << (int)f->major_version
+ << "." << (int)f->minor_version
+ << "." << (int)f->revision_version
+ << "." << (int)f->tag_version;
+
+ return identity.str();
+ }
+
+
+ // look for shadow style id
+ f = parse_shadow_style(p);
+ if (f)
+ {
+ std::stringstream identity;
+
+ // Shadow
+ if (std::equal(f->id, f->id+1, "S"))
+ identity << "Shadow ";
+
+ // UPnP
+ else if (std::equal(f->id, f->id+1, "U"))
+ identity << "UPnP ";
+
+ // unknown client
+ else
+ identity << std::string(f->id, f->id+1) << " ";
+
+ identity << (int)f->major_version
+ << "." << (int)f->minor_version
+ << "." << (int)f->revision_version;
+
+ return identity.str();
+ }
+
+ // ----------------------
+ // non standard encodings
+ // ----------------------
+
+
+ if (std::equal(PID + 5, PID + 5 + 8, "Azureus"))
+ {
+ return "Azureus 2.0.3.2";
+ }
+
+ if (std::equal(PID, PID + 11, "DansClient"))
+ {
+ return "XanTorrent";
+ }
+
+ if (std::equal(PID, PID + 7, "btfans"))
+ {
+ return "BitComet";
+ }
+
+ if (std::equal(PID, PID + 8, "turbobt"))
+ {
+ return "TurboBT";
+ }
+
+ if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0\x97"))
+ {
+ return "Experimental 3.2.1b2";
+ }
+
+ if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0\0"))
+ {
+ return "Experimental 3.1";
+ }
+
+ if (std::equal(PID, PID + 12, "\0\0\0\0\0\0\0\0\0\0\0\0"))
+ {
+ return "Generic";
+ }
+
+ return "Unknown";
+ }
+
+}
diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp
index 00331265d..e752ed02a 100755
--- a/src/peer_connection.cpp
+++ b/src/peer_connection.cpp
@@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/peer_connection.hpp"
#include "libtorrent/session.hpp"
+#include "libtorrent/identify_client.hpp"
#if defined(_MSC_VER)
#define for if (false) {} else for
@@ -381,7 +382,6 @@ bool libtorrent::peer_connection::dispatch_message(int received)
{
m_have_piece[index] = true;
- // TODO: maybe this if-statement should be moved into the policy
m_torrent->peer_has(index);
if (!m_torrent->have_piece(index) && !is_interesting())
m_torrent->get_policy().peer_is_interesting(*this);
@@ -859,12 +859,12 @@ void libtorrent::peer_connection::second_tick()
int bias = 0;
if (diff > -2*m_torrent->block_size())
{
- bias = m_statistics.download_rate() * .5;
+ bias = m_statistics.download_rate() / 2;
if (bias < 10*1024) bias = 10*1024;
}
else
{
- bias = -m_statistics.download_rate() * .5;
+ bias = -m_statistics.download_rate() / 2;
}
m_send_quota_limit = m_statistics.download_rate() + bias;
// the maximum send_quota given our download rate from this peer
@@ -1030,6 +1030,16 @@ void libtorrent::peer_connection::receive_data()
if (m_recv_pos < m_packet_size) break;
assert(m_recv_pos == m_packet_size);
+#ifndef NDEBUG
+ {
+ peer_id tmp;
+ std::copy(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (char*)tmp.begin());
+ std::stringstream s;
+ s << "received peer_id: " << tmp << " client: " << identify_client(tmp) << "\n";
+ (*m_logger) << s.str();
+ }
+#endif
+
if (m_active)
{
// verify peer_id
@@ -1052,7 +1062,7 @@ void libtorrent::peer_connection::receive_data()
if (m_torrent->has_peer(m_peer_id))
{
#ifndef NDEBUG
- (*m_logger) << m_socket->sender().as_string() << " duplicate connection, closing\n";
+ (*m_logger) << " duplicate connection, closing\n";
#endif
throw network_error(0);
}
@@ -1066,9 +1076,7 @@ void libtorrent::peer_connection::receive_data()
m_packet_size = 4;
m_recv_pos = 0;
m_recv_buffer.resize(4);
-#ifndef NDEBUG
- (*m_logger) << m_socket->sender().as_string() << " received peer_id\n";
-#endif
+
break;
}
@@ -1234,7 +1242,7 @@ void libtorrent::peer_connection::send_data()
, amount_to_send);
#ifndef NDEBUG
- (*m_logger) << m_socket->sender().as_string() << " ==> SENT [ length: " << sent << " ]\n";
+// (*m_logger) << m_socket->sender().as_string() << " ==> SENT [ length: " << sent << " ]\n";
#endif
if (sent > 0)
diff --git a/src/policy.cpp b/src/policy.cpp
index 410300122..22179b79f 100755
--- a/src/policy.cpp
+++ b/src/policy.cpp
@@ -593,8 +593,8 @@ namespace libtorrent
assert(i != m_peers.end());
i->connected = boost::posix_time::second_clock::local_time();
- i->prev_amount_download += c.statistics().total_download();
- i->prev_amount_upload += c.statistics().total_upload();
+ i->prev_amount_download += c.statistics().total_payload_download();
+ i->prev_amount_upload += c.statistics().total_payload_upload();
if (!i->connection->is_choked() && !m_torrent->is_aborted())
{
--m_num_unchoked;
@@ -651,7 +651,7 @@ namespace libtorrent
int policy::peer::total_download() const
{
if (connection != 0)
- return connection->statistics().total_download()
+ return connection->statistics().total_payload_download()
+ prev_amount_download;
else
return prev_amount_download;
@@ -660,7 +660,7 @@ namespace libtorrent
int policy::peer::total_upload() const
{
if (connection != 0)
- return connection->statistics().total_upload()
+ return connection->statistics().total_payload_upload()
+ prev_amount_upload;
else
return prev_amount_upload;
diff --git a/src/session.cpp b/src/session.cpp
index 1db426dd5..1eef81198 100755
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -337,6 +337,7 @@ namespace libtorrent
, m_tracker_manager(m_settings)
, m_listen_port(listen_port)
, m_upload_rate(-1)
+ , m_incoming_connection(false)
{
// ---- generate a peer id ----
@@ -462,6 +463,7 @@ namespace libtorrent
if (s)
{
// we got a connection request!
+ m_incoming_connection = true;
#ifndef NDEBUG
(*m_logger) << s->sender().as_string() << " <== INCOMING CONNECTION\n";
#endif
@@ -864,203 +866,15 @@ namespace libtorrent
std::auto_ptr session::pop_alert()
{
- return m_impl.m_alerts.get();
+ if (m_impl.m_alerts.pending())
+ return m_impl.m_alerts.get();
+ else
+ return std::auto_ptr(0);
}
- namespace
+ void session::set_severity_level(alert::severity_t s)
{
-
- // takes a peer id and returns a valid boost::optional
- // object if the peer id matched the azureus style encoding
- // the returned fingerprint contains information about the
- // client's id
- boost::optional parse_az_style(const peer_id& id)
- {
- fingerprint ret("..", 0, 0, 0, 0);
- peer_id::const_iterator i = id.begin();
-
- if (*i != '-') return boost::optional();
- ++i;
-
- for (int j = 0; j < 2; ++j)
- {
- if (!std::isprint(*i)) return boost::optional();
- ret.id[j] = *i;
- ++i;
- }
-
- if (!std::isdigit(*i)) return boost::optional();
- ret.major_version = *i - '0';
- ++i;
-
- if (!std::isdigit(*i)) return boost::optional();
- ret.minor_version = *i - '0';
- ++i;
-
- if (!std::isdigit(*i)) return boost::optional();
- ret.revision_version = *i - '0';
- ++i;
-
- if (!std::isdigit(*i)) return boost::optional();
- ret.tag_version = *i - '0';
- ++i;
-
- if (*i != '-') return boost::optional();
-
- return boost::optional(ret);
- }
-
- // checks if a peer id can possibly contain a shadow-style
- // identification
- boost::optional parse_shadow_style(const peer_id& id)
- {
- fingerprint ret("..", 0, 0, 0, 0);
- peer_id::const_iterator i = id.begin();
-
- if (!std::isprint(*i)) return boost::optional();
- ret.id[0] = *i;
- ret.id[1] = 0;
- ++i;
-
- if (id[8] == 45)
- {
- if (!std::isdigit(*i)) return boost::optional();
- ret.major_version = *i - '0';
- ++i;
-
- if (!std::isdigit(*i)) return boost::optional();
- ret.minor_version = *i - '0';
- ++i;
-
- if (!std::isdigit(*i)) return boost::optional();
- ret.revision_version = *i - '0';
- }
- else if (id[0] == 0)
- {
- if (*i > 127) return boost::optional();
- ret.major_version = *i;
- ++i;
-
- if (*i > 127) return boost::optional();
- ret.minor_version = *i;
- ++i;
-
- if (*i > 127) return boost::optional();
- ret.revision_version = *i;
- }
- else
- return boost::optional();
-
-
- ret.tag_version = 0;
- return boost::optional(ret);
- }
-
- } // namespace unnamed
-
-
-
- // TODO: document
- std::string identify_client(const peer_id& p)
- {
- peer_id::const_iterator PID = p.begin();
- boost::optional f;
-
-
- // look for azureus style id
- f = parse_az_style(p);
- if (f)
- {
- std::stringstream identity;
-
- // azureus
- if (std::equal(f->id, f->id+2, "AZ"))
- identity << "Azureus ";
-
- // BittorrentX
- else if (std::equal(f->id, f->id+2, "BX"))
- identity << "BittorrentX ";
-
- // libtorrent
- else if (std::equal(f->id, f->id+2, "LT"))
- identity << "libtorrent ";
-
- // unknown client
- else
- identity << std::string(f->id, f->id+2) << " ";
-
- identity << (int)f->major_version
- << "." << (int)f->minor_version
- << "." << (int)f->revision_version
- << "." << (int)f->tag_version;
-
- return identity.str();
- }
-
-
- // look for shadow style id
- f = parse_shadow_style(p);
- if (f)
- {
- std::stringstream identity;
-
- // Shadow
- if (std::equal(f->id, f->id+1, "S"))
- identity << "Shadow ";
-
- // UPnP
- else if (std::equal(f->id, f->id+1, "U"))
- identity << "UPnP ";
-
- // unknown client
- else
- identity << std::string(f->id, f->id+1) << " ";
-
- identity << (int)f->major_version
- << "." << (int)f->minor_version
- << "." << (int)f->revision_version;
-
- return identity.str();
- }
-
- // ----------------------
- // non standard encodings
- // ----------------------
-
-
- if (std::equal(PID + 5, PID + 5 + 8, "Azureus"))
- {
- return "Azureus 2.0.3.2";
- }
-
-
- if (std::equal(PID, PID + 11, "DansClient"))
- {
- return "XanTorrent";
- }
-
- if (std::equal(PID, PID + 7, "btfans"))
- {
- return "BitComet";
- }
-
- if (std::equal(PID, PID + 8, "turbobt"))
- {
- return "TurboBT";
- }
-
-
- if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\x97"))
- {
- return "Experimental 3.2.1b2";
- }
-
- if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0"))
- {
- return "Experimental 3.1";
- }
-
- return "Generic";
- }
+ m_impl.m_alerts.set_severity(s);
+ }
}
diff --git a/src/stat.cpp b/src/stat.cpp
index fe0ea9fa5..1bb06b098 100755
--- a/src/stat.cpp
+++ b/src/stat.cpp
@@ -51,10 +51,10 @@ void libtorrent::stat::second_tick()
m_upload_per_second_history+history-1,
m_upload_per_second_history+1);
- m_download_per_second_history[0] = m_downloaded + m_downloaded_protocol;
- m_upload_per_second_history[0] = m_uploaded + m_uploaded_protocol;
- m_downloaded = 0;
- m_uploaded = 0;
+ m_download_per_second_history[0] = m_downloaded_payload + m_downloaded_protocol;
+ m_upload_per_second_history[0] = m_uploaded_payload + m_uploaded_protocol;
+ m_downloaded_payload = 0;
+ m_uploaded_payload = 0;
m_downloaded_protocol = 0;
m_uploaded_protocol = 0;
diff --git a/src/torrent.cpp b/src/torrent.cpp
index 4aed92a2a..88864fe6f 100755
--- a/src/torrent.cpp
+++ b/src/torrent.cpp
@@ -51,6 +51,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/entry.hpp"
#include "libtorrent/peer.hpp"
#include "libtorrent/peer_id.hpp"
+#include "libtorrent/alert.hpp"
+#include "libtorrent/identify_client.hpp"
#if defined(_MSC_VER) && _MSC_VER < 1300
namespace std
@@ -177,6 +179,7 @@ namespace libtorrent
, m_time_scaler(0)
, m_priority(.5)
, m_num_pieces(0)
+ , m_got_tracker_response(false)
{
assert(torrent_file.begin_files() != torrent_file.end_files());
m_have_pieces.resize(torrent_file.num_pieces(), false);
@@ -250,6 +253,7 @@ namespace libtorrent
tracker_request_error(e.what());
}
+ m_got_tracker_response = true;
}
bool torrent::has_peer(const peer_id& id) const
@@ -282,6 +286,13 @@ namespace libtorrent
void torrent::piece_failed(int index)
{
+ if (m_ses.m_alerts.should_post(alert::info))
+ {
+ std::stringstream s;
+ s << "hash for piece " << index << " failed";
+ torrent_handle self(&m_ses, 0, m_torrent_file.info_hash());
+ m_ses.m_alerts.post_alert(hash_failed_alert(self, index, s.str()));
+ }
std::vector downloaders;
m_picker.get_downloaders(downloaders, index);
@@ -365,10 +376,10 @@ namespace libtorrent
request += boost::lexical_cast(port);
request += "&uploaded=";
- request += boost::lexical_cast(m_stat.total_upload());
+ request += boost::lexical_cast(m_stat.total_payload_upload());
request += "&downloaded=";
- request += boost::lexical_cast(m_stat.total_download());
+ request += boost::lexical_cast(m_stat.total_payload_download());
request += "&left=";
request += boost::lexical_cast(bytes_left());
@@ -450,7 +461,7 @@ namespace libtorrent
m_connections.erase(i);
#ifndef NDEBUG
- m_picker.integrity_check(this);
+// m_picker.integrity_check(this);
#endif
}
@@ -628,10 +639,20 @@ namespace libtorrent
- blocks_per_piece;
}
- st.total_download = m_stat.total_download();
- st.total_upload = m_stat.total_upload();
+ // payload transfer
+ st.total_payload_download = m_stat.total_payload_download();
+ st.total_payload_upload = m_stat.total_payload_upload();
+
+ // total transfer
+ st.total_download = m_stat.total_payload_download()
+ + m_stat.total_protocol_download();
+ st.total_upload = m_stat.total_payload_upload()
+ + m_stat.total_protocol_upload();
+
+ // transfer rate
st.download_rate = m_stat.download_rate();
st.upload_rate = m_stat.upload_rate();
+
st.progress = (blocks_we_have + unverified_blocks)
/ static_cast(total_blocks);
@@ -644,7 +665,9 @@ namespace libtorrent
st.total_done = (blocks_we_have + unverified_blocks) * m_block_size;
st.pieces = m_have_pieces;
- if (m_num_pieces == p.size())
+ if (m_got_tracker_response == false)
+ st.state = torrent_status::connecting_to_tracker;
+ else if (m_num_pieces == p.size())
st.state = torrent_status::seeding;
else
st.state = torrent_status::downloading;
@@ -652,6 +675,53 @@ namespace libtorrent
return st;
}
+ void torrent::tracker_request_timed_out()
+ {
+#ifndef NDEBUG
+ debug_log("*** tracker timed out");
+#endif
+ if (m_ses.m_alerts.should_post(alert::warning))
+ {
+ std::stringstream s;
+ s << "tracker: \""
+ << m_torrent_file.trackers()[m_currently_trying_tracker].url
+ << "\" timed out";
+ torrent_handle self(&m_ses, 0, m_torrent_file.info_hash());
+ m_ses.m_alerts.post_alert(tracker_alert( self, s.str()));
+ }
+ // TODO: increase the retry_delay for
+ // each failed attempt on the same tracker!
+ // maybe we should add a counter that keeps
+ // track of how many times a specific tracker
+ // has timed out?
+ try_next_tracker();
+ }
+
+ // TODO: this function should also take the
+ // HTTP-response code as an argument
+ // with some codes, we should just consider
+ // the tracker as a failure and not retry
+ // it anymore
+ void torrent::tracker_request_error(const char* str)
+ {
+#ifndef NDEBUG
+ debug_log(std::string("*** tracker error: ") + str);
+#endif
+ if (m_ses.m_alerts.should_post(alert::warning))
+ {
+ std::stringstream s;
+ s << "tracker: \""
+ << m_torrent_file.trackers()[m_currently_trying_tracker].url
+ << "\" " << str;
+ torrent_handle self(&m_ses, 0, m_torrent_file.info_hash());
+ m_ses.m_alerts.post_alert(tracker_alert(self, s.str()));
+ }
+
+
+ try_next_tracker();
+ }
+
+
#ifndef NDEBUG
void torrent::debug_log(const std::string& line)
{
diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp
index 210a94ea1..0f8086ba3 100755
--- a/src/torrent_handle.cpp
+++ b/src/torrent_handle.cpp
@@ -68,7 +68,6 @@ namespace libtorrent
{
if (m_ses == 0) throw invalid_handle();
- assert(m_chk != 0);
{
boost::mutex::scoped_lock l(m_ses->m_mutex);
torrent* t = m_ses->find_torrent(m_info_hash);
@@ -80,6 +79,7 @@ namespace libtorrent
}
+ if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
@@ -97,13 +97,13 @@ namespace libtorrent
{
if (m_ses == 0) throw invalid_handle();
- assert(m_chk != 0);
{
boost::mutex::scoped_lock l(m_ses->m_mutex);
torrent* t = m_ses->find_torrent(m_info_hash);
if (t != 0) return t->status();
}
+ if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
@@ -111,10 +111,7 @@ namespace libtorrent
if (d != 0)
{
torrent_status st;
- st.total_download = 0;
- st.total_upload = 0;
- st.download_rate = 0.f;
- st.upload_rate = 0.f;
+
if (d == &m_chk->m_torrents.front())
st.state = torrent_status::checking_files;
else
@@ -123,7 +120,6 @@ namespace libtorrent
st.next_announce = boost::posix_time::time_duration();
st.pieces.clear();
st.pieces.resize(d->torrent_ptr->torrent_file().num_pieces(), false);
- st.total_done = 0;
return st;
}
}
@@ -141,6 +137,7 @@ namespace libtorrent
if (t != 0) return t->torrent_file();
}
+ if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
@@ -160,6 +157,7 @@ namespace libtorrent
if (t != 0) return true;
}
+ if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
@@ -190,6 +188,7 @@ namespace libtorrent
}
}
+ if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
@@ -207,7 +206,6 @@ namespace libtorrent
{
v.clear();
if (m_ses == 0) throw invalid_handle();
- assert(m_chk != 0);
boost::mutex::scoped_lock l(m_ses->m_mutex);
@@ -235,8 +233,8 @@ namespace libtorrent
// TODO: add the prev_amount_downloaded and prev_amount_uploaded
// from the peer list in the policy
- p.total_download = statistics.total_download();
- p.total_upload = statistics.total_upload();
+ p.total_download = statistics.total_payload_download();
+ p.total_upload = statistics.total_payload_upload();
p.upload_limit = peer->send_quota();
p.upload_ceiling = peer->send_quota_limit();
@@ -274,7 +272,6 @@ namespace libtorrent
queue.clear();
if (m_ses == 0) throw invalid_handle();
- assert(m_chk != 0);
boost::mutex::scoped_lock l(m_ses->m_mutex);
torrent* t = m_ses->find_torrent(m_info_hash);