lt tracker request url ampersand fix, endpoint to string conversion fix. 1602

This commit is contained in:
Marcos Pinto 2007-09-23 23:45:41 +00:00
parent b209d268f2
commit 44240b194e
6 changed files with 172 additions and 415 deletions

View File

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2003 - 2005, Arvid Norberg, Daniel Wallin Copyright (c) 2007, Arvid Norberg
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -32,9 +32,8 @@ 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 <memory> #include <memory>
#include <cstring>
#include "libtorrent/invariant_check.hpp" #include "libtorrent/invariant_check.hpp"
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
@ -87,366 +86,113 @@ public:
char const* end; char const* end;
}; };
typedef std::pair<const_interval, const_interval> interval_type; buffer(std::size_t n = 0)
: m_begin(0)
buffer(std::size_t n = 0); , m_end(0)
~buffer(); , m_last(0)
interval allocate(std::size_t n);
void insert(char const* first, char const* last);
void erase(std::size_t n);
std::size_t size() const;
std::size_t capacity() const;
void reserve(std::size_t n);
interval_type data() const;
bool empty() const;
std::size_t space_left() const;
char const* raw_data() const
{ {
return m_first; if (n) resize(n);
} }
#ifndef NDEBUG buffer(buffer const& b)
void check_invariant() const; : m_begin(0)
#endif , m_end(0)
, m_last(0)
private:
char* m_first;
char* m_last;
char* m_write_cursor;
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)
: m_first((char*)::operator new(n))
, m_last(m_first + n)
, m_write_cursor(m_first)
, 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()
{
::operator delete (m_first);
}
inline buffer::interval buffer::allocate(std::size_t n)
{
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 if (b.size() == 0) return;
, m_debug.end() - m_pending_copy); resize(b.size());
m_pending_copy = 0; std::memcpy(m_begin, b.begin(), b.size());
}
m_debug.resize(m_debug.size() + n);
m_pending_copy = n;
#endif
if (m_read_cursor < m_write_cursor || m_empty)
{
// ..R***W..
if (m_last - m_write_cursor >= (std::ptrdiff_t)n)
{
interval ret(m_write_cursor, m_write_cursor + n);
m_write_cursor += n;
m_read_end = m_write_cursor;
assert(m_read_cursor <= m_read_end);
if (n) m_empty = false;
return ret;
} }
if (m_read_cursor - m_first >= (std::ptrdiff_t)n) buffer& operator=(buffer const& b)
{ {
m_read_end = m_write_cursor; resize(b.size());
interval ret(m_first, m_first + n); std::memcpy(m_begin, b.begin(), b.size());
m_write_cursor = m_first + n; return *this;
assert(m_read_cursor <= m_read_end);
if (n) m_empty = false;
return ret;
} }
reserve(capacity() + n - (m_last - m_write_cursor)); ~buffer()
assert(m_last - m_write_cursor >= (std::ptrdiff_t)n);
interval ret(m_write_cursor, m_write_cursor + n);
m_write_cursor += n;
m_read_end = m_write_cursor;
if (n) m_empty = false;
assert(m_read_cursor <= m_read_end);
return ret;
}
//**W...R**
if (m_read_cursor - m_write_cursor >= (std::ptrdiff_t)n)
{ {
interval ret(m_write_cursor, m_write_cursor + n); ::operator delete (m_begin);
m_write_cursor += n;
if (n) m_empty = false;
return ret;
} }
reserve(capacity() + n - (m_read_cursor - m_write_cursor));
assert(m_read_cursor - m_write_cursor >= (std::ptrdiff_t)n);
interval ret(m_write_cursor, m_write_cursor + n);
m_write_cursor += n;
if (n) m_empty = false;
return ret;
}
inline void buffer::insert(char const* first, char const* last) buffer::interval data() { return interval(m_begin, m_end); }
{ buffer::const_interval data() const { return const_interval(m_begin, m_end); }
INVARIANT_CHECK;
std::size_t n = last - first; void resize(std::size_t n)
#ifdef TORRENT_BUFFER_DEBUG
if (m_pending_copy)
{ {
std::copy(m_write_cursor - m_pending_copy, m_write_cursor reserve(n);
, m_debug.end() - m_pending_copy); m_end = m_begin + n;
m_pending_copy = 0;
} }
m_debug.insert(m_debug.end(), first, last);
#endif
if (space_left() < n) void insert(char* point, char const* first, char const* last)
{ {
reserve(capacity() + n); std::size_t p = point - m_begin;
} if (point == m_end)
m_empty = false;
char const* end = (m_last - m_write_cursor) < (std::ptrdiff_t)n ?
m_last : m_write_cursor + n;
std::size_t copied = end - m_write_cursor;
std::memcpy(m_write_cursor, first, copied);
m_write_cursor += copied;
if (m_write_cursor > m_read_end) m_read_end = m_write_cursor;
first += copied;
n -= copied;
if (n == 0) return;
assert(m_write_cursor == m_last);
m_write_cursor = m_first;
memcpy(m_write_cursor, first, n);
m_write_cursor += n;
}
inline void buffer::erase(std::size_t n)
{
INVARIANT_CHECK;
if (n == 0) return;
assert(!m_empty);
#ifndef NDEBUG
int prev_size = size();
#endif
assert(m_read_cursor <= m_read_end);
m_read_cursor += n;
if (m_read_cursor > m_read_end)
{ {
m_read_cursor = m_first + (m_read_cursor - m_read_end); resize(size() + last - first);
assert(m_read_cursor <= m_write_cursor); std::memcpy(m_begin + p, first, last - first);
return;
} }
m_empty = m_read_cursor == m_write_cursor; resize(size() + last - first);
std::memmove(m_begin + p + (last - first), m_begin + p, last - first);
std::memcpy(m_begin + p, first, last - first);
}
assert(prev_size - n == size()); void erase(char* begin, char* end)
#ifdef TORRENT_BUFFER_DEBUG
m_debug.erase(m_debug.begin(), m_debug.begin() + n);
#endif
}
inline std::size_t buffer::size() const
{
// ...R***W.
if (m_read_cursor < m_write_cursor)
{ {
return m_write_cursor - m_read_cursor; assert(end <= m_end);
} assert(begin >= m_begin);
// ***W..R* assert(begin <= end);
else if (end == m_end)
{ {
if (m_empty) return 0; resize(begin - m_begin);
return (m_write_cursor - m_first) + (m_read_end - m_read_cursor); return;
}
std::memmove(begin, end, m_end - end);
m_end = begin + (m_end - end);
} }
}
inline std::size_t buffer::capacity() const void clear() { m_end = m_begin; }
{ std::size_t size() const { return m_end - m_begin; }
return m_last - m_first; std::size_t capacity() const { return m_last - m_begin; }
} void reserve(std::size_t n)
{
inline void buffer::reserve(std::size_t size) if (n <= capacity()) return;
{ assert(n > 0);
std::size_t n = (std::size_t)(capacity() * 1.f);
if (n < size) n = size;
char* buf = (char*)::operator new(n); char* buf = (char*)::operator new(n);
char* old = m_first; std::size_t s = size();
std::memcpy(buf, m_begin, s);
if (m_read_cursor < m_write_cursor) ::operator delete (m_begin);
{ m_begin = buf;
// ...R***W.<>. m_end = buf + s;
std::memcpy( m_last = m_begin + n;
buf + (m_read_cursor - m_first)
, m_read_cursor
, m_write_cursor - m_read_cursor
);
m_write_cursor = buf + (m_write_cursor - m_first);
m_read_cursor = buf + (m_read_cursor - m_first);
m_read_end = m_write_cursor;
m_first = buf;
m_last = buf + n;
}
else
{
// **W..<>.R**
std::size_t skip = n - (m_last - m_first);
std::memcpy(buf, m_first, m_write_cursor - m_first);
std::memcpy(
buf + (m_read_cursor - m_first) + skip
, m_read_cursor
, m_last - m_read_cursor
);
m_write_cursor = buf + (m_write_cursor - m_first);
if (!m_empty)
{
m_read_cursor = buf + (m_read_cursor - m_first) + skip;
m_read_end = buf + (m_read_end - m_first) + skip;
}
else
{
m_read_cursor = m_write_cursor;
m_read_end = m_write_cursor;
} }
m_first = buf; bool empty() const { return m_begin == m_end; }
m_last = buf + n; char& operator[](std::size_t i) { assert(i >= 0 && i < size()); return m_begin[i]; }
} char const& operator[](std::size_t i) const { assert(i >= 0 && i < size()); return m_begin[i]; }
::operator delete (old); char* begin() { return m_begin; }
} char const* begin() const { return m_begin; }
char* end() { return m_end; }
char const* end() const { return m_end; }
#ifndef NDEBUG void swap(buffer& b)
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 using std::swap;
, m_debug.end() - m_pending_copy); swap(m_begin, b.m_begin);
m_pending_copy = 0; swap(m_end, b.m_end);
swap(m_last, b.m_last);
} }
#endif private:
char* m_begin; // first
char* m_end; // one passed end of size
char* m_last; // one passed end of allocation
};
// ...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)
);
}
// **W...R**
else
{
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)
, const_interval(m_first, m_write_cursor)
);
}
}
inline bool buffer::empty() const
{
return m_empty;
}
inline std::size_t buffer::space_left() const
{
if (m_empty) return m_last - m_first;
// ...R***W.
if (m_read_cursor < m_write_cursor)
{
return (m_last - m_write_cursor) + (m_read_cursor - m_first);
}
// ***W..R*
else
{
return m_read_cursor - m_write_cursor;
}
}
} }

