Merge pull request #494 from arvidn/udp-bind-failure-1.1
attempt to fix issue with binding udp sockets on windows
This commit is contained in:
commit
e9b334ce63
|
@ -2069,30 +2069,37 @@ retry:
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
int const ssl_port = m_settings.get_int(settings_pack::ssl_listen);
|
int const ssl_port = m_settings.get_int(settings_pack::ssl_listen);
|
||||||
udp::endpoint ssl_bind_if(m_listen_interface.address(), ssl_port);
|
udp::endpoint ssl_bind_if(m_listen_interface.address(), ssl_port);
|
||||||
|
tcp::endpoint ssl_bind_ep(m_listen_interface.address(), ssl_port);
|
||||||
|
|
||||||
// if ssl port is 0, we don't want to listen on an SSL port
|
// if ssl port is 0, we don't want to listen on an SSL port
|
||||||
if (ssl_port != 0)
|
if (ssl_port != 0)
|
||||||
{
|
{
|
||||||
// TODO: 2 use bind_to_device in udp_socket
|
// if the socket is already open with the port we want, just leave it
|
||||||
m_ssl_udp_socket.bind(ssl_bind_if, ec);
|
error_code err;
|
||||||
if (ec)
|
if (!m_ssl_udp_socket.is_open()
|
||||||
|
|| m_ssl_udp_socket.local_endpoint(err) != ssl_bind_ep
|
||||||
|
|| err)
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
m_ssl_udp_socket.bind(ssl_bind_if, ec);
|
||||||
session_log("SSL: cannot bind to UDP interface \"%s\": %s"
|
if (ec)
|
||||||
, print_endpoint(m_listen_interface).c_str(), ec.message().c_str());
|
|
||||||
#endif
|
|
||||||
if (m_alerts.should_post<listen_failed_alert>())
|
|
||||||
{
|
{
|
||||||
error_code err;
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
m_alerts.emplace_alert<listen_failed_alert>(ssl_bind_if.address().to_string()
|
session_log("SSL: cannot bind to UDP interface \"%s\": %s"
|
||||||
, ssl_port, listen_failed_alert::bind, ec, listen_failed_alert::utp_ssl);
|
, print_endpoint(m_listen_interface).c_str(), ec.message().c_str());
|
||||||
|
#endif
|
||||||
|
if (m_alerts.should_post<listen_failed_alert>())
|
||||||
|
{
|
||||||
|
m_alerts.emplace_alert<listen_failed_alert>(ssl_bind_if.address().to_string()
|
||||||
|
, ssl_port, listen_failed_alert::bind, ec, listen_failed_alert::utp_ssl);
|
||||||
|
}
|
||||||
|
m_ssl_udp_socket.close();
|
||||||
|
ec.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maybe_update_udp_mapping(0, true, ssl_port, ssl_port);
|
||||||
|
maybe_update_udp_mapping(1, true, ssl_port, ssl_port);
|
||||||
}
|
}
|
||||||
ec.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maybe_update_udp_mapping(0, true, ssl_port, ssl_port);
|
|
||||||
maybe_update_udp_mapping(1, true, ssl_port, ssl_port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2113,39 +2120,47 @@ retry:
|
||||||
}
|
}
|
||||||
#endif // TORRENT_USE_OPENSSL
|
#endif // TORRENT_USE_OPENSSL
|
||||||
|
|
||||||
// TODO: 2 use bind_to_device in udp_socket
|
udp::endpoint const udp_bind_ep(m_listen_interface.address()
|
||||||
m_udp_socket.bind(udp::endpoint(m_listen_interface.address()
|
, m_listen_interface.port());
|
||||||
, m_listen_interface.port()), ec);
|
|
||||||
if (ec)
|
// if the socket is already open with the port we want, just leave it
|
||||||
|
error_code err;
|
||||||
|
if (!m_udp_socket.is_open()
|
||||||
|
|| m_udp_socket.local_endpoint(err) != m_listen_interface
|
||||||
|
|| err)
|
||||||
{
|
{
|
||||||
|
m_udp_socket.bind(udp_bind_ep, ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
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_alerts.should_post<listen_failed_alert>())
|
if (m_alerts.should_post<listen_failed_alert>())
|
||||||
{
|
{
|
||||||
error_code err;
|
m_alerts.emplace_alert<listen_failed_alert>(m_listen_interface.address().to_string()
|
||||||
m_alerts.emplace_alert<listen_failed_alert>(m_listen_interface.address().to_string()
|
, m_listen_interface.port()
|
||||||
, m_listen_interface.port()
|
, listen_failed_alert::bind
|
||||||
, listen_failed_alert::bind
|
, ec, listen_failed_alert::udp);
|
||||||
, ec, listen_failed_alert::udp);
|
}
|
||||||
|
m_udp_socket.close();
|
||||||
|
if (listen_port_retries > 0)
|
||||||
|
{
|
||||||
|
m_listen_interface.port(m_listen_interface.port() + 1);
|
||||||
|
// update the actual port m_listen_interface was derived from also
|
||||||
|
if (!m_listen_interfaces.empty())
|
||||||
|
m_listen_interfaces[0].second += 1;
|
||||||
|
--listen_port_retries;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (listen_port_retries > 0)
|
else
|
||||||
{
|
{
|
||||||
m_listen_interface.port(m_listen_interface.port() + 1);
|
m_external_udp_port = m_udp_socket.local_port();
|
||||||
// update the actual port m_listen_interface was derived from also
|
maybe_update_udp_mapping(0, false, m_listen_interface.port(), m_listen_interface.port());
|
||||||
if (!m_listen_interfaces.empty())
|
maybe_update_udp_mapping(1, false, m_listen_interface.port(), m_listen_interface.port());
|
||||||
m_listen_interfaces[0].second += 1;
|
|
||||||
--listen_port_retries;
|
|
||||||
goto retry;
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_external_udp_port = m_udp_socket.local_port();
|
|
||||||
maybe_update_udp_mapping(0, false, m_listen_interface.port(), m_listen_interface.port());
|
|
||||||
maybe_update_udp_mapping(1, false, m_listen_interface.port(), m_listen_interface.port());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we made it! now post all the listen_succeeded_alerts
|
// we made it! now post all the listen_succeeded_alerts
|
||||||
|
@ -2153,15 +2168,15 @@ retry:
|
||||||
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
|
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
|
||||||
, end(m_listen_sockets.end()); i != end; ++i)
|
, end(m_listen_sockets.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
listen_succeeded_alert::socket_type_t socket_type = i->ssl
|
listen_succeeded_alert::socket_type_t const socket_type = i->ssl
|
||||||
? listen_succeeded_alert::tcp_ssl
|
? listen_succeeded_alert::tcp_ssl
|
||||||
: listen_succeeded_alert::tcp;
|
: listen_succeeded_alert::tcp;
|
||||||
|
|
||||||
if (!m_alerts.should_post<listen_succeeded_alert>()) continue;
|
if (!m_alerts.should_post<listen_succeeded_alert>()) continue;
|
||||||
|
|
||||||
error_code err;
|
error_code error;
|
||||||
tcp::endpoint bind_ep = i->sock->local_endpoint(err);
|
tcp::endpoint bind_ep = i->sock->local_endpoint(error);
|
||||||
if (err) continue;
|
if (error) continue;
|
||||||
|
|
||||||
m_alerts.emplace_alert<listen_succeeded_alert>(bind_ep, socket_type);
|
m_alerts.emplace_alert<listen_succeeded_alert>(bind_ep, socket_type);
|
||||||
}
|
}
|
||||||
|
@ -2171,8 +2186,7 @@ retry:
|
||||||
{
|
{
|
||||||
if (m_alerts.should_post<listen_succeeded_alert>())
|
if (m_alerts.should_post<listen_succeeded_alert>())
|
||||||
m_alerts.emplace_alert<listen_succeeded_alert>(
|
m_alerts.emplace_alert<listen_succeeded_alert>(
|
||||||
tcp::endpoint(ssl_bind_if.address(), ssl_bind_if.port())
|
ssl_bind_ep, listen_succeeded_alert::utp_ssl);
|
||||||
, listen_succeeded_alert::utp_ssl);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -694,22 +694,13 @@ void udp_socket::close()
|
||||||
TORRENT_ASSERT(m_magic == 0x1337);
|
TORRENT_ASSERT(m_magic == 0x1337);
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
// if we close the socket here, we can't shut down
|
m_ipv4_sock.close(ec);
|
||||||
// utp connections or NAT-PMP. We need to cancel the
|
|
||||||
// outstanding operations
|
|
||||||
m_ipv4_sock.cancel(ec);
|
|
||||||
if (ec == error::operation_not_supported)
|
|
||||||
m_ipv4_sock.close(ec);
|
|
||||||
TORRENT_ASSERT_VAL(!ec || ec == error::bad_descriptor, ec);
|
TORRENT_ASSERT_VAL(!ec || ec == error::bad_descriptor, ec);
|
||||||
#if TORRENT_USE_IPV6
|
#if TORRENT_USE_IPV6
|
||||||
m_ipv6_sock.cancel(ec);
|
m_ipv6_sock.close(ec);
|
||||||
if (ec == error::operation_not_supported)
|
|
||||||
m_ipv6_sock.close(ec);
|
|
||||||
TORRENT_ASSERT_VAL(!ec || ec == error::bad_descriptor, ec);
|
TORRENT_ASSERT_VAL(!ec || ec == error::bad_descriptor, ec);
|
||||||
#endif
|
#endif
|
||||||
m_socks5_sock.cancel(ec);
|
m_socks5_sock.close(ec);
|
||||||
if (ec == error::operation_not_supported)
|
|
||||||
m_socks5_sock.close(ec);
|
|
||||||
TORRENT_ASSERT_VAL(!ec || ec == error::bad_descriptor, ec);
|
TORRENT_ASSERT_VAL(!ec || ec == error::bad_descriptor, ec);
|
||||||
m_resolver.cancel();
|
m_resolver.cancel();
|
||||||
m_timer.cancel();
|
m_timer.cancel();
|
||||||
|
|
Loading…
Reference in New Issue