lt sync 1688

This commit is contained in:
Marcos Pinto 2007-10-22 22:33:08 +00:00
parent 2e5eb2b885
commit 5d4a69d852
15 changed files with 135 additions and 90 deletions

View file

@ -159,7 +159,7 @@ namespace libtorrent
asio::strand& m_strand;
tcp::resolver m_name_lookup;
int m_port;
boost::shared_ptr<socket_type> m_socket;
socket_type m_socket;
int m_recv_pos;
std::vector<char> m_buffer;
std::string m_send_buffer;

View file

@ -41,8 +41,8 @@ namespace libtorrent
{
struct proxy_settings;
boost::shared_ptr<socket_type> instantiate_connection(
asio::io_service& ios, proxy_settings const& ps);
bool instantiate_connection(asio::io_service& ios
, proxy_settings const& ps, socket_type& s);
}
#endif

View file

@ -104,10 +104,9 @@ public:
m_sock.bind(endpoint);
}
template <class Error_Handler>
void bind(endpoint_type const& endpoint, Error_Handler const& error_handler)
void bind(endpoint_type const& endpoint, asio::error_code& ec)
{
m_sock.bind(endpoint, error_handler);
m_sock.bind(endpoint, ec);
}
void open(protocol_type const& p)
@ -115,10 +114,9 @@ public:
m_sock.open(p);
}
template <class Error_Handler>
void open(protocol_type const& p, Error_Handler const& error_handler)
void open(protocol_type const& p, asio::error_code& ec)
{
m_sock.open(p, error_handler);
m_sock.open(p, ec);
}
void close()
@ -127,10 +125,9 @@ public:
m_sock.close();
}
template <class Error_Handler>
void close(Error_Handler const& error_handler)
void close(asio::error_code& ec)
{
m_sock.close(error_handler);
m_sock.close(ec);
}
endpoint_type remote_endpoint()
@ -138,8 +135,7 @@ public:
return m_remote_endpoint;
}
template <class Error_Handler>
endpoint_type remote_endpoint(Error_Handler const& error_handler)
endpoint_type remote_endpoint(asio::error_code& ec)
{
return m_remote_endpoint;
}
@ -149,10 +145,9 @@ public:
return m_sock.local_endpoint();
}
template <class Error_Handler>
endpoint_type local_endpoint(Error_Handler const& error_handler)
endpoint_type local_endpoint(asio::error_code& ec)
{
return m_sock.local_endpoint(error_handler);
return m_sock.local_endpoint(ec);
}
asio::io_service& io_service()
@ -168,7 +163,6 @@ public:
protected:
stream_socket m_sock;
// the socks5 proxy
std::string m_hostname;
int m_port;

View file

@ -87,7 +87,7 @@ namespace libtorrent
, tracker_receive_timeout(20)
, stop_tracker_timeout(5)
, tracker_maximum_response_length(1024*1024)
, piece_timeout(120)
, piece_timeout(10)
, request_queue_time(3.f)
, max_allowed_in_request_queue(250)
, max_out_request_queue(200)

View file

@ -89,3 +89,4 @@ private:
}
#endif

View file

@ -101,3 +101,4 @@ private:
}
#endif

View file

@ -424,6 +424,7 @@ namespace libtorrent
}
int block_size() const { TORRENT_ASSERT(m_block_size > 0); return m_block_size; }
peer_request to_req(piece_block const& p);
// this will tell all peers that we just got his piece
// and also let the piece picker know that we have this piece

View file

@ -105,7 +105,7 @@ namespace libtorrent
asio::strand& m_strand;
udp::resolver m_name_lookup;
boost::shared_ptr<datagram_socket> m_socket;
datagram_socket m_socket;
udp::endpoint m_target;
udp::endpoint m_sender;

View file

@ -501,15 +501,12 @@ public:
typedef typename S0::endpoint_type endpoint_type;
typedef typename S0::protocol_type protocol_type;
explicit variant_stream(asio::io_service& io_service)
: m_io_service(io_service)
, m_variant(boost::blank())
{}
explicit variant_stream() : m_variant(boost::blank()) {}
template <class S>
void instantiate()
void instantiate(asio::io_service& ios)
{
std::auto_ptr<S> owned(new S(m_io_service));
std::auto_ptr<S> owned(new S(ios));
boost::apply_visitor(aux::delete_visitor(), m_variant);
m_variant = owned.get();
owned.release();
@ -704,7 +701,6 @@ public:
}
private:
asio::io_service& m_io_service;
variant_type m_variant;
};