View File

@ -510,7 +510,7 @@ namespace libtorrent
int m_packet_size; int m_packet_size;
int m_recv_pos; int m_recv_pos;
std::vector<char> m_recv_buffer; buffer m_recv_buffer;
// this is the buffer where data that is // this is the buffer where data that is
// to be sent is stored until it gets // to be sent is stored until it gets
@ -521,7 +521,7 @@ namespace libtorrent
// waiting for a async_write operation on one // waiting for a async_write operation on one
// buffer, the other is used to write data to // buffer, the other is used to write data to
// be queued up. // be queued up.
std::vector<char> m_send_buffer[2]; buffer m_send_buffer[2];
// the current send buffer is the one to write to. // the current send buffer is the one to write to.
// (m_current_send_buffer + 1) % 2 is the // (m_current_send_buffer + 1) % 2 is the
// buffer we're currently waiting for. // buffer we're currently waiting for.

View File

@ -98,13 +98,18 @@ namespace libtorrent
typedef asio::basic_deadline_timer<libtorrent::ptime> deadline_timer; typedef asio::basic_deadline_timer<libtorrent::ptime> deadline_timer;
inline std::ostream& operator<<(std::ostream& os, tcp::endpoint const& ep) inline std::ostream& print_endpoint(std::ostream& os, tcp::endpoint const& ep)
{ {
address const& a = ep.address(); address const& addr = ep.address();
if (a.is_v6()) asio::error_code ec;
os << "[" << a.to_string() << "]:" << ep.port(); std::string a = addr.to_string(ec);
if (ec) return os;
if (addr.is_v6())
os << "[" << a << "]:";
else else
os << a.to_string() << ":" << ep.port(); os << a << ":";
os << ep.port();
return os; return os;
} }

