Merge pull request #1046 from laanwj/2012_04_rpcporterror
authorWladimir J. van der Laan <laanwj@gmail.com>
Tue, 10 Apr 2012 20:14:47 +0000 (13:14 -0700)
committerWladimir J. van der Laan <laanwj@gmail.com>
Tue, 10 Apr 2012 20:14:47 +0000 (13:14 -0700)
Show error message instead of exception crash when unable to bind RPC port

1  2 
src/bitcoinrpc.cpp

diff --combined src/bitcoinrpc.cpp
@@@ -15,6 -15,7 +15,6 @@@
  #include <boost/algorithm/string.hpp>
  #include <boost/lexical_cast.hpp>
  #include <boost/asio/ssl.hpp> 
 -#include <boost/filesystem.hpp>
  #include <boost/filesystem/fstream.hpp>
  typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
  
@@@ -1647,8 -1648,8 +1647,8 @@@ Value walletlock(const Array& params, b
      if (!pwalletMain->IsCrypted())
          throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
  
 -    CRITICAL_BLOCK(cs_nWalletUnlockTime)
      {
 +        LOCK(cs_nWalletUnlockTime);
          pwalletMain->Lock();
          nWalletUnlockTime = 0;
      }
@@@ -2376,29 -2377,38 +2376,41 @@@ void ThreadRPCServer2(void* parg
  
      asio::io_service io_service;
      ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332));
-     ip::tcp::acceptor acceptor(io_service, endpoint);
-     acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+     ip::tcp::acceptor acceptor(io_service);
+     try
+     {
+         acceptor.open(endpoint.protocol());
+         acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+         acceptor.bind(endpoint);
+         acceptor.listen(socket_base::max_connections);
+     }
+     catch(system::system_error &e)
+     {
+         ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
+                              _("Error"), wxOK | wxMODAL);
+         QueueShutdown();
+         return;
+     }
  
      ssl::context context(io_service, ssl::context::sslv23);
      if (fUseSSL)
      {
          context.set_options(ssl::context::no_sslv2);
 -        filesystem::path certfile = GetArg("-rpcsslcertificatechainfile", "server.cert");
 -        if (!certfile.is_complete()) certfile = filesystem::path(GetDataDir()) / certfile;
 -        if (filesystem::exists(certfile)) context.use_certificate_chain_file(certfile.string().c_str());
 -        else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", certfile.string().c_str());
 -        filesystem::path pkfile = GetArg("-rpcsslprivatekeyfile", "server.pem");
 -        if (!pkfile.is_complete()) pkfile = filesystem::path(GetDataDir()) / pkfile;
 -        if (filesystem::exists(pkfile)) context.use_private_key_file(pkfile.string().c_str(), ssl::context::pem);
 -        else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pkfile.string().c_str());
 -
 -        string ciphers = GetArg("-rpcsslciphers",
 -                                         "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
 -        SSL_CTX_set_cipher_list(context.impl(), ciphers.c_str());
 +
 +        filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
 +        if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile;
 +        pathCertFile.make_preferred();
 +        if (filesystem::exists(pathCertFile)) context.use_certificate_chain_file(pathCertFile.string().c_str());
 +        else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
 +
 +        filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
 +        if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile;
 +        pathPKFile.make_preferred();
 +        if (filesystem::exists(pathPKFile)) context.use_private_key_file(pathPKFile.string().c_str(), ssl::context::pem);
 +        else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
 +
 +        string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
 +        SSL_CTX_set_cipher_list(context.impl(), strCiphers.c_str());
      }
  
      loop
              {
                  // Execute
                  Value result;
 -                CRITICAL_BLOCK(cs_main)
 -                CRITICAL_BLOCK(pwalletMain->cs_wallet)
 +                {
 +                    LOCK2(cs_main, pwalletMain->cs_wallet);
                      result = (*(*mi).second)(params, false);
 +                }
  
                  // Send reply
                  string strReply = JSONRPCReply(result, Value::null, id);