diff --git a/Makefile.am b/Makefile.am index 2fe277cdb..1da76ab11 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,6 +39,8 @@ DOCS_IMAGES = \ docs/troubleshooting_thumb.png \ docs/hacking.diagram \ docs/hacking.png \ + docs/disk_cache.diagram \ + docs/disk_cache.png \ docs/utp_stack.diagram \ docs/utp_stack.png \ docs/style.css \ @@ -48,7 +50,7 @@ DOCS_IMAGES = \ docs/img/blue_top.png \ docs/img/dotline.gif \ docs/img/minus.gif \ - docs/img/orange.png + docs/img/orange.png \ DOCS_PAGES = \ docs/building.html \ diff --git a/docs/contributing.html b/docs/contributing.html index 5e33ebfb8..d72c9bad0 100644 --- a/docs/contributing.html +++ b/docs/contributing.html @@ -61,7 +61,7 @@ enumerated on this page, please contact This is not just limited to finding bugs and ways to reproduce crashes, but also sub-optimal behavior is certain scenarios and finding ways to reproduce those. Please -report any issue to the bug tracker at google code.

+report any issue to the bug tracker at github.

New features that need testing are streaming (set_piece_deadline()), the different choking algorithms (especially the new BitTyrant choker), the disk cache options (such as explicit_cache).

