Add -rpcbind option to allow binding RPC port on a specific interface #3695

pull laanwj wants to merge 3 commits into bitcoin:master from laanwj:2014_02_bind_improvements changing 6 files +396 −44
  1. laanwj commented at 5:37 PM on February 17, 2014: member

    Add -rpcbind command option to specify binding RPC service on one or multiple specific interfaces.

    Functionality if -rpcbind is not specified remains the same as before:

    • If no -rpcallowip specified, bind on localhost
    • If no -rpcbind specified, bind on any interface

    Implements part of #3111.

  2. jgarzik commented at 5:48 PM on February 17, 2014: contributor

    Overall, happy to see this.

    1. style is inconsistent with the rest of the core code, in minor ways: "if" keyword should be followed by a space. '{' follows else on same line. '{' follows try on same line. etc.

    2. a common interface for specifying bind addresses in unix daemons is specifying address/port pairs. This seems preferable to the current setup, which forces -rpcport on all bind addresses, when it really should just be a default.

    3. I'm not confident this v4/v6 handling code will work on both Linux and non-Linux. At a minimum, push_back'ing v4+v6, then cleaning up, seems error prone. Regardless... v4+v6 and v4-only cases need testing on both Linux and OSX (BSD-derived) to cover main use cases, IIRC.

  3. laanwj commented at 7:55 AM on February 18, 2014: member
    1. OK
    2. OK
    3. It follows the same logic in the bindany case as the old code, except that it's rolled into a loop (to make for shorter code). The idea is to
    • Try dual binding with boost::asio::ip::v6_only(false) when binding the asio::ip::address_v6::any() address
    • If this is succesful (!v6_only_error) and binding succeeded, stop trying, we're there
    • If this is not succesful (v6_only_error) and binding succeeded, we've only bound v6, so go around another loop to bind asio::ip::address_v4::any() as well
    • If binding did not succeed, we've not bound v6, so go around another loop to bind asio::ip::address_v4::any()

    If it makes you more comfortable I can just keep the old code as-is in the bindany case and only use new code if binding to explicit addresses or localhosts.

  4. laanwj commented at 8:31 AM on February 18, 2014: member

    I've updated the code style and made the bindany logic more explicit.

    I'll add parsing IPv4:port and [IPv6]:port later. It doesn't seem that boost has a built-in function for this, so I'll either have to

    • use Lookup (from netbase.cpp) with fAllowLookup=false as used for -bind and convert the result CService to boost address/port. This would introduce a dependency between the RPC and NET code.
    • or re-implement the simple parsing with Boost.

    I think the second option is better. Well SplitHostPort is extremely convenient here, I think I'm going with that, it's just a string utility function after all and doesn't use CService...

    Edit: looks like the boost::ip::resolver has numeric_host and numeric_service flags, that sounds promising, it may just do what we want. Except that it doesn't do the splitting part that we need here at all

  5. laanwj commented at 9:20 AM on February 18, 2014: member

    Voila, that was easy. Using SplitHostPort does introduce a dependency of rpc on netbase, but it is just a string parsing function and doesn't need to pull in any of the CService stuff so it could be moved somewhere else if that ever becomes a problem.

    Testing now please!

  6. in src/init.cpp:None in ec7961d45f outdated
     255 | @@ -256,6 +256,7 @@ bool static Bind(const CService &addr, unsigned int flags) {
     256 |      strUsage += "  -rpcport=<port>        " + _("Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)") + "\n";
     257 |      strUsage += "  -rpcallowip=<ip>       " + _("Allow JSON-RPC connections from specified IP address") + "\n";
     258 |      strUsage += "  -rpcthreads=<n>        " + _("Set the number of threads to service RPC calls (default: 4)") + "\n";
     259 | +    strUsage += "  -rpcbind=<addr>        " + _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6") + "\n";
    


    Diapolo commented at 12:19 PM on February 18, 2014:

    Perhaps mention the default (default: bind to all interfaces) here?


    laanwj commented at 12:46 PM on February 18, 2014:

    Agreed; although the full behavior is more complicated than that

    • unless -rpcallowip is specified, it binds to localhost
    • if one or more -rpcallowip and one or more -rpcbind is specified, bind to those specific addresses
    • if one or more -rpcallowip and no -rpcbind is specified, bind to all interfaces

    But listing all of that in the command line options help is too verbose. (default: bind to all interfaces) might be enough as it is true unless the option is ignored.

  7. jgarzik commented at 1:57 PM on February 18, 2014: contributor

    untested ACK

  8. laanwj commented at 3:36 PM on April 7, 2014: member

    Rebased and added an extensive Python-based test.

  9. laanwj commented at 4:16 PM on April 7, 2014: member

    Weird, seemingly the flags argument to resolver_query doesn't exist yet in the old boost that the pulltester uses. Will need an #ifdef here.

    rpcprotocol.h: In member function ‘bool SSLIOStreamDevice<Protocol>::connect(const std::string&, const std::string&)’:
    rpcprotocol.h:117: error: ‘flags’ is not a member of ‘boost::asio::ip::resolver_query_base’
    

    Edit: fixed

  10. Add -rpcbind option to allow binding RPC port on a specific interface
    Add -rpcbind command option to specify binding RPC service on one
    or multiple specific interfaces.
    
    Functionality if -rpcbind is not specified remains the same as before:
    
    - If no -rpcallowip specified, bind on localhost
    - If no -rpcbind specified, bind on any interface
    
    Implements part of #3111.
    deb3572ab1
  11. Support IPv6 lookup in bitcoin-cli even when IPv6 only bound on localhost
    First query in the current way (intelligently determining which network
    has a non-localhost interface). If this does not succeed, try plain
    lookup.
    
    Needed for testing.
    
    Fixes #1827 by always allowing IPv6 to be used.
    f923c07754
  12. Add Python test for -rpcbind and -rpcallowip
    Add a new test, `rpcbind_test.py`, that extensively tests the new
    `-rpcbind` functionality.
    b5ad5e783d
  13. BitcoinPullTester commented at 6:05 AM on May 13, 2014: none

    Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/b5ad5e783d6f636d5ca5703919d05fd0119a34fc for binaries and test log. This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/ Contact BlueMatt on freenode if something looks broken.

  14. laanwj merged this on May 13, 2014
  15. laanwj closed this on May 13, 2014

  16. laanwj referenced this in commit 29c1fbbb97 on May 13, 2014
  17. DrahtBot locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-13 15:16 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me