diff --git a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp index 7b4a9e71f..b5ecb21b3 100644 --- a/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp +++ b/libtorrent/include/libtorrent/kademlia/dht_tracker.hpp @@ -71,7 +71,8 @@ namespace libtorrent { namespace dht { friend void intrusive_ptr_add_ref(dht_tracker const*); friend void intrusive_ptr_release(dht_tracker const*); - dht_tracker(udp_socket& sock, dht_settings const& settings); + dht_tracker(udp_socket& sock, dht_settings const& settings + , entry const* state); void start(entry const& bootstrap); void stop(); diff --git a/libtorrent/include/libtorrent/kademlia/node.hpp b/libtorrent/include/libtorrent/kademlia/node.hpp index 8b59e0ce8..594a68e9f 100644 --- a/libtorrent/include/libtorrent/kademlia/node.hpp +++ b/libtorrent/include/libtorrent/kademlia/node.hpp @@ -161,7 +161,7 @@ class node_impl : boost::noncopyable typedef std::map table_t; public: node_impl(boost::function const& f - , dht_settings const& settings); + , dht_settings const& settings, boost::optional nid); virtual ~node_impl() {} @@ -186,7 +186,6 @@ public: typedef table_t::iterator data_iterator; - void set_node_id(node_id const& nid) { m_id = nid; } node_id const& nid() const { return m_id; } boost::tuple size() const{ return m_table.size(); } diff --git a/libtorrent/include/libtorrent/session_settings.hpp b/libtorrent/include/libtorrent/session_settings.hpp index b17ac01ff..d7ec48591 100644 --- a/libtorrent/include/libtorrent/session_settings.hpp +++ b/libtorrent/include/libtorrent/session_settings.hpp @@ -73,9 +73,9 @@ namespace libtorrent // uses username and password http_pw }; - + proxy_type type; - + }; struct TORRENT_EXPORT session_settings @@ -153,7 +153,7 @@ namespace libtorrent // the number of seconds to wait until giving up on a // tracker request if it hasn't finished int tracker_completion_timeout; - + // the number of seconds where no data is received // from the tracker until it should be considered // as timed out @@ -183,7 +183,7 @@ namespace libtorrent // all the pieces. i.e. the actual number of requests // depends on the download rate and this number. float request_queue_time; - + // the number of outstanding block requests a peer is // allowed to queue up in the client. If a peer sends // more requests than this (before the first one has @@ -191,7 +191,7 @@ namespace libtorrent // the higher this is, the faster upload speeds the // client can get to a single peer. int max_allowed_in_request_queue; - + // the maximum number of outstanding requests to // send to a peer. This limit takes precedence over // request_queue_time. @@ -204,23 +204,23 @@ namespace libtorrent // doing localized accesses and also to make it easier // to identify bad peers if a piece fails the hash check. int whole_pieces_threshold; - + // the number of seconds to wait for any activity on // the peer wire before closing the connectiong due // to time out. int peer_timeout; - + // same as peer_timeout, but only applies to url-seeds. // this is usually set lower, because web servers are // expected to be more reliable. int urlseed_timeout; - + // controls the pipelining size of url-seeds int urlseed_pipeline_size; // time to wait until a new retry takes place int urlseed_wait_retry; - + // sets the upper limit on the total number of files this // session will keep open. The reason why files are // left open at all is that some anti virus software @@ -234,7 +234,7 @@ namespace libtorrent // number of connections and the number of files // limits so their sum is slightly below it. int file_pool_size; - + // false to not allow multiple connections from the same // IP address. true will allow it. bool allow_multiple_connections_per_ip; @@ -242,7 +242,7 @@ namespace libtorrent // the number of times we can fail to connect to a peer // before we stop retrying it. int max_failcount; - + // the number of seconds to wait to reconnect to a peer. // this time is multiplied with the failcount. int min_reconnect_time; @@ -391,7 +391,7 @@ namespace libtorrent // the number of seconds in between recalculating which // torrents to activate and which ones to queue int auto_manage_interval; - + // when a seeding torrent reaches eaither the share ratio // (bytes up / bytes down) or the seed time ratio // (seconds as seed / seconds as downloader) or the seed @@ -461,7 +461,7 @@ namespace libtorrent , service_port(0) , max_fail_count(20) {} - + // the maximum number of peers to send in a // reply to get_peers int max_peers_reply; @@ -469,11 +469,11 @@ namespace libtorrent // the number of simultanous "connections" when // searching the DHT. int search_branching; - + // the listen port for the dht. This is a UDP port. // zero means use the same as the tcp interface int service_port; - + // the maximum number of times a node can fail // in a row before it is removed from the table. int max_fail_count; @@ -501,7 +501,7 @@ namespace libtorrent enum enc_level { plaintext, // use only plaintext encryption - rc4, // use only rc4 encryption + rc4, // use only rc4 encryption both // allow both }; diff --git a/libtorrent/src/disk_io_thread.cpp b/libtorrent/src/disk_io_thread.cpp index 0635a60b5..ab0fa2f74 100644 --- a/libtorrent/src/disk_io_thread.cpp +++ b/libtorrent/src/disk_io_thread.cpp @@ -88,6 +88,9 @@ namespace libtorrent l.unlock(); m_disk_io_thread.join(); + l.lock(); + TORRENT_ASSERT(m_abort == true); + m_jobs.clear(); } void disk_io_thread::get_cache_info(sha1_hash const& ih, std::vector& ret) const diff --git a/libtorrent/src/kademlia/dht_tracker.cpp b/libtorrent/src/kademlia/dht_tracker.cpp index 74a0fd132..71750d700 100644 --- a/libtorrent/src/kademlia/dht_tracker.cpp +++ b/libtorrent/src/kademlia/dht_tracker.cpp @@ -127,10 +127,20 @@ namespace libtorrent { namespace dht TORRENT_DEFINE_LOG(dht_tracker) #endif + boost::optional extract_node_id(entry const* e) + { + if (e == 0 || e->type() != entry::dictionary_t) return boost::optional(); + entry const* nid = e->find_key("node-id"); + if (nid == 0 || nid->type() != entry::string_t || nid->string().length() != 20) + return boost::optional(); + return boost::optional(node_id(nid->string().c_str())); + } + // class that puts the networking and the kademlia node in a single // unit and connecting them together. - dht_tracker::dht_tracker(udp_socket& sock, dht_settings const& settings) - : m_dht(bind(&dht_tracker::send_packet, this, _1), settings) + dht_tracker::dht_tracker(udp_socket& sock, dht_settings const& settings + , entry const* state) + : m_dht(bind(&dht_tracker::send_packet, this, _1), settings, extract_node_id(state)) , m_sock(sock) , m_last_new_key(time_now() - minutes(key_refresh)) , m_timer(sock.get_io_service()) @@ -183,12 +193,6 @@ namespace libtorrent { namespace dht if (entry const* nodes = bootstrap.find_key("nodes")) read_endpoint_list(nodes, initial_nodes); } catch (std::exception&) {} - - entry const* nid = bootstrap.find_key("node-id"); - if (nid - && nid->type() == entry::string_t - && nid->string().length() == 40) - m_dht.set_node_id(boost::lexical_cast(nid->string())); } error_code ec; diff --git a/libtorrent/src/kademlia/find_data.cpp b/libtorrent/src/kademlia/find_data.cpp index 8da689d68..5d5b79724 100644 --- a/libtorrent/src/kademlia/find_data.cpp +++ b/libtorrent/src/kademlia/find_data.cpp @@ -139,7 +139,6 @@ void find_data::initiate( , done_callback const& callback ) { - std::cerr << "find_data::initiate, key: " << target << "\n"; new find_data(target, branch_factor, max_results, table, rpc, callback); } diff --git a/libtorrent/src/kademlia/node.cpp b/libtorrent/src/kademlia/node.cpp index 258cb3b87..42db5a950 100644 --- a/libtorrent/src/kademlia/node.cpp +++ b/libtorrent/src/kademlia/node.cpp @@ -91,9 +91,10 @@ void purge_peers(std::set& peers) void nop() {} node_impl::node_impl(boost::function const& f - , dht_settings const& settings) + , dht_settings const& settings + , boost::optional nid) : m_settings(settings) - , m_id(generate_id()) + , m_id(nid ? *nid : generate_id()) , m_table(m_id, 8, settings) , m_rpc(bind(&node_impl::incoming_request, this, _1) , m_id, m_table, f) diff --git a/libtorrent/src/lazy_bdecode.cpp b/libtorrent/src/lazy_bdecode.cpp index 6c469b64a..bc0beaab4 100644 --- a/libtorrent/src/lazy_bdecode.cpp +++ b/libtorrent/src/lazy_bdecode.cpp @@ -37,12 +37,9 @@ POSSIBILITY OF SUCH DAMAGE. namespace { - enum - { - lazy_entry_grow_factor = 3, - lazy_entry_dict_init = 30, - lazy_entry_list_init = 50 - }; + const float lazy_entry_grow_factor = 1.5f; + const int lazy_entry_dict_init = 5; + const int lazy_entry_list_init = 5; } namespace libtorrent diff --git a/libtorrent/src/lsd.cpp b/libtorrent/src/lsd.cpp index 2d4e8b7da..495b0efd1 100644 --- a/libtorrent/src/lsd.cpp +++ b/libtorrent/src/lsd.cpp @@ -60,11 +60,13 @@ namespace libtorrent address guess_local_address(io_service&); } +static error_code ec; + lsd::lsd(io_service& ios, address const& listen_interface , peer_callback_t const& cb) : m_callback(cb) , m_retry_count(1) - , m_socket(ios, udp::endpoint(address_v4::from_string("239.192.152.143"), 6771) + , m_socket(ios, udp::endpoint(address_v4::from_string("239.192.152.143", ec), 6771) , bind(&lsd::on_announce, self(), _1, _2, _3)) , m_broadcast_timer(ios) , m_disabled(false) diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index e76c6a3e3..dc5116df2 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -2920,8 +2920,7 @@ namespace libtorrent // the minimum number of requests is 2 and the maximum is 48 // the block size doesn't have to be 16. So we first query the // torrent for it - const int block_size = m_request_large_blocks - ? t->torrent_file().piece_length() : t->block_size(); + const int block_size = t->block_size(); TORRENT_ASSERT(block_size > 0); if (m_snubbed) diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index a43d5bead..561b0506e 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -157,7 +157,6 @@ namespace aux { #endif , m_tracker_manager(m_settings, m_tracker_proxy) , m_listen_port_retries(listen_port_range.second - listen_port_range.first) - , m_listen_interface(address::from_string(listen_interface), listen_port_range.first) , m_abort(false) , m_paused(false) , m_max_uploads(8) @@ -189,6 +188,10 @@ namespace aux { , m_total_failed_bytes(0) , m_total_redundant_bytes(0) { + error_code ec; + m_listen_interface = tcp::endpoint(address::from_string(listen_interface, ec), listen_port_range.first); + TORRENT_ASSERT(!ec); + m_tcp_mapping[0] = -1; m_tcp_mapping[1] = -1; m_udp_mapping[0] = -1; @@ -268,7 +271,6 @@ namespace aux { *i = printable[rand() % (sizeof(printable)-1)]; } - error_code ec; m_timer.expires_from_now(seconds(1), ec); m_timer.async_wait( bind(&session_impl::second_tick, this, _1)); @@ -1611,23 +1613,17 @@ namespace aux { do { -#ifndef BOOST_NO_EXCEPTIONS - try - { -#endif - m_io_service.run(); - TORRENT_ASSERT(m_abort == true); -#ifndef BOOST_NO_EXCEPTIONS - } - catch (std::exception& e) + error_code ec; + m_io_service.run(ec); + TORRENT_ASSERT(m_abort == true); + if (ec) { #ifndef NDEBUG - std::cerr << e.what() << "\n"; - std::string err = e.what(); + std::cerr << ec.message() << "\n"; + std::string err = ec.message(); #endif TORRENT_ASSERT(false); } -#endif } while (!m_abort); @@ -1875,7 +1871,18 @@ namespace aux { tcp::endpoint new_interface; if (net_interface && std::strlen(net_interface) > 0) - new_interface = tcp::endpoint(address::from_string(net_interface), port_range.first); + { + error_code ec; + new_interface = tcp::endpoint(address::from_string(net_interface, ec), port_range.first); + if (ec) + { +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING + (*m_logger) << time_now_string() << "listen_on: " << net_interface + << " failed: " << ec.message() << "\n"; +#endif + return false; + } + } else new_interface = tcp::endpoint(address_v4::any(), port_range.first); @@ -2083,7 +2090,7 @@ namespace aux { , m_dht_settings.service_port , m_dht_settings.service_port); } - m_dht = new dht::dht_tracker(m_dht_socket, m_dht_settings); + m_dht = new dht::dht_tracker(m_dht_socket, m_dht_settings, &startup_state); if (!m_dht_socket.is_open() || m_dht_socket.local_port() != m_dht_settings.service_port) { m_dht_socket.bind(m_dht_settings.service_port); diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index 5caa3943a..de4c9bcf7 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -550,7 +550,9 @@ namespace libtorrent std::string ip = e->dict_find_string_value("ip"); int port = e->dict_find_int_value("port"); if (ip.empty() || port == 0) continue; - tcp::endpoint a(address::from_string(ip), (unsigned short)port); + error_code ec; + tcp::endpoint a(address::from_string(ip, ec), (unsigned short)port); + if (ec) continue; m_policy.peer_from_tracker(a, id, peer_info::resume_data, 0); } } @@ -567,7 +569,9 @@ namespace libtorrent std::string ip = e->dict_find_string_value("ip"); int port = e->dict_find_int_value("port"); if (ip.empty() || port == 0) continue; - tcp::endpoint a(address::from_string(ip), (unsigned short)port); + error_code ec; + tcp::endpoint a(address::from_string(ip, ec), (unsigned short)port); + if (ec) continue; policy::peer* p = m_policy.peer_from_tracker(a, id, peer_info::resume_data, 0); if (p) p->banned = true; } @@ -769,7 +773,10 @@ namespace libtorrent { INVARIANT_CHECK; - m_net_interface = tcp::endpoint(address::from_string(net_interface), 0); + error_code ec; + address a(address::from_string(net_interface, ec)); + if (ec) return; + m_net_interface = tcp::endpoint(a, 0); } void torrent::on_tracker_announce_disp(boost::weak_ptr p diff --git a/libtorrent/src/upnp.cpp b/libtorrent/src/upnp.cpp index dd90326cf..802b55191 100644 --- a/libtorrent/src/upnp.cpp +++ b/libtorrent/src/upnp.cpp @@ -59,6 +59,8 @@ POSSIBILITY OF SUCH DAMAGE. using boost::bind; using namespace libtorrent; +static error_code ec; + upnp::upnp(io_service& ios, connection_queue& cc , address const& listen_interface, std::string const& user_agent , portmap_callback_t const& cb, bool ignore_nonrouters, void* state) @@ -66,7 +68,7 @@ upnp::upnp(io_service& ios, connection_queue& cc , m_callback(cb) , m_retry_count(0) , m_io_service(ios) - , m_socket(ios, udp::endpoint(address_v4::from_string("239.255.255.250"), 1900) + , m_socket(ios, udp::endpoint(address_v4::from_string("239.255.255.250", ec), 1900) , bind(&upnp::on_reply, self(), _1, _2, _3), false) , m_broadcast_timer(ios) , m_refresh_timer(ios) @@ -114,7 +116,7 @@ void upnp::discover_device() void upnp::discover_device_impl() { - const char msearch[] = + const char msearch[] = "M-SEARCH * HTTP/1.1\r\n" "HOST: 239.255.255.250:1900\r\n" "ST:upnp:rootdevice\r\n" @@ -220,7 +222,7 @@ void upnp::delete_mapping(int mapping) #endif if (m.protocol == none) return; - + for (std::set::iterator i = m_devices.begin() , end(m_devices.end()); i != end; ++i) { @@ -257,7 +259,7 @@ void upnp::resend_request(error_code const& e) disable("no UPnP router found"); return; } - + for (std::set::iterator i = m_devices.begin() , end(m_devices.end()); i != end; ++i) { @@ -349,7 +351,7 @@ void upnp::on_reply(udp::endpoint const& from, char* buffer } #endif return; - } + } std::vector routes = enum_routes(m_io_service, ec); if (m_ignore_non_routers && std::find_if(routes.begin(), routes.end() @@ -559,7 +561,7 @@ void upnp::post(upnp::rootdevice const& d, std::string const& soap TORRENT_ASSERT(d.upnp_connection); std::stringstream header; - + header << "POST " << d.path << " HTTP/1.0\r\n" "Host: " << d.hostname << ":" << d.port << "\r\n" "Content-Type: text/xml; charset=\"utf-8\"\r\n" @@ -572,7 +574,7 @@ void upnp::post(upnp::rootdevice const& d, std::string const& soap m_log << time_now_string() << " ==> sending: " << header.str() << std::endl; #endif - + } void upnp::create_port_mapping(http_connection& c, rootdevice& d, int i) @@ -590,11 +592,11 @@ void upnp::create_port_mapping(http_connection& c, rootdevice& d, int i) #endif return; } - + std::string soap_action = "AddPortMapping"; std::stringstream soap; - + soap << "\n" "" @@ -709,7 +711,7 @@ void upnp::delete_port_mapping(rootdevice& d, int i) } std::stringstream soap; - + std::string soap_action = "DeletePortMapping"; soap << "\n" @@ -721,7 +723,7 @@ void upnp::delete_port_mapping(rootdevice& d, int i) "" << d.mapping[i].external_port << "" "" << (d.mapping[i].protocol == udp ? "UDP" : "TCP") << ""; soap << ""; - + post(d, soap.str(), soap_action); } @@ -738,7 +740,7 @@ namespace dst.clear(); while (*src) dst.push_back(tolower(*src++)); } - + bool string_equal_nocase(char const* lhs, char const* rhs) { while (tolower(*lhs) == tolower(*rhs)) @@ -900,10 +902,7 @@ void upnp::on_upnp_xml(error_code const& e return; } } - - if (s.url_base.empty()) d.control_url = s.control_url; - else d.control_url = s.url_base + s.control_url; - + if (s.url_base.empty()) d.control_url = s.control_url; else d.control_url = s.url_base + s.control_url; @@ -952,7 +951,7 @@ void upnp::disable(char const* msg) i->protocol = none; m_callback(i - m_mappings.begin(), 0, msg); } - + m_devices.clear(); error_code ec; m_broadcast_timer.cancel(ec); @@ -969,7 +968,7 @@ namespace bool exit; int error_code; }; - + void find_error_code(int type, char const* string, error_code_parse_state& state) { if (state.exit) return; @@ -992,7 +991,7 @@ namespace int code; char const* msg; }; - + error_code_t error_codes[] = { {402, "Invalid Arguments"} @@ -1034,9 +1033,9 @@ void upnp::on_upnp_map_response(error_code const& e d.disabled = true; return; } - + if (m_closing) return; - + // error code response may look like this: // @@ -1078,7 +1077,7 @@ void upnp::on_upnp_map_response(error_code const& e << " <== got error message: " << s.error_code << std::endl; } #endif - + mapping_t& m = d.mapping[mapping]; if (s.error_code == 725)