diff --git a/docs/manual.html b/docs/manual.html
index 59fe2e250..5ae8bc817 100755
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -490,15 +490,14 @@ the session, it conta
parse .torrent-files and add them to the session (see bdecode() bencode())
-
-- main loop (see session)
-
+main loop (see session)
+
+
- query the torrent_handles for progress (see torrent_handle)
- query the session for information
- add and remove torrents from the session at run-time
-
-
+
save resume data for all torrent_handles (optional, see
write_resume_data())
@@ -807,7 +806,7 @@ class entry
{
public:
- typedef std::list<std::pair<std::string, entry> > dictionary_type;
+ typedef std::map<std::string, entry> dictionary_type;
typedef std::string string_type;
typedef std::list<entry> list_type;
typedef size_type integer_type;
diff --git a/docs/manual.rst b/docs/manual.rst
index d04e6bddf..5708b3c30 100755
--- a/docs/manual.rst
+++ b/docs/manual.rst
@@ -374,9 +374,11 @@ The basic usage is as follows:
* conststruct a session
* parse .torrent-files and add them to the session (see `bdecode() bencode()`_)
* main loop (see session_)
+
* query the torrent_handles for progress (see torrent_handle_)
* query the session for information
* add and remove torrents from the session at run-time
+
* save resume data for all torrent_handles (optional, see
`write_resume_data()`_)
* destruct session object
diff --git a/examples/client_test.cpp b/examples/client_test.cpp
index bf01cc82e..644ef8ea1 100755
--- a/examples/client_test.cpp
+++ b/examples/client_test.cpp
@@ -405,7 +405,7 @@ int main(int argc, char* argv[])
catch (invalid_encoding&) {}
catch (boost::filesystem::filesystem_error&) {}
- handles.push_back(ses.add_torrent(e, save_path, resume_data, true, 64 * 1024));
+ handles.push_back(ses.add_torrent(e, save_path, resume_data, true, 16 * 1024));
handles.back().set_max_connections(60);
handles.back().set_max_uploads(-1);
// handles.back().set_ratio(1.02f);
diff --git a/include/libtorrent/buffer.hpp b/include/libtorrent/buffer.hpp
index e85fd3163..bc5a02fe3 100644
--- a/include/libtorrent/buffer.hpp
+++ b/include/libtorrent/buffer.hpp
@@ -32,6 +32,9 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef LIBTORRENT_BUFFER_HPP
#define LIBTORRENT_BUFFER_HPP
+//#define TORRENT_BUFFER_DEBUG
+
+#include "libtorrent/invariant_check.hpp"
#include
namespace libtorrent {
@@ -82,6 +85,10 @@ public:
return m_first;
}
+#ifndef NDEBUG
+ void check_invariant() const;
+#endif
+
private:
char* m_first;
char* m_last;
@@ -89,6 +96,10 @@ private:
char* m_read_cursor;
char* m_read_end;
bool m_empty;
+#ifdef TORRENT_BUFFER_DEBUG
+ mutable std::vector m_debug;
+ mutable int m_pending_copy;
+#endif
};
inline buffer::buffer(std::size_t n)
@@ -98,7 +109,11 @@ inline buffer::buffer(std::size_t n)
, m_read_cursor(m_first)
, m_read_end(m_last)
, m_empty(true)
-{}
+{
+#ifdef TORRENT_BUFFER_DEBUG
+ m_pending_copy = 0;
+#endif
+}
inline buffer::~buffer()
{
@@ -107,8 +122,20 @@ inline buffer::~buffer()
inline buffer::interval buffer::allocate(std::size_t n)
{
- assert(m_read_cursor <= m_read_end || m_empty);
+ assert(m_read_cursor <= m_read_end || m_empty);
+ INVARIANT_CHECK;
+
+#ifdef TORRENT_BUFFER_DEBUG
+ if (m_pending_copy)
+ {
+ std::copy(m_write_cursor - m_pending_copy, m_write_cursor
+ , m_debug.end() - m_pending_copy);
+ m_pending_copy = 0;
+ }
+ m_debug.resize(m_debug.size() + n);
+ m_pending_copy = n;
+#endif
if (m_read_cursor < m_write_cursor || m_empty)
{
// ..R***W..
@@ -160,8 +187,20 @@ inline buffer::interval buffer::allocate(std::size_t n)
inline void buffer::insert(char const* first, char const* last)
{
+ INVARIANT_CHECK;
+
std::size_t n = last - first;
+#ifdef TORRENT_BUFFER_DEBUG
+ if (m_pending_copy)
+ {
+ std::copy(m_write_cursor - m_pending_copy, m_write_cursor
+ , m_debug.end() - m_pending_copy);
+ m_pending_copy = 0;
+ }
+ m_debug.insert(m_debug.end(), first, last);
+#endif
+
if (space_left() < n)
{
reserve(capacity() + n);
@@ -182,7 +221,8 @@ inline void buffer::insert(char const* first, char const* last)
if (n == 0) return;
- if (m_write_cursor == m_last) m_write_cursor = m_first;
+ assert(m_write_cursor == m_last);
+ m_write_cursor = m_first;
memcpy(m_write_cursor, first, n);
m_write_cursor += n;
@@ -191,6 +231,9 @@ inline void buffer::insert(char const* first, char const* last)
inline void buffer::erase(std::size_t n)
{
assert(!m_empty);
+
+ INVARIANT_CHECK;
+
#ifndef NDEBUG
int prev_size = size();
#endif
@@ -205,6 +248,10 @@ inline void buffer::erase(std::size_t n)
m_empty = m_read_cursor == m_write_cursor;
assert(prev_size - n == size());
+
+#ifdef TORRENT_BUFFER_DEBUG
+ m_debug.erase(m_debug.begin(), m_debug.begin() + n);
+#endif
}
inline std::size_t buffer::size() const
@@ -246,7 +293,7 @@ inline void buffer::reserve(std::size_t size)
m_write_cursor = buf + (m_write_cursor - m_first);
m_read_cursor = buf + (m_read_cursor - m_first);
- m_read_end = 0;
+ m_read_end = m_write_cursor;
m_first = buf;
m_last = buf + n;
}
@@ -282,11 +329,45 @@ inline void buffer::reserve(std::size_t size)
::operator delete (old);
}
+#ifndef NDEBUG
+inline void buffer::check_invariant() const
+{
+ assert(m_read_end >= m_read_cursor);
+ assert(m_last >= m_read_cursor);
+ assert(m_last >= m_write_cursor);
+ assert(m_last >= m_first);
+ assert(m_first <= m_read_cursor);
+ assert(m_first <= m_write_cursor);
+#ifdef TORRENT_BUFFER_DEBUG
+ int a = m_debug.size();
+ int b = size();
+ (void)a;
+ (void)b;
+ assert(m_debug.size() == size());
+#endif
+}
+#endif
+
inline buffer::interval_type buffer::data() const
{
+ INVARIANT_CHECK;
+
+#ifdef TORRENT_BUFFER_DEBUG
+ if (m_pending_copy)
+ {
+ std::copy(m_write_cursor - m_pending_copy, m_write_cursor
+ , m_debug.end() - m_pending_copy);
+ m_pending_copy = 0;
+ }
+#endif
+
// ...R***W.
if (m_read_cursor < m_write_cursor)
{
+#ifdef TORRENT_BUFFER_DEBUG
+ assert(m_debug.size() == size());
+ assert(std::equal(m_debug.begin(), m_debug.end(), m_read_cursor));
+#endif
return interval_type(
const_interval(m_read_cursor, m_write_cursor)
, const_interval(m_last, m_last)
@@ -297,10 +378,23 @@ inline buffer::interval_type buffer::data() const
{
if (m_read_cursor == m_read_end)
{
+#ifdef TORRENT_BUFFER_DEBUG
+ assert(m_debug.size() == size());
+ assert(std::equal(m_debug.begin(), m_debug.end(), m_first));
+#endif
+
return interval_type(
const_interval(m_first, m_write_cursor)
, const_interval(m_last, m_last));
}
+#ifdef TORRENT_BUFFER_DEBUG
+ assert(m_debug.size() == size());
+ assert(std::equal(m_debug.begin(), m_debug.begin() + (m_read_end
+ - m_read_cursor), m_read_cursor));
+ assert(std::equal(m_debug.begin() + (m_read_end - m_read_cursor), m_debug.end()
+ , m_first));
+#endif
+
assert(m_read_cursor <= m_read_end || m_empty);
return interval_type(
const_interval(m_read_cursor, m_read_end)
diff --git a/src/identify_client.cpp b/src/identify_client.cpp
index fe508c8e6..ecff55074 100755
--- a/src/identify_client.cpp
+++ b/src/identify_client.cpp
@@ -159,6 +159,7 @@ namespace
, map_entry("MT", "Moonlight Torrent")
, map_entry("O", "Osprey Permaseed")
, map_entry("S", "Shadow")
+ , map_entry("SB", "Swiftbit")
, map_entry("SN", "ShareNet")
, map_entry("SS", "SwarmScope")
, map_entry("T", "BitTornado")
diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp
index 86126fa1c..e2745a5ad 100755
--- a/src/peer_connection.cpp
+++ b/src/peer_connection.cpp
@@ -158,7 +158,8 @@ namespace libtorrent
assert(m_torrent != 0);
#ifdef TORRENT_VERBOSE_LOGGING
- m_logger = m_ses.create_log(s->sender().as_string().c_str());
+ m_logger = m_ses.create_log(s->sender().as_string() + "_"
+ + boost::lexical_cast(s->sender().port));
(*m_logger) << "*** OUTGOING CONNECTION\n";
#endif
@@ -273,7 +274,8 @@ namespace libtorrent
std::fill(m_peer_id.begin(), m_peer_id.end(), 0);
#ifdef TORRENT_VERBOSE_LOGGING
- m_logger = m_ses.create_log(s->sender().as_string().c_str());
+ m_logger = m_ses.create_log(s->sender().as_string() + "_"
+ + boost::lexical_cast(s->sender().port));
(*m_logger) << "*** INCOMING CONNECTION\n";
#endif
@@ -475,10 +477,9 @@ namespace libtorrent
i.begin
, i.begin + 8
, 0);
- // indicate that we support the extension protocol
- if (m_ses.extensions_enabled())
- *(i.begin + 7) = 0x01;
+ // indicate that we support the DHT messages
+ *(i.begin + 7) = 0x01;
i.begin += 8;
// info hash
@@ -2128,8 +2129,11 @@ namespace libtorrent
// ok, now we have got enough of the handshake. Is this connection
// attached to a torrent?
- if ((m_recv_buffer[7] & 0x01) && m_ses.extensions_enabled())
- m_supports_extensions = true;
+ // the use of this bit collides with Mainline
+ // the new way of identifying support for the extensions
+ // is in the peer_id
+// if ((m_recv_buffer[7] & 0x01) && m_ses.extensions_enabled())
+// m_supports_extensions = true;
if (m_torrent == 0)
{
@@ -2184,8 +2188,6 @@ namespace libtorrent
}
}
- if (m_supports_extensions) send_extensions();
-
m_state = read_peer_id;
m_packet_size = 20;
m_recv_pos = 0;
@@ -2219,14 +2221,21 @@ namespace libtorrent
s << "\n";
(*m_logger) << s.str();
}
+
+ (*m_logger) << "ext: " << m_peer_id[17] << " " << m_peer_id[18] << " " << m_peer_id[19] << "\n";
#endif
std::copy(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (char*)m_peer_id.begin());
+ if (std::memcmp(&m_peer_id[17], "ext", 3) == 0)
+ m_supports_extensions = true;
+
// disconnect if the peer has the same peer-id as ourself
// since it most likely is ourself then
if (m_peer_id == m_ses.get_peer_id())
throw protocol_error("closing connection to ourself");
+ if (m_supports_extensions) send_extensions();
+
if (!m_active)
{
// check to make sure we don't have another connection with the same
diff --git a/src/policy.cpp b/src/policy.cpp
index e15544aa2..07246c3bf 100755
--- a/src/policy.cpp
+++ b/src/policy.cpp
@@ -942,6 +942,12 @@ namespace libtorrent
// this means we're already connected
// to this peer. don't connect to
// it again.
+
+#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
+ m_torrent->debug_log("already connected to peer: " + remote.as_string() + ":"
+ + boost::lexical_cast(remote.port));
+#endif
+
assert(i->connection->associated_torrent() == m_torrent);
return;
}
diff --git a/src/session.cpp b/src/session.cpp
index 8b4b96dbd..adf10ae7f 100755
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -261,6 +261,8 @@ namespace libtorrent { namespace detail
{
*i = printable[rand() % (sizeof(printable)-1)];
}
+ // this says that we support the extensions
+ std::memcpy(&m_peer_id[17], "ext", 3);
}
bool session_impl::extensions_enabled() const
@@ -908,6 +910,16 @@ namespace libtorrent
boost::mutex::scoped_lock l(m_impl.m_mutex);
std::fill(m_impl.m_extension_enabled, m_impl.m_extension_enabled
+ peer_connection::num_supported_extensions, false);
+
+ static char const printable[]
+ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!~*'()";
+
+ // remove the 'ext' sufix in the peer_id
+ for (unsigned char* i = m_impl.m_peer_id.begin() + 17;
+ i != m_impl.m_peer_id.end(); ++i)
+ {
+ *i = printable[rand() % (sizeof(printable)-1)];
+ }
}
void session::set_ip_filter(ip_filter const& f)
@@ -950,6 +962,9 @@ namespace libtorrent
assert(i < peer_connection::num_supported_extensions);
boost::mutex::scoped_lock l(m_impl.m_mutex);
m_impl.m_extension_enabled[i] = true;
+
+ // this says that we support the extensions
+ std::memcpy(&m_impl.m_peer_id[17], "ext", 3);
}
std::vector session::get_torrents()