diff --git a/docs/contributing.rst b/docs/contributing.rst index 0634c0d82..cb93797c2 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -21,13 +21,13 @@ enumerated on this page, please contact arvid@libtorrent.org or the `mailing lis 1. Testing This is not just limited to finding bugs and ways to reproduce crashes, but also sub-optimal behavior is certain scenarios and finding ways to reproduce those. Please - report any issue to the bug tracker at `google code`_. + report any issue to the bug tracker at `github`_. New features that need testing are streaming (``set_piece_deadline()``), the different choking algorithms (especially the new BitTyrant choker), the disk cache options (such as ``explicit_cache``). -.. _`google code`: http://code.google.com/p/libtorrent/issues/entry +.. _`github`: https://github.com/arvidn/libtorrent/issues 2. Documentation Finding typos or outdated sections in the documentation. Contributing documentation diff --git a/docs/disk_cache.diagram b/docs/disk_cache.diagram new file mode 100644 index 000000000..da666fbee --- /dev/null +++ b/docs/disk_cache.diagram @@ -0,0 +1,12 @@ + <---- "recently" "frequently" ---> + "used" "used" + + L1 ghost L1 L2 L2 ghost + AAAAAAAAFFFFFFFF FFFFFFFFAAAAAAAA + + cache size + <---------------> + + 2x cache size + <-------------------------------> + diff --git a/docs/hacking.diagram b/docs/hacking.diagram index db00a06d6..02d64968d 100644 --- a/docs/hacking.diagram +++ b/docs/hacking.diagram @@ -1,26 +1,30 @@ -+--------------+ pimpl +--------------+ -| cGRE session +----------->| session_impl | -+--------------+ +------+-----+-+ - m_torrents[] | | -+---------------------+ | | -| cGRE torrent_handle +-------+ | | -+---------------------+ weak | | | - | | | m_connections[] - | | +---+-------+ - | | | | - m_picker v v | v peers we are connected to - +--------------+ +--------++ +-----------------+ - | piece_picker |<---+-+ torrent ++ +--+ peer_connection ++ - +--------------+ | ++--------+| | ++----------------+| - m_torrent_file | +---------+ | +-----------------+ - +-------------------+ | | - | cGRE torrent_info |<---+ | m_socket - +-------------------+ | | +--------------------------+ - m_peer_list | +------+->| socket_type (variant) | - +-----------+ | | | (TCP/uTP/SSL/socks5/...) | - | peer_list |<---------+ | +--------------------------+ - +---------+-+ v - list of all | m_peers[] +--------------+ - peers we +-------------->| torrent_peer ++ contains contact information - know of ++-------------+| for peers we're not necessarily - +--------------+ connected to ++--------------+ "pimpl" +----------------+ +| "session" +--------------------------->| "session_impl" | ++--------------+ +------+-----+---+ + "m_torrents[]" | | ++---------------------+ | | +| "torrent_handle" +--------+ | | ++---------------------+ "weak" | +--------------+ | + | | | "m_connections[]" + | | +-------------+----+ + | | | | + "m_picker" v v | v "peers we are connected to" + +----------------+ +----------++ +-------------------+ + | "piece_picker" |<---+-+ "torrent" ++ +--+ "peer_connection" ++ + +----------------+ | ++----------+| | ++------------------+| + "m_torrent_file" | +-----------+ | +-------------------+ + +-------------------+ | | + | "torrent_info" |<---+ | "m_socket" + +-------------------+ | | +----------------------------+ + | +->| "socket_type (variant)" | + "m_peer_list" v | | "(TCP/uTP/SSL/socks5/...)" | + +--------------+ | +----------------------------+ + | "peer_list" | | + +------------+-+ | "m_peer_info" + "list of all" | "m_peers[]" | "contains contact information" + "peers we" | | "for peers we're not necessarily" + "know of" | v "connected to" + | +----------------+ + +---->| "torrent_peer" ++ + ++---------------+| + +----------------+ diff --git a/docs/hacking.rst b/docs/hacking.rst index bdb626c4e..7a1de5d93 100644 --- a/docs/hacking.rst +++ b/docs/hacking.rst @@ -136,17 +136,9 @@ The disk cache implements *ARC*, Adaptive Replacement Cache. This consists of a 5. volatile read blocks 6. write cache (blocks waiting to be flushed to disk) -.. parsed-literal:: - - <--- recently used frequently used ---> - +--------------+--------------+ +--------------+--------------+ - | L1 **ghost** | L1 | | L2 | L2 **ghost** | - +--------------+--------------+ +--------------+--------------+ - - <---------- cache_size ----------> - - <---------------------- 2 x cache_size ------------------------> +.. image:: disk_cache.png + These LRUs are stored in ``block_cache`` in an array ``m_lru``. The cache algorithm works like this:: diff --git a/docs/makefile b/docs/makefile index 9a02fd262..ff5b5bdc8 100644 --- a/docs/makefile +++ b/docs/makefile @@ -49,12 +49,13 @@ TARGETS = index \ FIGURES = \ read_disk_buffers \ write_disk_buffers \ - troubleshooting \ hacking \ utp_stack \ - storage + storage \ + disk_cache \ + troubleshooting -html: $(TARGETS:=.html) $(FIGURES:=.png) todo.html +html: $(TARGETS:=.html) $(FIGURES:=.png) todo.html pdf: $(TARGETS:=.pdf) $(FIGURES:=.eps) @@ -71,11 +72,11 @@ stats_counters.rst: ../src/session_stats.cpp ../include/libtorrent/performance_c manual.rst: stats_counters.rst touch manual.rst -troubleshooting_thumb.png: troubleshooting.png - convert troubleshooting.png -resize 800x800 troubleshooting_thumb.png -ifneq ($(STAGE),) - cp $@ $(WEB_PATH)/$@ -endif +#troubleshooting_thumb.png: troubleshooting.png +# convert troubleshooting.png -resize 800x800 troubleshooting_thumb.png +#ifneq ($(STAGE),) +# cp $@ $(WEB_PATH)/$@ +#endif todo.html:gen_todo.py ../src/*.cpp ../include/libtorrent/*.hpp python gen_todo.py @@ -111,11 +112,11 @@ ifneq ($(STAGE),) endif %.png:%.diagram - ditaa -E $? $@ + aafigure -o $@ $? ifneq ($(STAGE),) cp $@ $(WEB_PATH)/$@ endif clean: - rm -f $(TARGETS:=.html) $(TARGETS:=.pdf) settings.rst todo.html reference*.html reference*.rst + rm -f $(TARGETS:=.html) $(TARGETS:=.pdf) $(FIGURES:=.png) $(FIGURES:=.eps) settings.rst todo.html reference*.html reference*.rst diff --git a/docs/read_disk_buffers.diagram b/docs/read_disk_buffers.diagram index 6ffa96479..1d04a25dd 100644 --- a/docs/read_disk_buffers.diagram +++ b/docs/read_disk_buffers.diagram @@ -1,16 +1,16 @@ - copy into peer's encrypt in place -+----------------+ send buffer +-------------+ (no copy) +-------------+ -| receive buffer +----------------->| send buffer +--=--------------->| encrypted | -| | | | | send buffer | -+----------------+ +-------------+ +------+------+ + "copy into peer's" "encrypt in place" ++------------------+ "send buffer" +---------------+ "(no copy)" +---------------+ +| "receive buffer" +----------------->| "send buffer" +------------------>| "encrypted" | +| | | | | "send buffer" | ++------------------+ +---------------+ +---------------+ ^ | - | read() from file write() to socket | - | (copy) (copy) | ----=----|---------------------------------=---------------------------------|--=---- - | kernel space | + | "read() from file" "write() to socket" | + | "(copy)" "user space" "(copy)" | +- - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + | "kernel space" | | v -+-------+-----------+ +---------------+ -| kernel page cache | | socket kernel | -| | | buffer | -+-------------------+ +---------------+ ++-------+-------------+ +-----------------+ +| "kernel page cache" | | "socket kernel" | +| | | "buffer" | ++---------------------+ +-----------------+ diff --git a/docs/storage.diagram b/docs/storage.diagram index 8f0618d7d..895607642 100644 --- a/docs/storage.diagram +++ b/docs/storage.diagram @@ -1,31 +1,31 @@ +--------------------------+ -| disk_io_thread | -| (manages piece cache) | +| "disk_io_thread" | +| "(manages piece cache)" | +--------------------------+ ^ | v +--------------------------+ -| piece_manager | -| (maps pieces to slots) | +| "piece_manager" | +| "(maps pieces to slots)" | +--------------------------+ ^ | - v customization point -/--------------------------\ +------------------+ -| storage |<---->| file_pool | -| cGRE | | open file cache | -| (maps slots to file and | +------------------+ -| offset. reads and writes | -| to disk) | +------------------+ -| |<-----+ file_storage | -\--------------------------/ | standard slot to | - ^ | file mapping | - | +------------------+ + v "customization point" +/----------------------------\ +-------------------+ +| "storage" |<---->| "file_pool" | +| | | "open file cache" | +| "(maps slots to file and" | +-------------------+ +| "offset. reads and writes" | +| "to disk)" | +--------------------+ +| |<-----+ "file_storage" | +\----------------------------/ | "standard slot to" | + ^ | "file mapping" | + | +--------------------+ v +--------------------------+ -| file | -| (file class reads and | -| writes files) | +| "file" | +| "(file class reads and" | +| "writes files)" | +--------------------------+ diff --git a/docs/todo.html b/docs/todo.html index 2dc6a39f8..d336fcaa2 100644 --- a/docs/todo.html +++ b/docs/todo.html @@ -74,7 +74,7 @@ does not support hard links.

../src/file.cpp:487

relevance 3../src/session_impl.cpp:2028port map SSL udp socket here

port map SSL udp socket here

../src/session_impl.cpp:2028

		udp::endpoint ssl_bind_if(m_listen_interface.address(), ssl_port);
+
relevance 3../src/session_impl.cpp:2030port map SSL udp socket here

port map SSL udp socket here

../src/session_impl.cpp:2030

		udp::endpoint ssl_bind_if(m_listen_interface.address(), ssl_port);
 
 		// if ssl port is 0, we don't want to listen on an SSL port
 		if (ssl_port != 0)
@@ -1483,7 +1483,9 @@ listen_interfaces list

../src/session_impl.cpp:1923

relevance 2../src/session_impl.cpp:2012use bind_to_device in udp_socket

use bind_to_device in udp_socket

../src/session_impl.cpp:2012

#endif
+
relevance 2../src/session_impl.cpp:2014use bind_to_device in udp_socket

use bind_to_device in udp_socket

../src/session_impl.cpp:2014

#endif
 			if (listen_port_retries > 0)
 			{
 				m_listen_interface.port(m_listen_interface.port() + 1);
@@ -1533,7 +1533,7 @@ listen_interfaces list

../src/session_impl.cpp:1923

relevance 2../src/session_impl.cpp:2032use bind_to_device in udp_socket

use bind_to_device in udp_socket

../src/session_impl.cpp:2032

		if (ssl_port != 0)
+
relevance 2../src/session_impl.cpp:2034use bind_to_device in udp_socket

use bind_to_device in udp_socket

../src/session_impl.cpp:2034

		if (ssl_port != 0)
 		{
 			m_ssl_udp_socket.bind(ssl_bind_if, ec);
 			if (ec)
@@ -1584,8 +1584,8 @@ listen_interfaces list

../src/session_impl.cpp:1923

relevance 2../src/session_impl.cpp:3511make a list for torrents that want to be announced on the DHT so we don't have to loop over all torrents, just to find the ones that want to announce

make a list for torrents that want to be announced on the DHT so we -don't have to loop over all torrents, just to find the ones that want to announce

../src/session_impl.cpp:3511

		if (!m_dht_torrents.empty())
+
relevance 2../src/session_impl.cpp:3513make a list for torrents that want to be announced on the DHT so we don't have to loop over all torrents, just to find the ones that want to announce

make a list for torrents that want to be announced on the DHT so we +don't have to loop over all torrents, just to find the ones that want to announce

../src/session_impl.cpp:3513

		if (!m_dht_torrents.empty())
 		{
 			boost::shared_ptr<torrent> t;
 			do
@@ -1636,9 +1636,9 @@ don't have to loop over all torrents, just to find the ones that want to announc
 		if (m_torrents.empty()) return;
 
 		if (m_next_lsd_torrent == m_torrents.end())
-
relevance 2../src/storage.cpp:941is this risky? The upper layer will assume we have the whole file. Perhaps we should verify that at least the size of the file is correct

is this risky? The upper layer will assume we have the +

relevance 2../src/storage.cpp:948is this risky? The upper layer will assume we have the whole file. Perhaps we should verify that at least the size of the file is correct

is this risky? The upper layer will assume we have the whole file. Perhaps we should verify that at least the size -of the file is correct

../src/storage.cpp:941

		if (links)
+of the file is correct

../src/storage.cpp:948

		if (links)
 		{
 			// if this is a mutable torrent, and we need to pick up some files
 			// from other torrents, do that now. Note that there is an inherent
@@ -1844,8 +1844,8 @@ first IP in this list and leave a comment here

../src/torrent.cpp:3366relevance 2../src/torrent.cpp:4885abort lookups this torrent has made via the session host resolver interface

abort lookups this torrent has made via the -session host resolver interface

../src/torrent.cpp:4885

		// files belonging to the torrents
+
relevance 2../src/torrent.cpp:4890abort lookups this torrent has made via the session host resolver interface

abort lookups this torrent has made via the +session host resolver interface

../src/torrent.cpp:4890

		// files belonging to the torrents
 		disconnect_all(errors::torrent_aborted, op_bittorrent);
 
 		// post a message to the main thread to destruct
@@ -1896,7 +1896,7 @@ session host resolver interface

../src/torrent.cpp:4885

relevance 2../src/torrent.cpp:5031the tracker login feature should probably be deprecated

the tracker login feature should probably be deprecated

../src/torrent.cpp:5031

				alerts().emplace_alert<file_renamed_alert>(get_handle()
+
relevance 2../src/torrent.cpp:5036the tracker login feature should probably be deprecated

the tracker login feature should probably be deprecated

../src/torrent.cpp:5036

				alerts().emplace_alert<file_renamed_alert>(get_handle()
 					, j->buffer.string, j->piece);
 			m_torrent_file->rename_file(j->piece, j->buffer.string);
 		}
@@ -1947,9 +1947,9 @@ session host resolver interface

../src/torrent.cpp:4885

relevance 2../src/torrent.cpp:8018if peer is a really good peer, maybe we shouldn't disconnect it perhaps this logic should be disabled if we have too many idle peers (with some definition of idle)

if peer is a really good peer, maybe we shouldn't disconnect it +

relevance 2../src/torrent.cpp:8023if peer is a really good peer, maybe we shouldn't disconnect it perhaps this logic should be disabled if we have too many idle peers (with some definition of idle)

if peer is a really good peer, maybe we shouldn't disconnect it perhaps this logic should be disabled if we have too many idle peers -(with some definition of idle)

../src/torrent.cpp:8018

#ifndef TORRENT_DISABLE_LOGGING
+(with some definition of idle)

../src/torrent.cpp:8023

#ifndef TORRENT_DISABLE_LOGGING
 		debug_log("incoming peer (%d)", int(m_connections.size()));
 #endif
 
@@ -2418,7 +2418,7 @@ peer_connection

../src/web_peer_connection.cpp:689

relevance 2../src/kademlia/dht_storage.cpp:106make this configurable in dht_settings

make this configurable in dht_settings

../src/kademlia/dht_storage.cpp:106

	// this is a group. It contains a set of group members
+
relevance 2../src/kademlia/dht_storage.cpp:110make this configurable in dht_settings

make this configurable in dht_settings

../src/kademlia/dht_storage.cpp:110

	// this is a group. It contains a set of group members
 	struct torrent_entry
 	{
 		std::string name;
@@ -2725,14 +2725,14 @@ boost::tuple<int, int, int> routing_table::size() const
 			else
 				new_replacement_bucket.push_back(*j);
 		}
-
relevance 2../include/libtorrent/alert_types.hpp:1427should the alert baseclass have this object instead?

should the alert baseclass have this object instead?

../include/libtorrent/alert_types.hpp:1427

	{
+
relevance 2../include/libtorrent/alert_types.hpp:1429should the alert baseclass have this object instead?

should the alert baseclass have this object instead?

../include/libtorrent/alert_types.hpp:1429

	{
 		// internal
 		portmap_log_alert(aux::stack_allocator& alloc, int t, const char* m);
 
 		TORRENT_DEFINE_ALERT(portmap_log_alert, 52)
 
 		static const int static_category = alert::port_mapping_log_notification;
-		virtual std::string message() const;
+		virtual std::string message() const TORRENT_OVERRIDE;
 
 		int map_type;
 
@@ -2766,7 +2766,7 @@ boost::tuple<int, int, int> routing_table::size() const
 
 		static const int static_category = alert::status_notification
 			| alert::error_notification;
-		virtual std::string message() const;
+		virtual std::string message() const TORRENT_OVERRIDE;
 
 		error_code error;
 
@@ -2819,11 +2819,11 @@ POSSIBILITY OF SUCH DAMAGE.
 
 #endif
 
-
relevance 2../include/libtorrent/enum_net.hpp:143this could be done more efficiently by just looking up the interface with the given name, maybe even with if_nametoindex()

this could be done more efficiently by just looking up -the interface with the given name, maybe even with if_nametoindex()

../include/libtorrent/enum_net.hpp:143

-		address ip = address::from_string(device_name, ec);
-		if (!ec)
-		{
+
relevance 2../include/libtorrent/enum_net.hpp:150this could be done more efficiently by just looking up the interface with the given name, maybe even with if_nametoindex()

this could be done more efficiently by just looking up +the interface with the given name, maybe even with if_nametoindex()

../include/libtorrent/enum_net.hpp:150

			// providing 0.0.0.0 as the device, turn it into "::0"
+			if (ip == address_v4::any() && !ipv4)
+				ip = address_v6::any();
+#endif
 			bind_ep.address(ip);
 			// it appears to be an IP. Just bind to that address
 			sock.bind(bind_ep, ec);
@@ -3205,8 +3205,8 @@ protected:
 
 		boost::shared_ptr<tracker_connection> shared_from_this()
 		{
-
relevance 2../include/libtorrent/aux_/session_impl.hpp:1146the throttling of saving resume data could probably be factored out into a separate class

the throttling of saving resume data could probably be -factored out into a separate class

../include/libtorrent/aux_/session_impl.hpp:1146

			// each second tick the timer takes a little
+
relevance 2../include/libtorrent/aux_/session_impl.hpp:1147the throttling of saving resume data could probably be factored out into a separate class

the throttling of saving resume data could probably be +factored out into a separate class

../include/libtorrent/aux_/session_impl.hpp:1147

			// each second tick the timer takes a little
 			// bit longer than one second to trigger. The
 			// extra time it took is accumulated into this
 			// counter. Every time it exceeds 1000, torrents
@@ -3217,8 +3217,8 @@ factored out into a separate class

../include/libtorrent/aux_/session_im boost::uint16_t m_tick_residual; #ifndef TORRENT_DISABLE_LOGGING - virtual void session_log(char const* fmt, ...) const TORRENT_FORMAT(2,3); - virtual void session_vlog(char const* fmt, va_list& va) const TORRENT_FORMAT(2,0); + virtual void session_log(char const* fmt, ...) const TORRENT_OVERRIDE TORRENT_FINAL TORRENT_FORMAT(2,3); + virtual void session_vlog(char const* fmt, va_list& va) const TORRENT_OVERRIDE TORRENT_FINAL TORRENT_FORMAT(2,0); // this list of tracker loggers serves as tracker_callbacks when // shutting down. This list is just here to keep them alive during @@ -3226,8 +3226,8 @@ factored out into a separate class

../include/libtorrent/aux_/session_im std::list<boost::shared_ptr<tracker_logger> > m_tracker_loggers; #endif -
void queue_async_resume_data(boost::shared_ptr<torrent> const& t); -
void done_async_resume(); +
virtual void queue_async_resume_data(boost::shared_ptr<torrent> const& t) TORRENT_OVERRIDE TORRENT_FINAL; +
virtual void done_async_resume() TORRENT_OVERRIDE TORRENT_FINAL; void async_resume_dispatched(); // state for keeping track of external IPs @@ -3242,7 +3242,7 @@ factored out into a separate class

../include/libtorrent/aux_/session_im // *glares at gcc* struct extention_dht_query { - uint8_t query_len; + boost::uint8_t query_len; boost::array<char, max_dht_query_length> query; dht_extension_handler_t handler; }; @@ -3498,8 +3498,8 @@ the chunk headers should be subtracted from the receive_buffer_size

../s std::string request; request.reserve(400); -

relevance 1../src/session_impl.cpp:5306report the proper address of the router as the source IP of this understanding of our external address, instead of the empty address

report the proper address of the router as the source IP of -this understanding of our external address, instead of the empty address

../src/session_impl.cpp:5306

	void session_impl::on_port_mapping(int mapping, address const& ip, int port
+
relevance 1../src/session_impl.cpp:5308report the proper address of the router as the source IP of this understanding of our external address, instead of the empty address

report the proper address of the router as the source IP of +this understanding of our external address, instead of the empty address

../src/session_impl.cpp:5308

	void session_impl::on_port_mapping(int mapping, address const& ip, int port
 		, error_code const& ec, int map_transport)
 	{
 		TORRENT_ASSERT(is_single_thread());
@@ -3550,9 +3550,9 @@ this understanding of our external address, instead of the empty address

relevance 1../src/session_impl.cpp:6700we only need to do this if our global IPv4 address has changed since the DHT (currently) only supports IPv4. Since restarting the DHT is kind of expensive, it would be nice to not do it unnecessarily

we only need to do this if our global IPv4 address has changed +

relevance 1../src/session_impl.cpp:6702we only need to do this if our global IPv4 address has changed since the DHT (currently) only supports IPv4. Since restarting the DHT is kind of expensive, it would be nice to not do it unnecessarily

we only need to do this if our global IPv4 address has changed since the DHT (currently) only supports IPv4. Since restarting the DHT -is kind of expensive, it would be nice to not do it unnecessarily

../src/session_impl.cpp:6700

#endif
+is kind of expensive, it would be nice to not do it unnecessarily

../src/session_impl.cpp:6702

#endif
 
 		if (!m_external_ip.cast_vote(ip, source_type, source)) return;
 
@@ -3658,8 +3658,8 @@ up to the highest written piece in each file

../src/torrent.cpp:1235

relevance 1../src/torrent.cpp:7139save the send_stats state instead of throwing them away it may pose an issue when downgrading though

save the send_stats state instead of throwing them away -it may pose an issue when downgrading though

../src/torrent.cpp:7139

					for (int k = 0; k < bits; ++k)
+
relevance 1../src/torrent.cpp:7144save the send_stats state instead of throwing them away it may pose an issue when downgrading though

save the send_stats state instead of throwing them away +it may pose an issue when downgrading though

../src/torrent.cpp:7144

					for (int k = 0; k < bits; ++k)
 						v |= (info[j*8+k].state == piece_picker::block_info::state_finished)
 						? (1 << k) : 0;
 					bitmask.append(1, v);
@@ -3710,9 +3710,9 @@ it may pose an issue when downgrading though

../src/torrent.cpp:7139

relevance 1../src/torrent.cpp:8362should disconnect all peers that have the pieces we have not just seeds. It would be pretty expensive to check all pieces for all peers though

should disconnect all peers that have the pieces we have +

relevance 1../src/torrent.cpp:8367should disconnect all peers that have the pieces we have not just seeds. It would be pretty expensive to check all pieces for all peers though

should disconnect all peers that have the pieces we have not just seeds. It would be pretty expensive to check all pieces -for all peers though

../src/torrent.cpp:8362

+for all peers though

../src/torrent.cpp:8367

 		set_state(torrent_status::finished);
 		set_queue_position(-1);
 
@@ -4215,7 +4215,7 @@ TORRENT_TEST(duplicates)
 }
 
 
-
relevance 0../test/test_ssl.cpp:385test using a signed certificate with the wrong info-hash in DN

test using a signed certificate with the wrong info-hash in DN

../test/test_ssl.cpp:385

	// in verifying peers
+
relevance 0../test/test_ssl.cpp:391test using a signed certificate with the wrong info-hash in DN

test using a signed certificate with the wrong info-hash in DN

../test/test_ssl.cpp:391

	// in verifying peers
 	ctx.set_verify_mode(context::verify_none, ec);
 	if (ec)
 	{
@@ -4266,8 +4266,8 @@ TORRENT_TEST(duplicates)
 			return false;
 		}
 		fprintf(stderr, "use_tmp_dh_file \"%s\"\n", dh_params.c_str());
-
relevance 0../test/test_ssl.cpp:483also test using a hash that refers to a valid torrent but that differs from the SNI hash

also test using a hash that refers to a valid torrent -but that differs from the SNI hash

../test/test_ssl.cpp:483

	print_alerts(ses1, "ses1", true, true, true, &on_alert);
+
relevance 0../test/test_ssl.cpp:489also test using a hash that refers to a valid torrent but that differs from the SNI hash

also test using a hash that refers to a valid torrent +but that differs from the SNI hash

../test/test_ssl.cpp:489

	print_alerts(ses1, "ses1", true, true, true, &on_alert);
 	if (ec)
 	{
 		fprintf(stderr, "Failed SSL handshake: %s\n"
@@ -6465,7 +6465,7 @@ retry:
 					TORRENT_ASSERT(!m_abort);
 					m_listen_sockets.push_back(s);
 				}
-
relevance 0../src/session_impl.cpp:2750should this function take a shared_ptr instead?

should this function take a shared_ptr instead?

../src/session_impl.cpp:2750

	{
+
relevance 0../src/session_impl.cpp:2752should this function take a shared_ptr instead?

should this function take a shared_ptr instead?

../src/session_impl.cpp:2752

	{
 #if defined TORRENT_ASIO_DEBUGGING
 		complete_async("session_impl::on_socks_accept");
 #endif
@@ -6516,7 +6516,7 @@ retry:
 		TORRENT_ASSERT(p->is_disconnecting());
 
 		TORRENT_ASSERT(sp.use_count() > 0);
-
relevance 0../src/session_impl.cpp:3099have a separate list for these connections, instead of having to loop through all of them

have a separate list for these connections, instead of having to loop through all of them

../src/session_impl.cpp:3099

		if (m_auto_manage_time_scaler < 0)
+
relevance 0../src/session_impl.cpp:3101have a separate list for these connections, instead of having to loop through all of them

have a separate list for these connections, instead of having to loop through all of them

../src/session_impl.cpp:3101

		if (m_auto_manage_time_scaler < 0)
 		{
 			INVARIANT_CHECK;
 			m_auto_manage_time_scaler = settings().get_int(settings_pack::auto_manage_interval);
@@ -6567,7 +6567,7 @@ retry:
 			// to not miss the torrent after it
 			if (!t.want_tick()) --i;
 		}
-
relevance 0../src/session_impl.cpp:3132this should apply to all bandwidth channels

this should apply to all bandwidth channels

../src/session_impl.cpp:3132

#if TORRENT_DEBUG_STREAMING > 0
+
relevance 0../src/session_impl.cpp:3134this should apply to all bandwidth channels

this should apply to all bandwidth channels

../src/session_impl.cpp:3134

#if TORRENT_DEBUG_STREAMING > 0
 		printf("\033[2J\033[0;0H");
 #endif
 
@@ -6618,9 +6618,9 @@ retry:
 		// scrape paused torrents that are auto managed
 		// (unless the session is paused)
 		// --------------------------------------------------------------
-
relevance 0../src/session_impl.cpp:3861use a lower limit than m_settings.connections_limit to allocate the to 10% or so of connection slots for incoming connections

use a lower limit than m_settings.connections_limit +

relevance 0../src/session_impl.cpp:3863use a lower limit than m_settings.connections_limit to allocate the to 10% or so of connection slots for incoming connections

use a lower limit than m_settings.connections_limit to allocate the to 10% or so of connection slots for incoming -connections

../src/session_impl.cpp:3861

		// robin fashion, so that every torrent is equally likely to connect to a
+connections

../src/session_impl.cpp:3863

		// robin fashion, so that every torrent is equally likely to connect to a
 		// peer
 
 		// boost connections are connections made by torrent connection
@@ -6671,8 +6671,8 @@ connections

../src/session_impl.cpp:3861

relevance 0../src/session_impl.cpp:4011post a message to have this happen immediately instead of waiting for the next tick

post a message to have this happen -immediately instead of waiting for the next tick

../src/session_impl.cpp:4011

				continue;
+
relevance 0../src/session_impl.cpp:4013post a message to have this happen immediately instead of waiting for the next tick

post a message to have this happen +immediately instead of waiting for the next tick

../src/session_impl.cpp:4013

				continue;
 			}
 
 			if (!p->is_peer_interested()
@@ -6723,12 +6723,12 @@ immediately instead of waiting for the next tick

../src/session_impl.cpp , allowed_upload_slots); #ifndef TORRENT_DISABLE_LOGGING -

relevance 0../src/session_impl.cpp:4397it might be a nice feature here to limit the number of torrents to send in a single update. By just posting the first n torrents, they would nicely be round-robined because the torrent lists are always pushed back. Perhaps the status_update_alert could even have a fixed array of n entries rather than a vector, to further improve memory locality.

it might be a nice feature here to limit the number of torrents +

relevance 0../src/session_impl.cpp:4399it might be a nice feature here to limit the number of torrents to send in a single update. By just posting the first n torrents, they would nicely be round-robined because the torrent lists are always pushed back. Perhaps the status_update_alert could even have a fixed array of n entries rather than a vector, to further improve memory locality.

it might be a nice feature here to limit the number of torrents to send in a single update. By just posting the first n torrents, they would nicely be round-robined because the torrent lists are always pushed back. Perhaps the status_update_alert could even have a fixed array of n entries rather than a vector, to further improve memory -locality.

../src/session_impl.cpp:4397

			t->status(&*i, flags);
+locality.

../src/session_impl.cpp:4399

			t->status(&*i, flags);
 		}
 	}
 
@@ -6779,8 +6779,8 @@ locality.

../src/session_impl.cpp:4397

relevance 0../src/session_impl.cpp:4610this logic could probably be less spaghetti looking by being moved to a function with early exits

this logic could probably be less spaghetti looking by being -moved to a function with early exits

../src/session_impl.cpp:4610

		}
+
relevance 0../src/session_impl.cpp:4612this logic could probably be less spaghetti looking by being moved to a function with early exits

this logic could probably be less spaghetti looking by being +moved to a function with early exits

../src/session_impl.cpp:4612

		}
 
 		// figure out the info hash of the torrent
 		sha1_hash const* ih = 0;
@@ -6831,9 +6831,9 @@ moved to a function with early exits

../src/session_impl.cpp:4610

relevance 0../src/storage.cpp:751make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info

make this more generic to not just work if files have been +

relevance 0../src/storage.cpp:758make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info

make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance -maybe use the same format as .torrent files and reuse some code from torrent_info

../src/storage.cpp:751

			if (file_offset < files().file_size(file_index))
+maybe use the same format as .torrent files and reuse some code from torrent_info

../src/storage.cpp:758

			if (file_offset < files().file_size(file_index))
 				break;
 
 			file_offset -= files().file_size(file_index);
@@ -6884,9 +6884,9 @@ maybe use the same format as .torrent files and reuse some code from torrent_inf
 		}
 
 		if (file_sizes_ent.list_size() == 0)
-
relevance 0../src/storage.cpp:1082if everything moves OK, except for the partfile we currently won't update the save path, which breaks things. it would probably make more sense to give up on the partfile

if everything moves OK, except for the partfile +

relevance 0../src/storage.cpp:1089if everything moves OK, except for the partfile we currently won't update the save path, which breaks things. it would probably make more sense to give up on the partfile

if everything moves OK, except for the partfile we currently won't update the save path, which breaks things. -it would probably make more sense to give up on the partfile

../src/storage.cpp:1082

					if (ec)
+it would probably make more sense to give up on the partfile

../src/storage.cpp:1089

					if (ec)
 					{
 						ec.file = i->second;
 						ec.operation = storage_error::copy;
@@ -7446,7 +7446,7 @@ dedicated listen port

../src/torrent.cpp:2926

relevance 0../src/torrent.cpp:3723add one peer per IP the hostname resolves to

add one peer per IP the hostname resolves to

../src/torrent.cpp:3723

#endif
+
relevance 0../src/torrent.cpp:3728add one peer per IP the hostname resolves to

add one peer per IP the hostname resolves to

../src/torrent.cpp:3728

#endif
 
 	void torrent::on_peer_name_lookup(error_code const& e
 		, std::vector<address> const& host_list, int port)
@@ -7497,7 +7497,7 @@ dedicated listen port

../src/torrent.cpp:2926

relevance 0../src/torrent.cpp:4663update suggest_piece?

update suggest_piece?

../src/torrent.cpp:4663

		if (has_picker())
+
relevance 0../src/torrent.cpp:4668update suggest_piece?

update suggest_piece?

../src/torrent.cpp:4668

		if (has_picker())
 		{
 			torrent_peer* pp = peer->peer_info_struct();
 			m_picker->inc_refcount_all(pp);
@@ -7548,8 +7548,8 @@ dedicated listen port

../src/torrent.cpp:2926

relevance 0../src/torrent.cpp:4807really, we should just keep the picker around in this case to maintain the availability counters

really, we should just keep the picker around -in this case to maintain the availability counters

../src/torrent.cpp:4807

		pieces.reserve(cs.pieces.size());
+
relevance 0../src/torrent.cpp:4812really, we should just keep the picker around in this case to maintain the availability counters

really, we should just keep the picker around +in this case to maintain the availability counters

../src/torrent.cpp:4812

		pieces.reserve(cs.pieces.size());
 
 		// sort in ascending order, to get most recently used first
 		std::sort(cs.pieces.begin(), cs.pieces.end()
@@ -7600,12 +7600,12 @@ in this case to maintain the availability counters

../src/torrent.cpp:48 } void torrent::abort() -

relevance 0../src/torrent.cpp:6838make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info The mapped_files needs to be read both in the network thread and in the disk thread, since they both have their own mapped files structures which are kept in sync

make this more generic to not just work if files have been +

relevance 0../src/torrent.cpp:6843make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info The mapped_files needs to be read both in the network thread and in the disk thread, since they both have their own mapped files structures which are kept in sync

make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance maybe use the same format as .torrent files and reuse some code from torrent_info The mapped_files needs to be read both in the network thread and in the disk thread, since they both have their own mapped files structures -which are kept in sync

../src/torrent.cpp:6838

			{
+which are kept in sync

../src/torrent.cpp:6843

			{
 				m_save_path = p;
 #ifndef TORRENT_DISABLE_LOGGING
 				debug_log("loaded resume data: save-path: %s", m_save_path.c_str());
@@ -7656,12 +7656,12 @@ which are kept in sync

../src/torrent.cpp:6838

relevance 0../src/torrent.cpp:6971if this is a merkle torrent and we can't restore the tree, we need to wipe all the bits in the have array, but not necessarily we might want to do a full check to see if we have all the pieces. This is low priority since almost no one uses merkle torrents

if this is a merkle torrent and we can't +

relevance 0../src/torrent.cpp:6976if this is a merkle torrent and we can't restore the tree, we need to wipe all the bits in the have array, but not necessarily we might want to do a full check to see if we have all the pieces. This is low priority since almost no one uses merkle torrents

if this is a merkle torrent and we can't restore the tree, we need to wipe all the bits in the have array, but not necessarily we might want to do a full check to see if we have all the pieces. This is low priority since almost -no one uses merkle torrents

../src/torrent.cpp:6971

				add_web_seed(url, web_seed_entry::http_seed);
+no one uses merkle torrents

../src/torrent.cpp:6976

				add_web_seed(url, web_seed_entry::http_seed);
 			}
 		}
 
@@ -7712,9 +7712,9 @@ no one uses merkle torrents

../src/torrent.cpp:6971

relevance 0../src/torrent.cpp:7197make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance. using file_base

make this more generic to not just work if files have been +

relevance 0../src/torrent.cpp:7202make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance. using file_base

make this more generic to not just work if files have been renamed, but also if they have been merged into a single file for instance. -using file_base

../src/torrent.cpp:7197

		pieces.resize(m_torrent_file->num_pieces());
+using file_base

../src/torrent.cpp:7202

		pieces.resize(m_torrent_file->num_pieces());
 		if (!has_picker())
 		{
 			std::memset(&pieces[0], m_have_all, pieces.size());
@@ -7765,9 +7765,9 @@ using file_base

../src/torrent.cpp:7197

relevance 0../src/torrent.cpp:9440add a flag to ignore stats, and only care about resume data for content. For unchanged files, don't trigger a load of the metadata just to save an empty resume data file

add a flag to ignore stats, and only care about resume data for +

relevance 0../src/torrent.cpp:9445add a flag to ignore stats, and only care about resume data for content. For unchanged files, don't trigger a load of the metadata just to save an empty resume data file

add a flag to ignore stats, and only care about resume data for content. For unchanged files, don't trigger a load of the metadata -just to save an empty resume data file

../src/torrent.cpp:9440

		if (m_complete != 0xffffff) seeds = m_complete;
+just to save an empty resume data file

../src/torrent.cpp:9445

		if (m_complete != 0xffffff) seeds = m_complete;
 		else seeds = m_peer_list ? m_peer_list->num_seeds() : 0;
 
 		if (m_incomplete != 0xffffff) downloaders = m_incomplete;
@@ -7818,8 +7818,8 @@ just to save an empty resume data file

../src/torrent.cpp:9440

relevance 0../src/torrent.cpp:11057instead of resorting the whole list, insert the peers directly into the right place

instead of resorting the whole list, insert the peers -directly into the right place

../src/torrent.cpp:11057

				printf("timed out [average-piece-time: %d ms ]\n"
+
relevance 0../src/torrent.cpp:11062instead of resorting the whole list, insert the peers directly into the right place

instead of resorting the whole list, insert the peers +directly into the right place

../src/torrent.cpp:11062

				printf("timed out [average-piece-time: %d ms ]\n"
 					, m_average_piece_time);
 #endif
 			}
@@ -9050,10 +9050,10 @@ private:
 		// destructs.
 		//
 		// For more information on peer classes, see peer-classes_.
-
relevance 0../include/libtorrent/settings_pack.hpp:1094deprecate this ``max_rejects`` is the number of piece requests we will reject in a row while a peer is choked before the peer is considered abusive and is disconnected.

deprecate this +

relevance 0../include/libtorrent/settings_pack.hpp:1092deprecate this ``max_rejects`` is the number of piece requests we will reject in a row while a peer is choked before the peer is considered abusive and is disconnected.

deprecate this ``max_rejects`` is the number of piece requests we will reject in a row while a peer is choked before the peer is considered abusive -and is disconnected.

../include/libtorrent/settings_pack.hpp:1094

+and is disconnected.

../include/libtorrent/settings_pack.hpp:1092

 			// this is the minimum allowed announce interval for a tracker. This
 			// is specified in seconds and is used as a sanity check on what is
 			// returned from a tracker. It mitigates hammering misconfigured
@@ -9453,7 +9453,7 @@ public:
 	item(entry const& v
 		, std::pair<char const*, int> salt
 		, boost::uint64_t seq, char const* pk, char const* sk);
-
relevance 0../include/libtorrent/aux_/session_impl.hpp:858should this be renamed m_outgoing_interfaces?

should this be renamed m_outgoing_interfaces?

../include/libtorrent/aux_/session_impl.hpp:858

			// client with the tracker only. It is randomized
+
relevance 0../include/libtorrent/aux_/session_impl.hpp:859should this be renamed m_outgoing_interfaces?

should this be renamed m_outgoing_interfaces?

../include/libtorrent/aux_/session_impl.hpp:859

			// client with the tracker only. It is randomized
 			// at startup
 			int m_key;
 
@@ -9504,7 +9504,7 @@ public:
 			// round-robin index into m_net_interfaces
 			mutable boost::uint8_t m_interface_index;
 
-
relevance 0../include/libtorrent/aux_/session_impl.hpp:909replace this by a proper asio timer

replace this by a proper asio timer

../include/libtorrent/aux_/session_impl.hpp:909

+
relevance 0../include/libtorrent/aux_/session_impl.hpp:910replace this by a proper asio timer

replace this by a proper asio timer

../include/libtorrent/aux_/session_impl.hpp:910

 			void open_new_incoming_socks_connection();
 
 			enum listen_on_flags_t
@@ -9528,7 +9528,7 @@ public:
 
 			// this is used to decide when to recalculate which
 			// torrents to keep queued and which to activate
-
relevance 0../include/libtorrent/aux_/session_impl.hpp:914replace this by a proper asio timer

replace this by a proper asio timer

../include/libtorrent/aux_/session_impl.hpp:914

			{
+
relevance 0../include/libtorrent/aux_/session_impl.hpp:915replace this by a proper asio timer

replace this by a proper asio timer

../include/libtorrent/aux_/session_impl.hpp:915

			{
 				open_ssl_socket = 0x10
 			};
 
@@ -9554,7 +9554,7 @@ public:
 			// is only decresed when the unchoke set
 			// is recomputed, and when it reaches zero,
 			// the optimistic unchoke is moved to another peer.
-
relevance 0../include/libtorrent/aux_/session_impl.hpp:921replace this by a proper asio timer

replace this by a proper asio timer

../include/libtorrent/aux_/session_impl.hpp:921

+
relevance 0../include/libtorrent/aux_/session_impl.hpp:922replace this by a proper asio timer

replace this by a proper asio timer

../include/libtorrent/aux_/session_impl.hpp:922

 #ifndef TORRENT_DISABLE_DHT
 			entry m_dht_state;
 #endif
diff --git a/docs/troubleshooting.png b/docs/troubleshooting.png
index af0d74fa6..9318e4e45 100644
Binary files a/docs/troubleshooting.png and b/docs/troubleshooting.png differ
diff --git a/docs/utp_stack.diagram b/docs/utp_stack.diagram
index 2de786b8f..b3b808597 100644
--- a/docs/utp_stack.diagram
+++ b/docs/utp_stack.diagram
@@ -1,9 +1,9 @@
-+-----------------------+
-| BitTorrent protocol   |
-+-----------------------+
-|          SSL          |
-+-----------+-----------+
-| TCP       | uTP       |
-|           +-----------+
-|           | UDP       |
-+-----------+-----------+
++------------------------+
+| "BitTorrent protocol"  |
++------------------------+
+|         "SSL"          |
++------------+-----------+
+| "TCP"      | "uTP"     |
+|            +-----------+
+|            | "UDP"     |
++------------+-----------+