View File

@ -432,6 +432,7 @@ namespace libtorrent
{ {
m_send_buffer += "ipv6="; m_send_buffer += "ipv6=";
m_send_buffer += req.ipv6; m_send_buffer += req.ipv6;
m_send_buffer += '&';
} }
// extension that tells the tracker that // extension that tells the tracker that

View File

@ -2082,7 +2082,8 @@ namespace libtorrent
p.remote_dl_rate = 0; p.remote_dl_rate = 0;
} }
p.send_buffer_size = send_buffer_size(); p.send_buffer_size = int(m_send_buffer[0].capacity()
+ m_send_buffer[1].capacity());
} }
void peer_connection::cut_receive_buffer(int size, int packet_size) void peer_connection::cut_receive_buffer(int size, int packet_size)
@ -2512,7 +2513,7 @@ namespace libtorrent
void peer_connection::send_buffer(char const* begin, char const* end) void peer_connection::send_buffer(char const* begin, char const* end)
{ {
std::vector<char>& buf = m_send_buffer[m_current_send_buffer]; buffer& buf = m_send_buffer[m_current_send_buffer];
buf.insert(buf.end(), begin, end); buf.insert(buf.end(), begin, end);
setup_send(); setup_send();
} }
@ -2521,7 +2522,7 @@ namespace libtorrent
// return value is destructed // return value is destructed
buffer::interval peer_connection::allocate_send_buffer(int size) buffer::interval peer_connection::allocate_send_buffer(int size)
{ {
std::vector<char>& buf = m_send_buffer[m_current_send_buffer]; buffer& buf = m_send_buffer[m_current_send_buffer];
buf.resize(buf.size() + size); buf.resize(buf.size() + size);
buffer::interval ret(&buf[0] + buf.size() - size, &buf[0] + buf.size()); buffer::interval ret(&buf[0] + buf.size() - size, &buf[0] + buf.size());
return ret; return ret;
@ -2588,7 +2589,7 @@ namespace libtorrent
&& m_recv_pos == 0 && m_recv_pos == 0
&& (m_recv_buffer.capacity() - m_packet_size) > 128) && (m_recv_buffer.capacity() - m_packet_size) > 128)
{ {
std::vector<char>(m_packet_size).swap(m_recv_buffer); buffer(m_packet_size).swap(m_recv_buffer);
} }
int max_receive = m_packet_size - m_recv_pos; int max_receive = m_packet_size - m_recv_pos;
@ -2807,7 +2808,7 @@ namespace libtorrent
if (int(m_send_buffer[i].size()) < 64 if (int(m_send_buffer[i].size()) < 64
&& int(m_send_buffer[i].capacity()) > 128) && int(m_send_buffer[i].capacity()) > 128)
{ {
std::vector<char> tmp(m_send_buffer[i]); buffer tmp(m_send_buffer[i]);
tmp.swap(m_send_buffer[i]); tmp.swap(m_send_buffer[i]);
assert(m_send_buffer[i].capacity() == m_send_buffer[i].size()); assert(m_send_buffer[i].capacity() == m_send_buffer[i].size());
} }

