From c1d79812f428860e6f624835851d6f3ecd86bbb3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 12 Sep 2012 16:45:01 +0200 Subject: [PATCH] Do not abort if RPC listening for IPv6 fails Instead, fall back to IPv4 listening. --- src/bitcoinrpc.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 84a6d6f89648a..fa392363616a4 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -761,17 +761,19 @@ void ThreadRPCServer2(void* parg) const bool loopback = !mapArgs.count("-rpcallowip"); asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any(); ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332)); + boost::system::error_code v6_only_error; + boost::shared_ptr acceptor(new ip::tcp::acceptor(io_service)); boost::signals2::signal StopRequests; + bool fListening = false; + std::string strerr; try { - boost::shared_ptr acceptor(new ip::tcp::acceptor(io_service)); acceptor->open(endpoint.protocol()); acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); // Try making the socket dual IPv6/IPv4 (if listening on the "any" address) - boost::system::error_code v6_only_error; acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error); acceptor->bind(endpoint); @@ -783,8 +785,16 @@ void ThreadRPCServer2(void* parg) static_cast(&ip::tcp::acceptor::close), acceptor.get()) .track(acceptor)); + fListening = true; + } + catch(boost::system::system_error &e) + { + strerr = strprintf(_("An error occurred while setting up the RPC port %i for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what()); + } + + try { // If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately - if (loopback || v6_only_error) + if (!fListening || loopback || v6_only_error) { bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any(); endpoint.address(bindAddress); @@ -800,12 +810,17 @@ void ThreadRPCServer2(void* parg) StopRequests.connect(signals2::slot( static_cast(&ip::tcp::acceptor::close), acceptor.get()) .track(acceptor)); + + fListening = true; } } catch(boost::system::system_error &e) { - uiInterface.ThreadSafeMessageBox(strprintf(_("An error occurred while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()), - _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); + strerr = strprintf(_("An error occurred while setting up the RPC port %i for listening on IPv4: %s"), endpoint.port(), e.what()); + } + + if (!fListening) { + uiInterface.ThreadSafeMessageBox(strerr, _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL); StartShutdown(); return; }