first step in making opening all the listen sockets a bit more reliable

This commit is contained in:
arvidn 2015-06-29 23:10:09 -04:00
parent d1670c72c2
commit 94d6e06c97
2 changed files with 21 additions and 26 deletions

View File

@ -824,11 +824,6 @@ namespace libtorrent
// at startup // at startup
int m_key; int m_key;
// the number of retries we make when binding the
// listen socket. For each retry the port number
// is incremented by one
int m_listen_port_retries;
// the addresses or device names of the interfaces we are supposed to // the addresses or device names of the interfaces we are supposed to
// listen on. if empty, it means that we should let the os decide // listen on. if empty, it means that we should let the os decide
// which interface to listen on // which interface to listen on
@ -885,7 +880,7 @@ namespace libtorrent
}; };
listen_socket_t setup_listener(std::string const& device listen_socket_t setup_listener(std::string const& device
, bool ipv4, int port, int& retries, int flags, error_code& ec); , bool ipv4, int port, int flags, error_code& ec);
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
entry m_dht_state; entry m_dht_state;

View File

@ -383,7 +383,6 @@ namespace aux {
, m_work(io_service::work(m_io_service)) , m_work(io_service::work(m_io_service))
, m_max_queue_pos(-1) , m_max_queue_pos(-1)
, m_key(0) , m_key(0)
, m_listen_port_retries(10)
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, m_i2p_conn(m_io_service) , m_i2p_conn(m_io_service)
#endif #endif
@ -1622,8 +1621,10 @@ namespace aux {
enum { listen_no_system_port = 0x02 }; enum { listen_no_system_port = 0x02 };
listen_socket_t session_impl::setup_listener(std::string const& device listen_socket_t session_impl::setup_listener(std::string const& device
, bool ipv4, int port, int& retries, int flags, error_code& ec) , bool ipv4, int port, int flags, error_code& ec)
{ {
int retries = m_settings.get_int(settings_pack::max_retry_port_bind);
listen_socket_t ret; listen_socket_t ret;
ret.ssl = flags & open_ssl_socket; ret.ssl = flags & open_ssl_socket;
int last_op = 0; int last_op = 0;
@ -1677,14 +1678,14 @@ namespace aux {
if (ec == error_code(boost::system::errc::no_such_device, generic_category())) if (ec == error_code(boost::system::errc::no_such_device, generic_category()))
return ret; return ret;
while (ec && retries > 0) while (bool(ec) && retries > 0)
{ {
TORRENT_ASSERT_VAL(ec, ec); TORRENT_ASSERT_VAL(ec, ec);
#ifndef TORRENT_DISABLE_LOGGING #ifndef TORRENT_DISABLE_LOGGING
session_log("failed to bind to interface [%s %d] \"%s : %s\": %s " session_log("failed to bind to interface [%s %d] \"%s\" : %s (%d) : %s "
"(retries: %d)" "(retries: %d)"
, device.c_str(), port, bind_ip.to_string(ec).c_str() , device.c_str(), port, bind_ip.to_string(ec).c_str()
, ec.category().name(), ec.message().c_str(), retries); , ec.category().name(), ec.value(), ec.message().c_str(), retries);
#endif #endif
ec.clear(); ec.clear();
TORRENT_ASSERT_VAL(!ec, ec); TORRENT_ASSERT_VAL(!ec, ec);
@ -1694,7 +1695,7 @@ namespace aux {
, device.c_str(), port, ec); , device.c_str(), port, ec);
last_op = listen_failed_alert::bind; last_op = listen_failed_alert::bind;
} }
if (ec && !(flags & listen_no_system_port)) if (bool(ec) && !(flags & listen_no_system_port))
{ {
// instead of giving up, try let the OS pick a port // instead of giving up, try let the OS pick a port
port = 0; port = 0;
@ -1777,8 +1778,7 @@ namespace aux {
? 0 : listen_no_system_port; ? 0 : listen_no_system_port;
error_code ec; error_code ec;
// reset the retry counter int listen_port_retries = m_settings.get_int(settings_pack::max_retry_port_bind);
m_listen_port_retries = m_settings.get_int(settings_pack::max_retry_port_bind);
retry: retry:
@ -1803,10 +1803,11 @@ retry:
{ {
// this means we should open two listen sockets // this means we should open two listen sockets
// one for IPv4 and one for IPv6 // one for IPv4 and one for IPv6
int retries = m_settings.get_int(settings_pack::max_retry_port_bind);
listen_socket_t s = setup_listener("0.0.0.0", true listen_socket_t s = setup_listener("0.0.0.0", true
, m_listen_interface.port() , m_listen_interface.port()
, m_listen_port_retries, flags, ec); , flags, ec);
if (s.sock) if (s.sock)
{ {
@ -1822,10 +1823,10 @@ retry:
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
if (m_settings.get_int(settings_pack::ssl_listen)) if (m_settings.get_int(settings_pack::ssl_listen))
{ {
int retries = 10; int retries = m_settings.get_int(settings_pack::max_retry_port_bind);
listen_socket_t s = setup_listener("0.0.0.0", true listen_socket_t s = setup_listener("0.0.0.0", true
, m_settings.get_int(settings_pack::ssl_listen) , m_settings.get_int(settings_pack::ssl_listen)
, retries, flags | open_ssl_socket, ec); , flags | open_ssl_socket, ec);
if (s.sock) if (s.sock)
{ {
@ -1840,7 +1841,7 @@ retry:
if (supports_ipv6()) if (supports_ipv6())
{ {
listen_socket_t s = setup_listener("::1", false, m_listen_interface.port() listen_socket_t s = setup_listener("::1", false, m_listen_interface.port()
, m_listen_port_retries, flags, ec); , flags, ec);
if (s.sock) if (s.sock)
{ {
@ -1852,10 +1853,9 @@ retry:
if (m_settings.get_int(settings_pack::ssl_listen)) if (m_settings.get_int(settings_pack::ssl_listen))
{ {
s.ssl = true; s.ssl = true;
int retries = 10;
listen_socket_t s = setup_listener("::1", false listen_socket_t s = setup_listener("::1", false
, m_settings.get_int(settings_pack::ssl_listen) , m_settings.get_int(settings_pack::ssl_listen)
, retries, flags | open_ssl_socket, ec); , flags | open_ssl_socket, ec);
if (s.sock) if (s.sock)
{ {
@ -1906,7 +1906,7 @@ retry:
continue; continue;
listen_socket_t s = setup_listener(device, address_family, port listen_socket_t s = setup_listener(device, address_family, port
, m_listen_port_retries, flags, ec); , flags, ec);
if (ec == error_code(boost::system::errc::no_such_device, generic_category())) if (ec == error_code(boost::system::errc::no_such_device, generic_category()))
{ {
@ -1935,7 +1935,7 @@ retry:
listen_socket_t s = setup_listener(device, address_family listen_socket_t s = setup_listener(device, address_family
, m_settings.get_int(settings_pack::ssl_listen) , m_settings.get_int(settings_pack::ssl_listen)
, m_listen_port_retries, flags | open_ssl_socket, ec); , flags | open_ssl_socket, ec);
if (s.sock) if (s.sock)
{ {
@ -1964,10 +1964,10 @@ retry:
session_log("cannot bind TCP listen socket to interface \"%s\": %s" session_log("cannot bind TCP listen socket to interface \"%s\": %s"
, print_endpoint(m_listen_interface).c_str(), ec.message().c_str()); , print_endpoint(m_listen_interface).c_str(), ec.message().c_str());
#endif #endif
if (m_listen_port_retries > 0) if (listen_port_retries > 0)
{ {
m_listen_interface.port(m_listen_interface.port() + 1); m_listen_interface.port(m_listen_interface.port() + 1);
--m_listen_port_retries; --listen_port_retries;
goto retry; goto retry;
} }
if (m_alerts.should_post<listen_failed_alert>()) if (m_alerts.should_post<listen_failed_alert>())
@ -2018,10 +2018,10 @@ retry:
session_log("cannot bind to UDP interface \"%s\": %s" session_log("cannot bind to UDP interface \"%s\": %s"
, print_endpoint(m_listen_interface).c_str(), ec.message().c_str()); , print_endpoint(m_listen_interface).c_str(), ec.message().c_str());
#endif #endif
if (m_listen_port_retries > 0) if (listen_port_retries > 0)
{ {
m_listen_interface.port(m_listen_interface.port() + 1); m_listen_interface.port(m_listen_interface.port() + 1);
--m_listen_port_retries; --listen_port_retries;
goto retry; goto retry;
} }
if (m_alerts.should_post<listen_failed_alert>()) if (m_alerts.should_post<listen_failed_alert>())