View File

@ -695,14 +695,16 @@ namespace detail
// not even that worked, give up // not even that worked, give up
if (m_alerts.should_post(alert::fatal)) if (m_alerts.should_post(alert::fatal))
{ {
std::string msg = "cannot bind to the given interface '" std::stringstream msg;
+ boost::lexical_cast<std::string>(ep) + "' " + ec.message(); msg << "cannot bind to interface '";
m_alerts.post_alert(listen_failed_alert(ep, msg)); print_endpoint(msg, ep) << "' " << ec.message();
m_alerts.post_alert(listen_failed_alert(ep, msg.str()));
} }
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
std::string msg = "cannot bind to the given interface '" std::stringstream msg;
+ boost::lexical_cast<std::string>(ep) + "' " + ec.message(); msg << "cannot bind to interface '";
(*m_logger) << msg << "\n"; print_endpoint(msg, ep) << "' " << ec.message();
(*m_logger) << msg.str() << "\n";
#endif #endif
return listen_socket_t(); return listen_socket_t();
} }
@ -712,14 +714,16 @@ namespace detail
{ {
if (m_alerts.should_post(alert::fatal)) if (m_alerts.should_post(alert::fatal))
{ {
std::string msg = "cannot listen the given interface '" std::stringstream msg;
+ boost::lexical_cast<std::string>(ep) + "' " + ec.message(); msg << "cannot listen on interface '";
m_alerts.post_alert(listen_failed_alert(ep, msg)); print_endpoint(msg, ep) << "' " << ec.message();
m_alerts.post_alert(listen_failed_alert(ep, msg.str()));
} }
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
std::string msg = "cannot listen the given interface '" std::stringstream msg;
+ boost::lexical_cast<std::string>(ep) + "' " + ec.message(); msg << "cannot listen on interface '";
(*m_logger) << msg << "\n"; print_endpoint(msg, ep) << "' " << ec.message();
(*m_logger) << msg.str() << "\n";
#endif #endif
return listen_socket_t(); return listen_socket_t();
} }
@ -732,7 +736,7 @@ namespace detail
} }
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << "listening on: " << ep.address().to_string() << ":" << ep.port() (*m_logger) << "listening on: " << ep
<< " external port: " << s.external_port << "\n"; << " external port: " << s.external_port << "\n";
#endif #endif
return s; return s;