diff --git a/libtorrent/include/libtorrent/session_settings.hpp b/libtorrent/include/libtorrent/session_settings.hpp index e71efc7e3..d7ec48591 100644 --- a/libtorrent/include/libtorrent/session_settings.hpp +++ b/libtorrent/include/libtorrent/session_settings.hpp @@ -118,7 +118,7 @@ namespace libtorrent , use_dht_as_fallback(false) #endif , free_torrent_hashes(true) - , upnp_ignore_nonrouters(true) + , upnp_ignore_nonrouters(false) , send_buffer_watermark(80 * 1024) , auto_upload_slots(true) , use_parole_mode(true) diff --git a/libtorrent/src/bt_peer_connection.cpp b/libtorrent/src/bt_peer_connection.cpp index f09628f07..3e682ee92 100755 --- a/libtorrent/src/bt_peer_connection.cpp +++ b/libtorrent/src/bt_peer_connection.cpp @@ -1288,6 +1288,7 @@ namespace libtorrent { t->get_policy().update_peer_port(listen_port , peer_info_struct(), peer_info::incoming); + if (is_disconnecting()) return; } // there should be a version too // but where do we put that info? diff --git a/libtorrent/src/connection_queue.cpp b/libtorrent/src/connection_queue.cpp index d5228a66a..560f31e59 100644 --- a/libtorrent/src/connection_queue.cpp +++ b/libtorrent/src/connection_queue.cpp @@ -119,19 +119,16 @@ namespace libtorrent m_timer.cancel(ec); m_abort = true; - // make a copy of the list to go through, so - // that connections removing themseleves won't - // interfere with the iteration - std::list closing_entries = m_queue; - - // we don't want to call the timeout callback while we're locked - // since that is a recepie for dead-locks - l.unlock(); - - for (std::list::iterator i = closing_entries.begin() - , end(closing_entries.end()); i != end; ++i) + while (!m_queue.empty()) { - try { i->on_timeout(); } catch (std::exception&) {} + // we don't want to call the timeout callback while we're locked + // since that is a recepie for dead-locks + entry e = m_queue.front(); + m_queue.pop_front(); + if (e.connecting) --m_num_connecting; + l.unlock(); + try { e.on_timeout(); } catch (std::exception&) {} + l.lock(); } } diff --git a/libtorrent/src/http_connection.cpp b/libtorrent/src/http_connection.cpp index cd4f8c4c1..ef06533f1 100644 --- a/libtorrent/src/http_connection.cpp +++ b/libtorrent/src/http_connection.cpp @@ -199,7 +199,6 @@ void http_connection::start(std::string const& hostname, std::string const& port void http_connection::on_connect_timeout() { - TORRENT_ASSERT(m_connection_ticket >= 0); if (m_connection_ticket > -1) m_cc.done(m_connection_ticket); m_connection_ticket = -1; diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index d2790cdf0..e76c6a3e3 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -1397,13 +1397,19 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); TORRENT_ASSERT(t); if (m_upload_only && t->is_finished()) + { disconnect("seed to seed"); + return; + } if (m_upload_only && !m_interesting && m_bitfield_received && t->are_files_checked()) + { disconnect("uninteresting upload-only peer"); + return; + } } // ----------------------------- @@ -2531,7 +2537,7 @@ namespace libtorrent m_torrent.reset(); } -#ifndef NDEBUG +#if !defined NDEBUG && defined TORRENT_EXPENSIVE_INVARIANT_CHECKS // since this connection doesn't have a torrent reference // no torrent should have a reference to this connection either for (aux::session_impl::torrent_map::const_iterator i = m_ses.m_torrents.begin() diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index adc163f50..a43d5bead 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -498,7 +498,7 @@ namespace aux { m_half_open.close(); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " connection queue: " << m_half_open.size() << std::endl; + (*m_logger) << time_now_string() << " connection queue: " << m_half_open.size() << "\n"; #endif // abort all connections @@ -512,7 +512,7 @@ namespace aux { } #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " connection queue: " << m_half_open.size() << std::endl; + (*m_logger) << time_now_string() << " connection queue: " << m_half_open.size() << "\n"; #endif TORRENT_ASSERT(m_half_open.size() == 0); diff --git a/libtorrent/src/upnp.cpp b/libtorrent/src/upnp.cpp index 390d49450..bc6529f2d 100644 --- a/libtorrent/src/upnp.cpp +++ b/libtorrent/src/upnp.cpp @@ -753,14 +753,17 @@ namespace struct parse_state { - parse_state(): found_service(false) {} + parse_state(): in_service(false) {} void reset(char const* st) { - found_service = false; + in_service = false; service_type = st; tag_stack.clear(); + control_url.clear(); + model.clear(); + url_base.clear(); } - bool found_service; + bool in_service; std::list tag_stack; std::string control_url; char const* service_type; @@ -791,22 +794,26 @@ void find_control_url(int type, char const* string, parse_state& state) else if (type == xml_end_tag) { if (!state.tag_stack.empty()) + { + if (state.in_service && state.tag_stack.back() == "service") + state.in_service = false; state.tag_stack.pop_back(); + } } else if (type == xml_string) { if (state.tag_stack.empty()) return; // std::cout << " " << string << std::endl; - if (!state.found_service && state.top_tags("service", "servicetype")) + if (!state.in_service && state.top_tags("service", "servicetype")) { if (string_equal_nocase(string, state.service_type)) - state.found_service = true; + state.in_service = true; } - else if (state.found_service && state.top_tags("service", "controlurl")) + else if (state.in_service && state.top_tags("service", "controlurl")) { state.control_url = string; } - else if (state.tag_stack.back() == "modelname") + else if (state.model.empty() && state.top_tags("device", "modelname")) { state.model = string; } @@ -865,7 +872,7 @@ void upnp::on_upnp_xml(error_code const& e s.reset("urn:schemas-upnp-org:service:WANIPConnection:1"); xml_parse((char*)p.get_body().begin, (char*)p.get_body().end , bind(&find_control_url, _1, _2, boost::ref(s))); - if (s.found_service) + if (!s.control_url.empty()) { d.service_namespace = s.service_type; if (!s.model.empty()) m_model = s.model; @@ -877,7 +884,7 @@ void upnp::on_upnp_xml(error_code const& e s.reset("urn:schemas-upnp-org:service:WANPPPConnection:1"); xml_parse((char*)p.get_body().begin, (char*)p.get_body().end , bind(&find_control_url, _1, _2, boost::ref(s))); - if (s.found_service) + if (!s.control_url.empty()) { d.service_namespace = s.service_type; if (!s.model.empty()) m_model = s.model; @@ -894,6 +901,9 @@ void upnp::on_upnp_xml(error_code const& e } } + if (s.url_base.empty()) d.control_url = s.control_url; + else d.control_url = s.url_base + s.control_url; + std::string protocol; std::string auth; char const* error; @@ -911,9 +921,6 @@ void upnp::on_upnp_xml(error_code const& e << " urlbase: " << s.url_base << " namespace: " << d.service_namespace << std::endl; #endif - if (s.url_base.empty()) d.control_url = s.control_url; - else d.control_url = s.url_base + s.control_url; - boost::tie(protocol, auth, d.hostname, d.port, d.path, error) = parse_url_components(d.control_url);