View file

@ -496,7 +496,7 @@ namespace libtorrent
void http_tracker_connection::on_timeout()
{
m_timed_out = true;
m_socket.reset();
m_socket.close();
m_name_lookup.cancel();
if (m_connection_ticket > -1) m_cc.done(m_connection_ticket);
m_connection_ticket = -1;
@ -550,18 +550,20 @@ namespace libtorrent
}
if (cb) cb->m_tracker_address = target_address;
m_socket = instantiate_connection(m_name_lookup.io_service(), m_proxy);
bool ret = instantiate_connection(m_strand.io_service(), m_proxy, m_socket);
TORRENT_ASSERT(ret);
if (m_proxy.type == proxy_settings::http
|| m_proxy.type == proxy_settings::http_pw)
{
// the tracker connection will talk immediately to
// the proxy, without requiring CONNECT support
m_socket->get<http_stream>().set_no_connect(true);
m_socket.get<http_stream>().set_no_connect(true);
}
m_socket->open(target_address.protocol());
m_socket->bind(tcp::endpoint(bind_interface(), 0));
m_socket.open(target_address.protocol());
m_socket.bind(tcp::endpoint(bind_interface(), 0));
m_cc.enqueue(bind(&http_tracker_connection::connect, self(), _1, target_address)
, bind(&http_tracker_connection::on_timeout, self())
, seconds(m_settings.tracker_receive_timeout));
@ -574,7 +576,7 @@ namespace libtorrent
void http_tracker_connection::connect(int ticket, tcp::endpoint target_address)
{
m_connection_ticket = ticket;
m_socket->async_connect(target_address, bind(&http_tracker_connection::connected, self(), _1));
m_socket.async_connect(target_address, bind(&http_tracker_connection::connected, self(), _1));
}
void http_tracker_connection::connected(asio::error_code const& error) try
@ -595,7 +597,7 @@ namespace libtorrent
#endif
restart_read_timeout();
async_write(*m_socket, asio::buffer(m_send_buffer.c_str()
async_write(m_socket, asio::buffer(m_send_buffer.c_str()
, m_send_buffer.size()), bind(&http_tracker_connection::sent
, self(), _1));
}
@ -620,7 +622,7 @@ namespace libtorrent
#endif
restart_read_timeout();
TORRENT_ASSERT(m_buffer.size() - m_recv_pos > 0);
m_socket->async_read_some(asio::buffer(&m_buffer[m_recv_pos]
m_socket.async_read_some(asio::buffer(&m_buffer[m_recv_pos]
, m_buffer.size() - m_recv_pos), bind(&http_tracker_connection::receive
, self(), _1, _2));
}
@ -701,7 +703,7 @@ namespace libtorrent
}
TORRENT_ASSERT(m_buffer.size() - m_recv_pos > 0);
m_socket->async_read_some(asio::buffer(&m_buffer[m_recv_pos]
m_socket.async_read_some(asio::buffer(&m_buffer[m_recv_pos]
, m_buffer.size() - m_recv_pos), bind(&http_tracker_connection::receive
, self(), _1, _2));
}

View file

@ -42,42 +42,40 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
boost::shared_ptr<socket_type> instantiate_connection(
asio::io_service& ios, proxy_settings const& ps)
bool instantiate_connection(asio::io_service& ios
, proxy_settings const& ps, socket_type& s)
{
boost::shared_ptr<socket_type> s(new socket_type(ios));
if (ps.type == proxy_settings::none)
{
s->instantiate<stream_socket>();
s.instantiate<stream_socket>(ios);
}
else if (ps.type == proxy_settings::http
|| ps.type == proxy_settings::http_pw)
{
s->instantiate<http_stream>();
s->get<http_stream>().set_proxy(ps.hostname, ps.port);
s.instantiate<http_stream>(ios);
s.get<http_stream>().set_proxy(ps.hostname, ps.port);
if (ps.type == proxy_settings::socks5_pw)
s->get<http_stream>().set_username(ps.username, ps.password);
s.get<http_stream>().set_username(ps.username, ps.password);
}
else if (ps.type == proxy_settings::socks5
|| ps.type == proxy_settings::socks5_pw)
{
s->instantiate<socks5_stream>();
s->get<socks5_stream>().set_proxy(ps.hostname, ps.port);
s.instantiate<socks5_stream>(ios);
s.get<socks5_stream>().set_proxy(ps.hostname, ps.port);
if (ps.type == proxy_settings::socks5_pw)
s->get<socks5_stream>().set_username(ps.username, ps.password);
s.get<socks5_stream>().set_username(ps.username, ps.password);
}
else if (ps.type == proxy_settings::socks4)
{
s->instantiate<socks4_stream>();
s->get<socks4_stream>().set_proxy(ps.hostname, ps.port);
s->get<socks4_stream>().set_username(ps.username);
s.instantiate<socks4_stream>(ios);
s.get<socks4_stream>().set_proxy(ps.hostname, ps.port);
s.get<socks4_stream>().set_username(ps.username);
}
else
{
throw std::runtime_error("unsupported proxy type");
return false;
}
return s;
return true;
}
}

View file

@ -2209,18 +2209,19 @@ namespace libtorrent
piece_picker& picker = t->picker();
while (!m_download_queue.empty())
{
picker.abort_download(m_download_queue.back());
piece_block const& r = m_download_queue.back();
picker.abort_download(r);
write_cancel(t->to_req(r));
m_download_queue.pop_back();
}
while (!m_request_queue.empty())
{
picker.abort_download(m_request_queue.back());
piece_block const& r = m_request_queue.back();
picker.abort_download(r);
write_cancel(t->to_req(r));
m_request_queue.pop_back();
}
// TODO: If we have a limited number of upload
// slots, choke this peer
m_assume_fifo = true;
request_a_block(*t, *this);
@ -2990,11 +2991,25 @@ namespace libtorrent
// time, it is considered to have timed out
time_duration d;
d = now - m_last_receive;
if (d > seconds(m_timeout)) return true;
if (d > seconds(m_timeout))
{
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string() << " *** LAST ACTIVITY [ "
<< total_seconds(d) << " seconds ago ] ***\n";
#endif
return true;
}
// if it takes more than 5 seconds to receive
// handshake, disconnect
if (in_handshake() && d > seconds(5)) return true;
if (in_handshake() && d > seconds(5))
{
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string() << " *** NO HANDSHAKE [ "
<< total_seconds(d) << " seconds ago ] ***\n";
#endif
return true;
}
// disconnect peers that we unchoked, but
// they didn't send a request within 20 seconds.
@ -3005,7 +3020,14 @@ namespace libtorrent
&& !m_choked
&& m_peer_interested
&& t && t->is_finished()
&& d > seconds(20)) return true;
&& d > seconds(20))
{
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string() << " *** NO REQUEST [ t: "
<< total_seconds(d) << " ] ***\n";
#endif
return true;
}
// TODO: as long as we have less than 95% of the
// global (or local) connection limit, connections should
@ -3021,11 +3043,21 @@ namespace libtorrent
time_duration time_limit = seconds(
m_ses.settings().inactivity_timeout);
// don't bother disconnect peers we haven't been intersted
// in (and that hasn't been interested in us) for a while
// unless we have used up all our connection slots
if (!m_interesting
&& !m_peer_interested
&& d1 > time_limit
&& d2 > time_limit)
&& d2 > time_limit
&& (m_ses.num_connections() >= m_ses.max_connections()
|| (t && t->num_peers() >= t->max_connections())))
{
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string() << " *** MUTUAL NO INTEREST [ "
"t1: " << total_seconds(d1) << " | "
"t2: " << total_seconds(d2) << " ] ***\n";
#endif
return true;
}
@ -3068,10 +3100,9 @@ namespace libtorrent
if (m_writing) return;
#ifdef TORRENT_VERBOSE_LOGGING
using namespace boost::posix_time;
(*m_logger) << time_now_string() << " ==> KEEPALIVE\n";
#endif
m_last_sent = time_now();
write_keepalive();
}

