diff --git a/docs/manual.html b/docs/manual.html
index e0a5bc92e..ad1b1836f 100755
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -566,6 +566,21 @@ if it managed to open the socket, and false if it failed. If it fails, it will a
generate an appropriate alert (listen_failed_alert).
The interface parameter can also be a hostname that will resolve to the device you
want to listen on.
+If you're also starting the DHT, it is a good idea to do that after you've called
+listen_on(), since the default listen port for the DHT is the same as the tcp
+listen socket. If you start the DHT first, it will assume the tcp port is free and
+open the udp socket on that port, then later, when listen_on() is called, it
+may turn out that the tcp port is in use. That results in the DHT and the bittorrent
+socket listening on different ports. If the DHT is active when listen_on is
+called, the udp port will be rebound to the new port, if it was configured to use
+the same port as the tcp socket, and if the listen_on call failed to bind to the
+same port that the udp uses.
+The reason why it's a good idea to run the DHT and the bittorrent socket on the same
+port is because that is an assumption that may be used to increase performance. One
+way to accelerate the connecting of peers on windows may be to first ping all peers
+with a DHT ping packet, and connect to those that responds first. On windows one
+can only connect to a few peers at a time because of a built in limitation (in XP
+Service pack 2).
diff --git a/docs/manual.rst b/docs/manual.rst
index 1e047a7a7..844d8da09 100755
--- a/docs/manual.rst
+++ b/docs/manual.rst
@@ -436,6 +436,22 @@ generate an appropriate alert (listen_failed_alert_).
The interface parameter can also be a hostname that will resolve to the device you
want to listen on.
+If you're also starting the DHT, it is a good idea to do that after you've called
+``listen_on()``, since the default listen port for the DHT is the same as the tcp
+listen socket. If you start the DHT first, it will assume the tcp port is free and
+open the udp socket on that port, then later, when ``listen_on()`` is called, it
+may turn out that the tcp port is in use. That results in the DHT and the bittorrent
+socket listening on different ports. If the DHT is active when ``listen_on`` is
+called, the udp port will be rebound to the new port, if it was configured to use
+the same port as the tcp socket, and if the listen_on call failed to bind to the
+same port that the udp uses.
+
+The reason why it's a good idea to run the DHT and the bittorrent socket on the same
+port is because that is an assumption that may be used to increase performance. One
+way to accelerate the connecting of peers on windows may be to first ping all peers
+with a DHT ping packet, and connect to those that responds first. On windows one
+can only connect to a few peers at a time because of a built in limitation (in XP
+Service pack 2).
pop_alert() set_severity_level()
--------------------------------
diff --git a/examples/client_test.cpp b/examples/client_test.cpp
index c6fa11bb3..62802c538 100755
--- a/examples/client_test.cpp
+++ b/examples/client_test.cpp
@@ -590,6 +590,22 @@ int main(int ac, char* av[])
ses.add_extension(&create_metadata_plugin);
ses.add_extension(&create_ut_pex_plugin);
+ ses.set_max_uploads(upload_slots_limit);
+ ses.set_max_half_open_connections(half_open_limit);
+ ses.set_download_rate_limit(download_limit);
+ ses.set_upload_rate_limit(upload_limit);
+ ses.listen_on(std::make_pair(listen_port, listen_port + 10)
+ , bind_to_interface.c_str());
+ ses.set_settings(settings);
+ if (log_level == "debug")
+ ses.set_severity_level(alert::debug);
+ else if (log_level == "warning")
+ ses.set_severity_level(alert::warning);
+ else if (log_level == "fatal")
+ ses.set_severity_level(alert::fatal);
+ else
+ ses.set_severity_level(alert::info);
+
#ifndef TORRENT_DISABLE_DHT
settings.use_dht_as_fallback = false;
@@ -613,22 +629,6 @@ int main(int ac, char* av[])
, 6881));
#endif
- ses.set_max_uploads(upload_slots_limit);
- ses.set_max_half_open_connections(half_open_limit);
- ses.set_download_rate_limit(download_limit);
- ses.set_upload_rate_limit(upload_limit);
- ses.listen_on(std::make_pair(listen_port, listen_port + 10)
- , bind_to_interface.c_str());
- ses.set_settings(settings);
- if (log_level == "debug")
- ses.set_severity_level(alert::debug);
- else if (log_level == "warning")
- ses.set_severity_level(alert::warning);
- else if (log_level == "fatal")
- ses.set_severity_level(alert::fatal);
- else
- ses.set_severity_level(alert::info);
-
// look for ipfilter.dat
// poor man's parser
// reads emule ipfilter files.
diff --git a/src/session_impl.cpp b/src/session_impl.cpp
index 984862b07..f2a90fc6d 100755
--- a/src/session_impl.cpp
+++ b/src/session_impl.cpp
@@ -1450,27 +1450,27 @@ namespace libtorrent { namespace detail
if (m_listen_socket)
m_listen_socket.reset();
+ bool new_listen_address = m_listen_interface.address() != new_interface.address();
+
+ m_incoming_connection = false;
+ m_listen_interface = new_interface;
+
+ open_listen_port();
+
#ifndef TORRENT_DISABLE_DHT
- if ((m_listen_interface.address() != new_interface.address()
- || m_dht_same_port)
- && m_dht)
+ if ((new_listen_address || m_dht_same_port) && m_dht)
{
if (m_dht_same_port)
m_dht_settings.service_port = new_interface.port();
// the listen interface changed, rebind the dht listen socket as well
m_dht->rebind(new_interface.address()
, m_dht_settings.service_port);
- if (m_listen_interface.address() != new_interface.address())
+ if (new_listen_address)
m_natpmp.rebind(new_interface.address());
m_natpmp.set_mappings(0, m_dht_settings.service_port);
}
#endif
- m_incoming_connection = false;
- m_listen_interface = new_interface;
-
- open_listen_port();
-
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
m_logger = create_log("main_session", listen_port(), false);
using boost::posix_time::second_clock;
@@ -1578,6 +1578,14 @@ namespace libtorrent { namespace detail
|| m_dht_same_port)
{
m_dht_same_port = true;
+ // if you hit this assert you are trying to start the
+ // DHT with the same port as the tcp listen port
+ // (which is default) _before_ you have opened the
+ // tcp listen port (so there is no configured port to use)
+ // basically, make sure you call listen_on() before
+ // start_dht(). See documentation for listen_on() for
+ // more information.
+ assert(m_listen_interface.port() > 0);
m_dht_settings.service_port = m_listen_interface.port();
}
m_external_udp_port = m_dht_settings.service_port;