Libtorrent sync 1814

This commit is contained in:
Andrew Resch 2007-12-13 06:30:39 +00:00
parent 8271d70ec7
commit 83be470f1e
19 changed files with 122 additions and 49 deletions

View File

@ -177,8 +177,6 @@ char const* session_start_natpmp_doc =
""; "";
char const* session_stop_natpmp_doc = char const* session_stop_natpmp_doc =
""; "";
char const* session_wait_for_alert_doc =
"";
// -- alert ----------------------------------------------------------------- // -- alert -----------------------------------------------------------------

View File

@ -5,7 +5,6 @@
#include <libtorrent/session.hpp> #include <libtorrent/session.hpp>
#include <libtorrent/torrent.hpp> #include <libtorrent/torrent.hpp>
#include <libtorrent/storage.hpp> #include <libtorrent/storage.hpp>
#include <libtorrent/time.hpp>
#include <boost/python.hpp> #include <boost/python.hpp>
#include "gil.hpp" #include "gil.hpp"
@ -57,7 +56,6 @@ extern char const* session_stop_lsd_doc;
extern char const* session_stop_upnp_doc; extern char const* session_stop_upnp_doc;
extern char const* session_start_natpmp_doc; extern char const* session_start_natpmp_doc;
extern char const* session_stop_natpmp_doc; extern char const* session_stop_natpmp_doc;
extern char const* session_wait_for_alert_doc;
namespace namespace
{ {
@ -250,7 +248,6 @@ void bind_session()
.def("stop_lsd", allow_threads(&session::stop_lsd), session_stop_lsd_doc) .def("stop_lsd", allow_threads(&session::stop_lsd), session_stop_lsd_doc)
.def("start_natpmp", allow_threads(&session::start_natpmp), session_start_natpmp_doc) .def("start_natpmp", allow_threads(&session::start_natpmp), session_start_natpmp_doc)
.def("stop_natpmp", allow_threads(&session::stop_natpmp), session_stop_natpmp_doc) .def("stop_natpmp", allow_threads(&session::stop_natpmp), session_stop_natpmp_doc)
.def("wait_for_alert", allow_threads(&session::wait_for_alert), session_wait_for_alert_doc)
; ;
register_ptr_to_python<std::auto_ptr<alert> >(); register_ptr_to_python<std::auto_ptr<alert> >();

View File

@ -100,7 +100,7 @@ namespace libtorrent {
void set_severity(alert::severity_t severity); void set_severity(alert::severity_t severity);
bool should_post(alert::severity_t severity) const; bool should_post(alert::severity_t severity) const;
std::auto_ptr<alert> wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
private: private:
std::queue<alert*> m_alerts; std::queue<alert*> m_alerts;

View File

@ -280,7 +280,7 @@ namespace libtorrent
void set_severity_level(alert::severity_t s); void set_severity_level(alert::severity_t s);
std::auto_ptr<alert> pop_alert(); std::auto_ptr<alert> pop_alert();
std::auto_ptr<alert> wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
int upload_rate_limit() const; int upload_rate_limit() const;
int download_rate_limit() const; int download_rate_limit() const;

View File

@ -111,7 +111,7 @@ struct bandwidth_limit
void assign(int amount) throw() void assign(int amount) throw()
{ {
TORRENT_ASSERT(amount > 0); TORRENT_ASSERT(amount >= 0);
m_current_rate += amount; m_current_rate += amount;
m_quota_left += amount; m_quota_left += amount;
} }
@ -225,8 +225,14 @@ struct bandwidth_manager
} }
#endif #endif
TORRENT_ASSERT(peer->max_assignable_bandwidth(m_channel) > 0);
boost::shared_ptr<Torrent> t = peer->associated_torrent().lock(); boost::shared_ptr<Torrent> t = peer->associated_torrent().lock();
if (peer->max_assignable_bandwidth(m_channel) == 0)
{
t->expire_bandwidth(m_channel, blk);
peer->assign_bandwidth(m_channel, 0);
return;
}
m_queue.push_back(bw_queue_entry<PeerConnection>(peer, blk, non_prioritized)); m_queue.push_back(bw_queue_entry<PeerConnection>(peer, blk, non_prioritized));
if (!non_prioritized) if (!non_prioritized)
{ {
@ -389,6 +395,7 @@ private:
if (max_assignable == 0) if (max_assignable == 0)
{ {
t->expire_bandwidth(m_channel, qe.max_block_size); t->expire_bandwidth(m_channel, qe.max_block_size);
qe.peer->assign_bandwidth(m_channel, 0);
TORRENT_ASSERT(amount == limit - m_current_quota); TORRENT_ASSERT(amount == limit - m_current_quota);
continue; continue;
} }
@ -430,7 +437,7 @@ private:
if (block_size > qe.max_block_size) block_size = qe.max_block_size; if (block_size > qe.max_block_size) block_size = qe.max_block_size;
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl; std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl;
#endif #endif
if (amount < block_size / 2) if (amount < block_size / 2)
{ {

View File

@ -124,7 +124,8 @@ namespace libtorrent
private: private:
mutable boost::mutex m_mutex; typedef boost::recursive_mutex mutex_t;
mutable mutex_t m_mutex;
boost::condition m_signal; boost::condition m_signal;
bool m_abort; bool m_abort;
std::deque<disk_io_job> m_jobs; std::deque<disk_io_job> m_jobs;

View File

@ -128,6 +128,19 @@ namespace libtorrent { namespace dht
// used to resolve hostnames for nodes // used to resolve hostnames for nodes
udp::resolver m_host_resolver; udp::resolver m_host_resolver;
// used to ignore abusive dht nodes
struct node_ban_entry
{
node_ban_entry(): count(0) {}
udp::endpoint src;
ptime limit;
int count;
};
enum { num_ban_nodes = 20 };
node_ban_entry m_ban_nodes[num_ban_nodes];
// reference counter for intrusive_ptr // reference counter for intrusive_ptr
mutable boost::detail::atomic_count m_refs; mutable boost::detail::atomic_count m_refs;

View File

@ -265,7 +265,7 @@ namespace libtorrent
std::auto_ptr<alert> pop_alert(); std::auto_ptr<alert> pop_alert();
void set_severity_level(alert::severity_t s); void set_severity_level(alert::severity_t s);
std::auto_ptr<alert> wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
connection_queue& get_connection_queue(); connection_queue& get_connection_queue();

View File

@ -84,7 +84,7 @@ namespace libtorrent
LIBTORRENT_VERSION) LIBTORRENT_VERSION)
: user_agent(user_agent_) : user_agent(user_agent_)
, tracker_completion_timeout(60) , tracker_completion_timeout(60)
, tracker_receive_timeout(20) , tracker_receive_timeout(40)
, stop_tracker_timeout(5) , stop_tracker_timeout(5)
, tracker_maximum_response_length(1024*1024) , tracker_maximum_response_length(1024*1024)
, piece_timeout(10) , piece_timeout(10)

View File

@ -99,6 +99,7 @@ namespace libtorrent
time_duration operator/(int rhs) const { return time_duration(diff / rhs); } time_duration operator/(int rhs) const { return time_duration(diff / rhs); }
explicit time_duration(boost::int64_t d) : diff(d) {} explicit time_duration(boost::int64_t d) : diff(d) {}
time_duration& operator-=(time_duration const& c) { diff -= c.diff; return *this; } time_duration& operator-=(time_duration const& c) { diff -= c.diff; return *this; }
time_duration operator+(time_duration const& c) { return time_duration(diff + c.diff); }
boost::int64_t diff; boost::int64_t diff;
}; };

View File

@ -78,11 +78,11 @@ namespace libtorrent {
} }
} }
std::auto_ptr<alert> alert_manager::wait_for_alert(time_duration max_wait) alert const* alert_manager::wait_for_alert(time_duration max_wait)
{ {
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
if (!m_alerts.empty()) return std::auto_ptr<alert>(m_alerts.front()); if (!m_alerts.empty()) return m_alerts.front();
int secs = total_seconds(max_wait); int secs = total_seconds(max_wait);
max_wait -= seconds(secs); max_wait -= seconds(secs);
@ -96,10 +96,10 @@ namespace libtorrent {
xt.sec += 1; xt.sec += 1;
} }
xt.nsec = nsec; xt.nsec = nsec;
if (!m_condition.timed_wait(lock, xt)) return std::auto_ptr<alert>(NULL); if (!m_condition.timed_wait(lock, xt)) return 0;
TORRENT_ASSERT(!m_alerts.empty()); TORRENT_ASSERT(!m_alerts.empty());
if (m_alerts.empty()) return std::auto_ptr<alert>(NULL); if (m_alerts.empty()) return 0;
return std::auto_ptr<alert>(m_alerts.front()); return m_alerts.front();
} }
void alert_manager::post_alert(const alert& alert_) void alert_manager::post_alert(const alert& alert_)