View file

@ -902,8 +902,8 @@ namespace detail
void session_impl::async_accept(boost::shared_ptr<socket_acceptor> const& listener)
{
shared_ptr<socket_type> c(new socket_type(m_io_service));
c->instantiate<stream_socket>();
shared_ptr<socket_type> c(new socket_type);
c->instantiate<stream_socket>(m_io_service);
listener->async_accept(c->get<stream_socket>()
, bind(&session_impl::on_incoming_connection, this, c
, boost::weak_ptr<socket_acceptor>(listener), _1));

View file

@ -326,6 +326,21 @@ namespace libtorrent
disconnect_all();
}
peer_request torrent::to_req(piece_block const& p)
{
int block_offset = p.block_index * m_block_size;
int block_size = (std::min)((int)torrent_file().piece_size(
p.piece_index) - block_offset, m_block_size);
TORRENT_ASSERT(block_size > 0);
TORRENT_ASSERT(block_size <= m_block_size);
peer_request r;
r.piece = p.piece_index;
r.start = block_offset;
r.length = block_size;
return r;
}
std::string torrent::name() const
{
if (valid_metadata()) return m_torrent_file->name();
@ -1656,8 +1671,11 @@ namespace libtorrent
else return;
}
boost::shared_ptr<socket_type> s
= instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy());
boost::shared_ptr<socket_type> s(new socket_type);
bool ret = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy(), *s);
TORRENT_ASSERT(ret);
if (m_ses.web_seed_proxy().type == proxy_settings::http
|| m_ses.web_seed_proxy().type == proxy_settings::http_pw)
{
@ -1869,8 +1887,11 @@ namespace libtorrent
tcp::endpoint const& a(peerinfo->ip);
TORRENT_ASSERT((m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) == 0);
boost::shared_ptr<socket_type> s
= instantiate_connection(m_ses.m_io_service, m_ses.peer_proxy());
boost::shared_ptr<socket_type> s(new socket_type);
bool ret = instantiate_connection(m_ses.m_io_service, m_ses.peer_proxy(), *s);
TORRENT_ASSERT(ret);
boost::intrusive_ptr<peer_connection> c(new bt_peer_connection(
m_ses, shared_from_this(), s, a, peerinfo));

View file

@ -86,6 +86,7 @@ namespace libtorrent
, m_man(man)
, m_strand(str)
, m_name_lookup(m_strand.io_service())
, m_socket(m_strand.io_service())
, m_transaction_id(0)
, m_connection_id(0)
, m_settings(stn)
@ -103,7 +104,7 @@ namespace libtorrent
, udp::resolver::iterator i) try
{
if (error == asio::error::operation_aborted) return;
if (!m_socket) return; // the operation was aborted
if (!m_socket.is_open()) return; // the operation was aborted
if (error || i == udp::resolver::iterator())
{
fail(-1, error.message().c_str());
@ -143,10 +144,9 @@ namespace libtorrent
if (cb) cb->m_tracker_address = tcp::endpoint(target_address.address(), target_address.port());
m_target = target_address;
m_socket.reset(new datagram_socket(m_name_lookup.io_service()));
m_socket->open(target_address.protocol());
m_socket->bind(udp::endpoint(bind_interface(), 0));
m_socket->connect(target_address);
m_socket.open(target_address.protocol());
m_socket.bind(udp::endpoint(bind_interface(), 0));
m_socket.connect(target_address);
send_udp_connect();
}
catch (std::exception& e)
@ -156,7 +156,7 @@ namespace libtorrent
void udp_tracker_connection::on_timeout()
{
m_socket.reset();
m_socket.close();
m_name_lookup.cancel();
fail_timeout();
}
@ -171,7 +171,7 @@ namespace libtorrent
+ lexical_cast<std::string>(tracker_req().info_hash) + "]");
}
#endif
if (!m_socket) return; // the operation was aborted
if (!m_socket.is_open()) return; // the operation was aborted
char send_buf[16];
char* ptr = send_buf;
@ -187,10 +187,10 @@ namespace libtorrent
// transaction_id
detail::write_int32(m_transaction_id, ptr);
m_socket->send(asio::buffer((void*)send_buf, 16), 0);
m_socket.send(asio::buffer((void*)send_buf, 16), 0);
++m_attempts;
m_buffer.resize(udp_buffer_size);
m_socket->async_receive_from(asio::buffer(m_buffer), m_sender
m_socket.async_receive_from(asio::buffer(m_buffer), m_sender
, boost::bind(&udp_tracker_connection::connect_response, self(), _1, _2));
}
@ -198,7 +198,7 @@ namespace libtorrent
, std::size_t bytes_transferred) try
{
if (error == asio::error::operation_aborted) return;
if (!m_socket) return; // the operation was aborted
if (!m_socket.is_open()) return; // the operation was aborted
if (error)
{
fail(-1, error.message().c_str());
@ -208,7 +208,7 @@ namespace libtorrent
if (m_target != m_sender)
{
// this packet was not received from the tracker
m_socket->async_receive_from(asio::buffer(m_buffer), m_sender
m_socket.async_receive_from(asio::buffer(m_buffer), m_sender
, boost::bind(&udp_tracker_connection::connect_response, self(), _1, _2));
return;
}
@ -284,7 +284,7 @@ namespace libtorrent
if (m_transaction_id == 0)
m_transaction_id = rand() ^ (rand() << 16);
if (!m_socket) return; // the operation was aborted
if (!m_socket.is_open()) return; // the operation was aborted
std::vector<char> buf;
std::back_insert_iterator<std::vector<char> > out(buf);
@ -332,10 +332,10 @@ namespace libtorrent
}
#endif
m_socket->send(asio::buffer(buf), 0);
m_socket.send(asio::buffer(buf), 0);
++m_attempts;
m_socket->async_receive_from(asio::buffer(m_buffer), m_sender
m_socket.async_receive_from(asio::buffer(m_buffer), m_sender
, bind(&udp_tracker_connection::announce_response, self(), _1, _2));
}
@ -344,7 +344,7 @@ namespace libtorrent
if (m_transaction_id == 0)
m_transaction_id = rand() ^ (rand() << 16);
if (!m_socket) return; // the operation was aborted
if (!m_socket.is_open()) return; // the operation was aborted
std::vector<char> buf;
std::back_insert_iterator<std::vector<char> > out(buf);
@ -358,10 +358,10 @@ namespace libtorrent
// info_hash
std::copy(tracker_req().info_hash.begin(), tracker_req().info_hash.end(), out);
m_socket->send(asio::buffer(&buf[0], buf.size()), 0);
m_socket.send(asio::buffer(&buf[0], buf.size()), 0);
++m_attempts;
m_socket->async_receive_from(asio::buffer(m_buffer), m_sender
m_socket.async_receive_from(asio::buffer(m_buffer), m_sender
, bind(&udp_tracker_connection::scrape_response, self(), _1, _2));
}
@ -369,7 +369,7 @@ namespace libtorrent
, std::size_t bytes_transferred) try
{
if (error == asio::error::operation_aborted) return;
if (!m_socket) return; // the operation was aborted
if (!m_socket.is_open()) return; // the operation was aborted
if (error)
{
fail(-1, error.message().c_str());
@ -379,7 +379,7 @@ namespace libtorrent
if (m_target != m_sender)
{
// this packet was not received from the tracker
m_socket->async_receive_from(asio::buffer(m_buffer), m_sender
m_socket.async_receive_from(asio::buffer(m_buffer), m_sender
, bind(&udp_tracker_connection::connect_response, self(), _1, _2));
return;
}
@ -479,7 +479,7 @@ namespace libtorrent
, std::size_t bytes_transferred) try
{
if (error == asio::error::operation_aborted) return;
if (!m_socket) return; // the operation was aborted
if (!m_socket.is_open()) return; // the operation was aborted
if (error)
{
fail(-1, error.message().c_str());
@ -489,7 +489,7 @@ namespace libtorrent
if (m_target != m_sender)
{
// this packet was not received from the tracker
m_socket->async_receive_from(asio::buffer(m_buffer), m_sender
m_socket.async_receive_from(asio::buffer(m_buffer), m_sender
, bind(&udp_tracker_connection::connect_response, self(), _1, _2));
return;
}