diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 200d3088c..5a6f3ea15 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1516,7 +1516,6 @@ namespace aux { return ret; } ret->local_endpoint = ret->sock->local_endpoint(ec); - ret->device = lep.device; last_op = operation_t::getname; if (ec) { @@ -1534,7 +1533,6 @@ namespace aux { } return ret; } - ret->tracker_key = get_tracker_key(ret->local_endpoint.address()); ret->tcp_external_port = ret->local_endpoint.port(); TORRENT_ASSERT(ret->tcp_external_port == bind_ep.port() @@ -1565,7 +1563,7 @@ namespace aux { = (lep.ssl == transport::ssl) ? socket_type_t::utp_ssl : socket_type_t::udp; - udp::endpoint const udp_bind_ep(bind_ep.address(), bind_ep.port()); + udp::endpoint udp_bind_ep(bind_ep.address(), bind_ep.port()); ret->udp_sock = std::make_shared(m_io_service); ret->udp_sock->sock.open(udp_bind_ep.protocol(), ec); @@ -1613,6 +1611,36 @@ namespace aux { #endif ret->udp_sock->sock.bind(udp_bind_ep, ec); + while (ec == error_code(error::address_in_use) && retries > 0) + { + TORRENT_ASSERT_VAL(ec, ec); +#ifndef TORRENT_DISABLE_LOGGING + if (should_log()) + { + session_log("failed to bind udp socket to: %s on device: %s :" + " [%s] (%d) %s (retries: %d)" + , print_endpoint(bind_ep).c_str() + , lep.device.c_str() + , ec.category().name(), ec.value(), ec.message().c_str() + , retries); + } +#endif + ec.clear(); + --retries; + udp_bind_ep.port(udp_bind_ep.port() + 1); + ret->udp_sock->sock.bind(udp_bind_ep, ec); + } + + if (ec == error_code(error::address_in_use) + && m_settings.get_bool(settings_pack::listen_system_port_fallback) + && udp_bind_ep.port() != 0) + { + // instead of giving up, try let the OS pick a port + udp_bind_ep.port(0); + ec.clear(); + ret->udp_sock->sock.bind(udp_bind_ep, ec); + } + last_op = operation_t::sock_bind; if (ec) { @@ -1640,6 +1668,9 @@ namespace aux { ret->local_endpoint = tcp::endpoint(udp_ep.address(), udp_ep.port()); } + ret->tracker_key = get_tracker_key(ret->local_endpoint.address()); + ret->device = lep.device; + error_code err; set_socket_buffer_size(ret->udp_sock->sock, m_settings, err); if (err) @@ -2584,6 +2615,10 @@ namespace aux { } async_accept(listener, ssl); + // don't accept any connections from our local sockets + if (m_settings.get_bool(settings_pack::force_proxy)) + return; + #ifdef TORRENT_USE_OPENSSL if (ssl == transport::ssl) { diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index a0b79ff8d..6702b1cc4 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -434,11 +434,9 @@ void udp_socket::open(udp const& protocol, error_code& ec) #endif // this is best-effort. ignore errors - error_code err; #ifdef TORRENT_WINDOWS + error_code err; m_socket.set_option(exclusive_address_use(true), err); -#else - m_socket.set_option(boost::asio::socket_base::reuse_address(true), err); #endif }