View File

@ -62,7 +62,7 @@ namespace libtorrent
disk_io_thread::~disk_io_thread() disk_io_thread::~disk_io_thread()
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
m_abort = true; m_abort = true;
m_signal.notify_all(); m_signal.notify_all();
l.unlock(); l.unlock();
@ -74,7 +74,7 @@ namespace libtorrent
disk_io_job disk_io_thread::find_job(boost::intrusive_ptr<piece_manager> s disk_io_job disk_io_thread::find_job(boost::intrusive_ptr<piece_manager> s
, int action, int piece) const , int action, int piece) const
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
for (std::deque<disk_io_job>::const_iterator i = m_jobs.begin(); for (std::deque<disk_io_job>::const_iterator i = m_jobs.begin();
i != m_jobs.end(); ++i) i != m_jobs.end(); ++i)
{ {
@ -98,7 +98,7 @@ namespace libtorrent
// aborts read operations // aborts read operations
void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> s) void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> s)
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
// read jobs are aborted, write and move jobs are syncronized // read jobs are aborted, write and move jobs are syncronized
for (std::deque<disk_io_job>::iterator i = m_jobs.begin(); for (std::deque<disk_io_job>::iterator i = m_jobs.begin();
i != m_jobs.end();) i != m_jobs.end();)
@ -151,7 +151,7 @@ namespace libtorrent
{ {
TORRENT_ASSERT(!j.callback); TORRENT_ASSERT(!j.callback);
TORRENT_ASSERT(j.storage); TORRENT_ASSERT(j.storage);
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
std::deque<disk_io_job>::reverse_iterator i = m_jobs.rbegin(); std::deque<disk_io_job>::reverse_iterator i = m_jobs.rbegin();
if (j.action == disk_io_job::read) if (j.action == disk_io_job::read)
@ -206,7 +206,7 @@ namespace libtorrent
char* disk_io_thread::allocate_buffer() char* disk_io_thread::allocate_buffer()
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
#ifdef TORRENT_STATS #ifdef TORRENT_STATS
++m_allocations; ++m_allocations;
#endif #endif
@ -215,7 +215,7 @@ namespace libtorrent
void disk_io_thread::free_buffer(char* buf) void disk_io_thread::free_buffer(char* buf)
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
#ifdef TORRENT_STATS #ifdef TORRENT_STATS
--m_allocations; --m_allocations;
#endif #endif
@ -229,7 +229,7 @@ namespace libtorrent
#ifdef TORRENT_DISK_STATS #ifdef TORRENT_DISK_STATS
m_log << log_time() << " idle" << std::endl; m_log << log_time() << " idle" << std::endl;
#endif #endif
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
#ifndef NDEBUG #ifndef NDEBUG
m_current.action = (disk_io_job::action_t)-1; m_current.action = (disk_io_job::action_t)-1;
m_current.piece = -1; m_current.piece = -1;
@ -250,7 +250,7 @@ namespace libtorrent
int ret = 0; int ret = 0;
bool free_buffer = true; bool free_current_buffer = true;
try try
{ {
TORRENT_ASSERT(j.storage); TORRENT_ASSERT(j.storage);
@ -264,15 +264,10 @@ namespace libtorrent
#ifdef TORRENT_DISK_STATS #ifdef TORRENT_DISK_STATS
m_log << log_time() << " read " << j.buffer_size << std::endl; m_log << log_time() << " read " << j.buffer_size << std::endl;
#endif #endif
free_buffer = false; free_current_buffer = false;
if (j.buffer == 0) if (j.buffer == 0)
{ {
l.lock(); j.buffer = allocate_buffer();
j.buffer = (char*)m_pool.ordered_malloc();
#ifdef TORRENT_STATS
++m_allocations;
#endif
l.unlock();
TORRENT_ASSERT(j.buffer_size <= m_block_size); TORRENT_ASSERT(j.buffer_size <= m_block_size);
if (j.buffer == 0) if (j.buffer == 0)
{ {
@ -347,14 +342,7 @@ namespace libtorrent
m_current.callback.clear(); m_current.callback.clear();
#endif #endif
if (j.buffer && free_buffer) if (j.buffer && free_current_buffer) free_buffer(j.buffer);
{
l.lock();
m_pool.ordered_free(j.buffer);
#ifdef TORRENT_STATS
--m_allocations;
#endif
}
} }
} }
} }

View File

@ -284,7 +284,17 @@ void http_connection::on_read(asio::error_code const& e
{ {
libtorrent::buffer::const_interval rcv_buf(&m_recvbuffer[0] libtorrent::buffer::const_interval rcv_buf(&m_recvbuffer[0]
, &m_recvbuffer[0] + m_read_pos); , &m_recvbuffer[0] + m_read_pos);
m_parser.incoming(rcv_buf); try
{
m_parser.incoming(rcv_buf);
}
catch (std::exception& e)
{
m_timer.cancel();
m_handler(asio::error::fault, m_parser, 0, 0);
m_handler.clear();
return;
}
if (!m_bottled && m_parser.header_finished()) if (!m_bottled && m_parser.header_finished())
{ {
if (m_read_pos > m_parser.body_start()) if (m_read_pos > m_parser.body_start())

View File

@ -217,7 +217,11 @@ namespace libtorrent
char dummy; char dummy;
std::string bytes; std::string bytes;
size_type range_start, range_end; size_type range_start, range_end;
range_str >> bytes >> range_start >> dummy >> range_end; // apparently some web servers do not send the "bytes"
// in their content-range
if (value.find(' ') != std::string::npos)
range_str >> bytes;
range_str >> range_start >> dummy >> range_end;
if (!range_str || range_end < range_start) if (!range_str || range_end < range_start)
{ {
throw std::runtime_error("invalid content-range in HTTP response: " + range_str.str()); throw std::runtime_error("invalid content-range in HTTP response: " + range_str.str());

View File

@ -405,6 +405,54 @@ namespace libtorrent { namespace dht
if (error) return; if (error) return;
node_ban_entry* match = 0;
node_ban_entry* min = m_ban_nodes;
ptime now = time_now();
for (node_ban_entry* i = m_ban_nodes; i < m_ban_nodes + num_ban_nodes; ++i)
{
if (i->src == m_remote_endpoint[current_buffer])
{
match = i;
break;
}
if (i->count < min->count) min = i;
}
if (match)
{
++match->count;
if (match->count >= 20)
{
if (now < match->limit)
{
#ifdef TORRENT_DHT_VERBOSE_LOGGING
if (match->count == 20)
{
TORRENT_LOG(dht_tracker) << time_now_string() << " BANNING PEER [ ip: "
<< m_remote_endpoint[current_buffer] << " | "
"time: " << total_seconds((now - match->limit) + seconds(5))
<< " | count: " << match->count << " ]";
}
#endif
// we've received 20 messages in less than 5 seconds from
// this node. Ignore it until it's silent for 5 minutes
match->limit = now + minutes(5);
return;
}
// we got 50 messages from this peer, but it was in
// more than 5 seconds. Reset the counter and the timer
match->count = 0;
match->limit = now + seconds(5);
}
}
else
{
min->count = 1;
min->limit = now + seconds(5);
min->src = m_remote_endpoint[current_buffer];
}
#ifdef TORRENT_DHT_VERBOSE_LOGGING #ifdef TORRENT_DHT_VERBOSE_LOGGING
++m_total_message_input; ++m_total_message_input;
m_total_in_bytes += bytes_transferred; m_total_in_bytes += bytes_transferred;

View File

@ -213,11 +213,11 @@ bool rpc_manager::incoming(msg const& m)
return false; return false;
} }
if (m.addr != o->target_addr) if (m.addr.address() != o->target_addr.address())
{ {
#ifdef TORRENT_DHT_VERBOSE_LOGGING #ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_LOG(rpc) << "Reply with incorrect address and valid transaction id: " TORRENT_LOG(rpc) << "Reply with incorrect address and valid transaction id: "
<< tid << " from " << m.addr; << tid << " from " << m.addr << " expected: " << o->target_addr;
#endif #endif
return false; return false;
} }

View File

@ -422,7 +422,7 @@ namespace libtorrent
return m_impl->pop_alert(); return m_impl->pop_alert();
} }
std::auto_ptr<alert> session::wait_for_alert(time_duration max_wait) alert const* session::wait_for_alert(time_duration max_wait)
{ {
return m_impl->wait_for_alert(max_wait); return m_impl->wait_for_alert(max_wait);
} }

View File

@ -1836,7 +1836,7 @@ namespace detail
t.abort(); t.abort();
if ((!t.is_paused() || t.should_request()) if ((!t.is_paused() || t.should_request())
&& !t.torrent_file().trackers().empty()) && !t.trackers().empty())
{ {
tracker_request req = t.generate_tracker_request(); tracker_request req = t.generate_tracker_request();
TORRENT_ASSERT(req.event == tracker_request::stopped); TORRENT_ASSERT(req.event == tracker_request::stopped);
@ -2272,7 +2272,7 @@ namespace detail
return std::auto_ptr<alert>(0); return std::auto_ptr<alert>(0);
} }
std::auto_ptr<alert> session_impl::wait_for_alert(time_duration max_wait) alert const* session_impl::wait_for_alert(time_duration max_wait)
{ {
return m_alerts.wait_for_alert(max_wait); return m_alerts.wait_for_alert(max_wait);
} }

View File

@ -735,8 +735,10 @@ namespace libtorrent
return make_tuple(m_torrent_file->total_size() return make_tuple(m_torrent_file->total_size()
, m_torrent_file->total_size()); , m_torrent_file->total_size());
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
size_type wanted_done = size_type(m_num_pieces - m_picker->num_have_filtered()) size_type wanted_done = size_type(m_num_pieces - m_picker->num_have_filtered())
* piece_size; * piece_size;
TORRENT_ASSERT(wanted_done >= 0);
size_type total_done size_type total_done
= size_type(m_num_pieces) * piece_size; = size_type(m_num_pieces) * piece_size;
@ -762,6 +764,7 @@ namespace libtorrent
TORRENT_ASSERT(total_done <= m_torrent_file->total_size()); TORRENT_ASSERT(total_done <= m_torrent_file->total_size());
TORRENT_ASSERT(wanted_done <= m_torrent_file->total_size()); TORRENT_ASSERT(wanted_done <= m_torrent_file->total_size());
TORRENT_ASSERT(total_done >= wanted_done);
const std::vector<piece_picker::downloading_piece>& dl_queue const std::vector<piece_picker::downloading_piece>& dl_queue
= m_picker->get_download_queue(); = m_picker->get_download_queue();
@ -2760,6 +2763,8 @@ namespace libtorrent
#endif #endif
disconnect_all(); disconnect_all();
if (!m_paused)
m_just_paused = true;
m_paused = true; m_paused = true;
// tell the tracker that we stopped // tell the tracker that we stopped
m_event = tracker_request::stopped; m_event = tracker_request::stopped;
@ -3033,6 +3038,7 @@ namespace libtorrent
st.num_incomplete = m_incomplete; st.num_incomplete = m_incomplete;
st.paused = m_paused; st.paused = m_paused;
boost::tie(st.total_done, st.total_wanted_done) = bytes_done(); boost::tie(st.total_done, st.total_wanted_done) = bytes_done();
TORRENT_ASSERT(st.total_done >= st.total_wanted_done);
// payload transfer // payload transfer
st.total_payload_download = m_stat.total_payload_download(); st.total_payload_download = m_stat.total_payload_download();