Changed the way libtorrent find out if a peer supports its extensions to make it compatible with Mainline beta.

This commit is contained in:
Arvid Norberg 2005-09-18 10:18:23 +00:00
parent 5a1e064783
commit 82c0ca5675
8 changed files with 146 additions and 20 deletions

View File

@ -490,15 +490,14 @@ the <tt class="docutils literal"><span class="pre">session</span></tt>, it conta
</li> </li>
<li><p class="first">parse .torrent-files and add them to the session (see <a class="reference" href="#bdecode-bencode">bdecode() bencode()</a>)</p> <li><p class="first">parse .torrent-files and add them to the session (see <a class="reference" href="#bdecode-bencode">bdecode() bencode()</a>)</p>
</li> </li>
<li><dl class="first docutils"> <li><p class="first">main loop (see <a class="reference" href="#session">session</a>)</p>
<dt>main loop (see <a class="reference" href="#session">session</a>)</dt> <blockquote>
<dd><ul class="first last simple"> <ul class="simple">
<li>query the torrent_handles for progress (see <a class="reference" href="#torrent-handle">torrent_handle</a>)</li> <li>query the torrent_handles for progress (see <a class="reference" href="#torrent-handle">torrent_handle</a>)</li>
<li>query the session for information</li> <li>query the session for information</li>
<li>add and remove torrents from the session at run-time</li> <li>add and remove torrents from the session at run-time</li>
</ul> </ul>
</dd> </blockquote>
</dl>
</li> </li>
<li><p class="first">save resume data for all torrent_handles (optional, see <li><p class="first">save resume data for all torrent_handles (optional, see
<a class="reference" href="#write-resume-data">write_resume_data()</a>)</p> <a class="reference" href="#write-resume-data">write_resume_data()</a>)</p>
@ -807,7 +806,7 @@ class entry
{ {
public: public:
typedef std::list&lt;std::pair&lt;std::string, entry&gt; &gt; dictionary_type; typedef std::map&lt;std::string, entry&gt; dictionary_type;
typedef std::string string_type; typedef std::string string_type;
typedef std::list&lt;entry&gt; list_type; typedef std::list&lt;entry&gt; list_type;
typedef size_type integer_type; typedef size_type integer_type;

View File

@ -374,9 +374,11 @@ The basic usage is as follows:
* conststruct a session * conststruct a session
* parse .torrent-files and add them to the session (see `bdecode() bencode()`_) * 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 torrent_handles for progress (see torrent_handle_)
* query the session for information * query the session for information
* add and remove torrents from the session at run-time * add and remove torrents from the session at run-time
* save resume data for all torrent_handles (optional, see * save resume data for all torrent_handles (optional, see
`write_resume_data()`_) `write_resume_data()`_)
* destruct session object * destruct session object

View File

@ -405,7 +405,7 @@ int main(int argc, char* argv[])
catch (invalid_encoding&) {} catch (invalid_encoding&) {}
catch (boost::filesystem::filesystem_error&) {} 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_connections(60);
handles.back().set_max_uploads(-1); handles.back().set_max_uploads(-1);
// handles.back().set_ratio(1.02f); // handles.back().set_ratio(1.02f);

View File

@ -32,6 +32,9 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef LIBTORRENT_BUFFER_HPP #ifndef LIBTORRENT_BUFFER_HPP
#define LIBTORRENT_BUFFER_HPP #define LIBTORRENT_BUFFER_HPP
//#define TORRENT_BUFFER_DEBUG
#include "libtorrent/invariant_check.hpp"
#include <memory> #include <memory>
namespace libtorrent { namespace libtorrent {
@ -82,6 +85,10 @@ public:
return m_first; return m_first;
} }
#ifndef NDEBUG
void check_invariant() const;
#endif
private: private:
char* m_first; char* m_first;
char* m_last; char* m_last;
@ -89,6 +96,10 @@ private:
char* m_read_cursor; char* m_read_cursor;
char* m_read_end; char* m_read_end;
bool m_empty; bool m_empty;
#ifdef TORRENT_BUFFER_DEBUG
mutable std::vector<char> m_debug;
mutable int m_pending_copy;
#endif
}; };
inline buffer::buffer(std::size_t n) 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_cursor(m_first)
, m_read_end(m_last) , m_read_end(m_last)
, m_empty(true) , m_empty(true)
{} {
#ifdef TORRENT_BUFFER_DEBUG
m_pending_copy = 0;
#endif
}
inline buffer::~buffer() inline buffer::~buffer()
{ {
@ -109,6 +124,18 @@ 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) if (m_read_cursor < m_write_cursor || m_empty)
{ {
// ..R***W.. // ..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) inline void buffer::insert(char const* first, char const* last)
{ {
INVARIANT_CHECK;
std::size_t n = last - first; 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) if (space_left() < n)
{ {
reserve(capacity() + n); reserve(capacity() + n);
@ -182,7 +221,8 @@ inline void buffer::insert(char const* first, char const* last)
if (n == 0) return; 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); memcpy(m_write_cursor, first, n);
m_write_cursor += 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) inline void buffer::erase(std::size_t n)
{ {
assert(!m_empty); assert(!m_empty);
INVARIANT_CHECK;
#ifndef NDEBUG #ifndef NDEBUG
int prev_size = size(); int prev_size = size();
#endif #endif
@ -205,6 +248,10 @@ inline void buffer::erase(std::size_t n)
m_empty = m_read_cursor == m_write_cursor; m_empty = m_read_cursor == m_write_cursor;
assert(prev_size - n == size()); 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 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_write_cursor = buf + (m_write_cursor - m_first);
m_read_cursor = buf + (m_read_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_first = buf;
m_last = buf + n; m_last = buf + n;
} }
@ -282,11 +329,45 @@ inline void buffer::reserve(std::size_t size)
::operator delete (old); ::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 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. // ...R***W.
if (m_read_cursor < m_write_cursor) 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( return interval_type(
const_interval(m_read_cursor, m_write_cursor) const_interval(m_read_cursor, m_write_cursor)
, const_interval(m_last, m_last) , const_interval(m_last, m_last)
@ -297,10 +378,23 @@ inline buffer::interval_type buffer::data() const
{ {
if (m_read_cursor == m_read_end) 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( return interval_type(
const_interval(m_first, m_write_cursor) const_interval(m_first, m_write_cursor)
, const_interval(m_last, m_last)); , 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); assert(m_read_cursor <= m_read_end || m_empty);
return interval_type( return interval_type(
const_interval(m_read_cursor, m_read_end) const_interval(m_read_cursor, m_read_end)

View File

@ -159,6 +159,7 @@ namespace
, map_entry("MT", "Moonlight Torrent") , map_entry("MT", "Moonlight Torrent")
, map_entry("O", "Osprey Permaseed") , map_entry("O", "Osprey Permaseed")
, map_entry("S", "Shadow") , map_entry("S", "Shadow")
, map_entry("SB", "Swiftbit")
, map_entry("SN", "ShareNet") , map_entry("SN", "ShareNet")
, map_entry("SS", "SwarmScope") , map_entry("SS", "SwarmScope")
, map_entry("T", "BitTornado") , map_entry("T", "BitTornado")

View File

@ -158,7 +158,8 @@ namespace libtorrent
assert(m_torrent != 0); assert(m_torrent != 0);
#ifdef TORRENT_VERBOSE_LOGGING #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<std::string>(s->sender().port));
(*m_logger) << "*** OUTGOING CONNECTION\n"; (*m_logger) << "*** OUTGOING CONNECTION\n";
#endif #endif
@ -273,7 +274,8 @@ namespace libtorrent
std::fill(m_peer_id.begin(), m_peer_id.end(), 0); std::fill(m_peer_id.begin(), m_peer_id.end(), 0);
#ifdef TORRENT_VERBOSE_LOGGING #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<std::string>(s->sender().port));
(*m_logger) << "*** INCOMING CONNECTION\n"; (*m_logger) << "*** INCOMING CONNECTION\n";
#endif #endif
@ -475,9 +477,8 @@ namespace libtorrent
i.begin i.begin
, i.begin + 8 , i.begin + 8
, 0); , 0);
// indicate that we support the extension protocol
if (m_ses.extensions_enabled()) // indicate that we support the DHT messages
*(i.begin + 7) = 0x01; *(i.begin + 7) = 0x01;
i.begin += 8; i.begin += 8;
@ -2128,8 +2129,11 @@ namespace libtorrent
// ok, now we have got enough of the handshake. Is this connection // ok, now we have got enough of the handshake. Is this connection
// attached to a torrent? // attached to a torrent?
if ((m_recv_buffer[7] & 0x01) && m_ses.extensions_enabled()) // the use of this bit collides with Mainline
m_supports_extensions = true; // 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) if (m_torrent == 0)
{ {
@ -2184,8 +2188,6 @@ namespace libtorrent
} }
} }
if (m_supports_extensions) send_extensions();
m_state = read_peer_id; m_state = read_peer_id;
m_packet_size = 20; m_packet_size = 20;
m_recv_pos = 0; m_recv_pos = 0;
@ -2219,14 +2221,21 @@ namespace libtorrent
s << "\n"; s << "\n";
(*m_logger) << s.str(); (*m_logger) << s.str();
} }
(*m_logger) << "ext: " << m_peer_id[17] << " " << m_peer_id[18] << " " << m_peer_id[19] << "\n";
#endif #endif
std::copy(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (char*)m_peer_id.begin()); 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 // disconnect if the peer has the same peer-id as ourself
// since it most likely is ourself then // since it most likely is ourself then
if (m_peer_id == m_ses.get_peer_id()) if (m_peer_id == m_ses.get_peer_id())
throw protocol_error("closing connection to ourself"); throw protocol_error("closing connection to ourself");
if (m_supports_extensions) send_extensions();
if (!m_active) if (!m_active)
{ {
// check to make sure we don't have another connection with the same // check to make sure we don't have another connection with the same

View File

@ -942,6 +942,12 @@ namespace libtorrent
// this means we're already connected // this means we're already connected
// to this peer. don't connect to // to this peer. don't connect to
// it again. // it again.
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
m_torrent->debug_log("already connected to peer: " + remote.as_string() + ":"
+ boost::lexical_cast<std::string>(remote.port));
#endif
assert(i->connection->associated_torrent() == m_torrent); assert(i->connection->associated_torrent() == m_torrent);
return; return;
} }

View File

@ -261,6 +261,8 @@ namespace libtorrent { namespace detail
{ {
*i = printable[rand() % (sizeof(printable)-1)]; *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 bool session_impl::extensions_enabled() const
@ -908,6 +910,16 @@ namespace libtorrent
boost::mutex::scoped_lock l(m_impl.m_mutex); boost::mutex::scoped_lock l(m_impl.m_mutex);
std::fill(m_impl.m_extension_enabled, m_impl.m_extension_enabled std::fill(m_impl.m_extension_enabled, m_impl.m_extension_enabled
+ peer_connection::num_supported_extensions, false); + 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) void session::set_ip_filter(ip_filter const& f)
@ -950,6 +962,9 @@ namespace libtorrent
assert(i < peer_connection::num_supported_extensions); assert(i < peer_connection::num_supported_extensions);
boost::mutex::scoped_lock l(m_impl.m_mutex); boost::mutex::scoped_lock l(m_impl.m_mutex);
m_impl.m_extension_enabled[i] = true; 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<torrent_handle> session::get_torrents() std::vector<torrent_handle> session::get_torrents()