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><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><dl class="first docutils">
<dt>main loop (see <a class="reference" href="#session">session</a>)</dt>
<dd><ul class="first last simple">
<li><p class="first">main loop (see <a class="reference" href="#session">session</a>)</p>
<blockquote>
<ul class="simple">
<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>add and remove torrents from the session at run-time</li>
</ul>
</dd>
</dl>
</blockquote>
</li>
<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>
@ -807,7 +806,7 @@ class entry
{
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::list&lt;entry&gt; list_type;
typedef size_type integer_type;

View File

@ -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

View File

@ -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);

View File

@ -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 <memory>
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<char> 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)

View File

@ -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")

View File

@ -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<std::string>(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<std::string>(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

View File

@ -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<std::string>(remote.port));
#endif
assert(i->connection->associated_torrent() == m_torrent);
return;
}

View File

@ -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<torrent_handle> session::get_torrents()