From b6be33b5b64c0ddb53fb800c0eb011b3dfa5d1c1 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 25 Mar 2008 04:38:59 +0000 Subject: [PATCH] storage fix --- src/session_impl.cpp | 16 ++++++++++-- src/storage.cpp | 9 ++++--- src/udp_socket.cpp | 45 ++++++++++++++++++++++++++++------ src/udp_tracker_connection.cpp | 7 ++++-- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 1360688db..0c10808b1 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -162,7 +162,7 @@ namespace aux { #ifndef TORRENT_DISABLE_DHT , m_dht_same_port(true) , m_external_udp_port(0) - , m_dht_socket(m_io_service, bind(&session_impl::on_receive_udp, this, _1, _2, _3) + , m_dht_socket(m_io_service, bind(&session_impl::on_receive_udp, this, _1, _2, _3, _4) , m_half_open) #endif , m_timer(m_io_service) @@ -580,8 +580,20 @@ namespace aux { #ifndef TORRENT_DISABLE_DHT - void session_impl::on_receive_udp(udp::endpoint const& ep, char const* buf, int len) + void session_impl::on_receive_udp(asio::error_code const& e + , udp::endpoint const& ep, char const* buf, int len) { + if (e) + { + if (m_alerts.should_post(alert::info)) + { + std::string msg = "UDP socket error from '" + + boost::lexical_cast(ep) + "' " + e.message(); + m_alerts.post_alert(udp_error_alert(ep, msg)); + } + return; + } + if (len > 20 && *buf == 'd' && m_dht) { // this is probably a dht message diff --git a/src/storage.cpp b/src/storage.cpp index 5c076a26e..49f05b84f 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -2212,6 +2212,7 @@ namespace libtorrent { TORRENT_ASSERT(m_storage_mode == storage_mode_compact); TORRENT_ASSERT(m_unallocated_slots.empty()); + TORRENT_ASSERT(m_free_slots.empty()); // we have allocated all slots, switch to // full allocation mode in order to free // some unnecessary memory. @@ -2330,10 +2331,8 @@ namespace libtorrent TORRENT_ASSERT(slot_index >= 0); TORRENT_ASSERT(slot_index < (int)m_slot_to_piece.size()); - if (m_unallocated_slots.empty()) - { + if (m_free_slots.empty() && m_unallocated_slots.empty()) switch_to_full_mode(); - } return slot_index; } @@ -2400,7 +2399,9 @@ namespace libtorrent TORRENT_ASSERT(m_current_slot <= m_info->num_pieces()); - if (m_unallocated_slots.empty() && m_state == state_finished) + if (m_unallocated_slots.empty() + && m_free_slots.empty() + && m_state == state_finished) { TORRENT_ASSERT(m_storage_mode != storage_mode_compact); } diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index d31513166..ee7d4cc80 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -39,7 +39,37 @@ void udp_socket::send(udp::endpoint const& ep, char const* p, int len, asio::err void udp_socket::on_read(udp::socket* s, asio::error_code const& e, std::size_t bytes_transferred) { - if (e) return; + if (e) + { +#ifndef BOOST_NO_EXCEPTIONS + try { +#endif + if (s == &m_ipv4_sock) + m_callback(e, m_v4_ep, 0, 0); + else + m_callback(e, m_v6_ep, 0, 0); +#ifndef BOOST_NO_EXCEPTIONS + } catch(std::exception&) {} +#endif + + // don't stop listening on recoverable errors + if (e != asio::error::host_unreachable + && e != asio::error::fault + && e != asio::error::connection_reset + && e != asio::error::connection_refused + && e != asio::error::connection_aborted + && e != asio::error::message_size) + return; + + if (s == &m_ipv4_sock) + s->async_receive_from(asio::buffer(m_v4_buf, sizeof(m_v4_buf)) + , m_v4_ep, boost::bind(&udp_socket::on_read, this, s, _1, _2)); + else + s->async_receive_from(asio::buffer(m_v6_buf, sizeof(m_v6_buf)) + , m_v6_ep, boost::bind(&udp_socket::on_read, this, s, _1, _2)); + + return; + } if (!m_callback) return; if (s == &m_ipv4_sock) @@ -49,9 +79,9 @@ void udp_socket::on_read(udp::socket* s, asio::error_code const& e, std::size_t #endif if (m_tunnel_packets && m_v4_ep == m_proxy_addr) - unwrap(m_v4_buf, bytes_transferred); + unwrap(e, m_v4_buf, bytes_transferred); else - m_callback(m_v4_ep, m_v4_buf, bytes_transferred); + m_callback(e, m_v4_ep, m_v4_buf, bytes_transferred); #ifndef BOOST_NO_EXCEPTIONS } catch(std::exception&) {} @@ -66,9 +96,9 @@ void udp_socket::on_read(udp::socket* s, asio::error_code const& e, std::size_t #endif if (m_tunnel_packets && m_v6_ep == m_proxy_addr) - unwrap(m_v6_buf, bytes_transferred); + unwrap(e, m_v6_buf, bytes_transferred); else - m_callback(m_v6_ep, m_v6_buf, bytes_transferred); + m_callback(e, m_v6_ep, m_v6_buf, bytes_transferred); #ifndef BOOST_NO_EXCEPTIONS } catch(std::exception&) {} @@ -102,7 +132,7 @@ void udp_socket::wrap(udp::endpoint const& ep, char const* p, int len, asio::err } // unwrap the UDP packet from the SOCKS5 header -void udp_socket::unwrap(char const* buf, int size) +void udp_socket::unwrap(asio::error_code const& e, char const* buf, int size) { using namespace libtorrent::detail; @@ -128,7 +158,6 @@ void udp_socket::unwrap(char const* buf, int size) { // IPv6 TORRENT_ASSERT(false && "not supported yet"); - } else { @@ -136,7 +165,7 @@ void udp_socket::unwrap(char const* buf, int size) return; } - m_callback(sender, p, size - (p - buf)); + m_callback(e, sender, p, size - (p - buf)); } void udp_socket::close() diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index 62066ec0e..fecf6bac1 100755 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -84,7 +84,7 @@ namespace libtorrent : tracker_connection(man, req, ios, bind_infc, c) , m_man(man) , m_name_lookup(ios) - , m_socket(ios, boost::bind(&udp_tracker_connection::on_receive, this, _1, _2, _3), cc) + , m_socket(ios, boost::bind(&udp_tracker_connection::on_receive, this, _1, _2, _3, _4), cc) , m_transaction_id(0) , m_connection_id(0) , m_settings(stn) @@ -185,7 +185,8 @@ namespace libtorrent tracker_connection::close(); } - void udp_tracker_connection::on_receive(udp::endpoint const& ep, char const* buf, int size) + void udp_tracker_connection::on_receive(asio::error_code const& e + , udp::endpoint const& ep, char const* buf, int size) { // ignore resposes before we've sent any requests if (m_state == action_error) return; @@ -194,6 +195,8 @@ namespace libtorrent // ignore packet not sent from the tracker if (m_target != ep) return; + + if (e) fail(-1, e.message().c_str()); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING boost::shared_ptr cb = requester();