Make HTTP server shutdown more graceful #6719

pull laanwj wants to merge 3 commits into bitcoin:master from laanwj:2015_09_rpc_shutdown_race changing 2 files +67 −10
  1. laanwj commented at 3:46 pm on September 24, 2015: member

    Shutting down the HTTP server currently breaks off all current requests. This can create a race condition with RPC stop command, where the calling process never receives confirmation.

    This change removes the listening sockets on shutdown so that no new requests can come in, but no longer breaks off requests in progress.

    Meant to fix #6717.

  2. laanwj added the label RPC on Sep 24, 2015
  3. laanwj added the label Tests on Sep 24, 2015
  4. dcousens commented at 6:49 am on September 25, 2015: contributor

    but no longer breaks off requests in progress.

    Possible attack vector by denying the service the ability to shut down / restart by keeping a connection open?

  5. laanwj commented at 7:40 am on September 25, 2015: member

    After -rpcservertimeout current connections will get booted, unless there is activity. If they do any requests they get a server unavailable error. But yes, if your application software is truly malicious they could keep the server busy by sending e.g. one header at a time, every timeout-1 seconds.

    Note that this solution is cleaner in any case, it doesn’t rule out queuing a event_base_loopbreak(eventBase);, say, 30 seconds in the future to force a shutdown.

  6. jonasschnelli commented at 9:17 am on September 25, 2015: contributor

    utACK.

    I agree that the attack vectors are out of scope for this PR maybe for the whole http-json-rpc-daemon (it’s not hardened enough to expose to potential malicious environments).

  7. dcousens commented at 10:00 am on September 25, 2015: contributor
    utACK, just thought I’d mention it.
  8. laanwj commented at 12:00 pm on September 25, 2015: member

    @dcousens It’s great that you mentioned it. It reminded me of potential issue of this: what happens if a timer is stilll running, will it block the event queue exit until it triggers? Will test this scenario by stopping with an unlocked wallet.

    Pushed another related fix:

    http: Wait for worker threads to exit

    Add a WaitExit() call to http’s WorkQueue to make StopHTTPServer delete the work queue only when all worker threads stopped.

    This fixes a problem that was reproducable by pressing Ctrl-C during AppInit2:

    0/usr/include/boost/thread/pthread/condition_variable_fwd.hpp:81: boost::condition_variable::~condition_variable(): Assertion `!ret' failed.
    1/usr/include/boost/thread/pthread/mutex.hpp:108: boost::mutex::~mutex(): Assertion `!posix::pthread_mutex_destroy(&m)' failed.
    

    I was assuming that threadGroup->join_all(); would always have been called when entering the Shutdown(). However this is not the case in bitcoind’s AppInit2-non-zero-exit case “was left out intentionally here”. (now that the http module takes care of waiting for its own worker threads, we could even make it stop using threadGroup completely, but I leave that for a future refactor)

  9. laanwj force-pushed on Sep 25, 2015
  10. laanwj commented at 1:39 pm on September 25, 2015: member
    Pushed another commit to force-exit the event loop after a predefined time after interruption. This addresses @dcousens ’s issue, as well as the case that other events are still lingering (such as a wallet unlock timer).
  11. dcousens commented at 2:19 pm on September 25, 2015: contributor
    utACK, well done @laanwj
  12. theuni commented at 9:35 pm on September 25, 2015: member
    Concept ACK, btw. Definitely an improvement.
  13. Make HTTP server shutdown more graceful
    Shutting down the HTTP server currently breaks off all current requests.
    This can create a race condition with RPC `stop` command, where the calling
    process never receives confirmation.
    
    This change removes the listening sockets on shutdown so that no new
    requests can come in, but no longer breaks off requests in progress.
    
    Meant to fix #6717.
    5e0c221356
  14. http: Wait for worker threads to exit
    Add a WaitExit() call to http's WorkQueue to make it delete the work
    queue only when all worker threads stopped.
    
    This fixes a problem that was reproducable by pressing Ctrl-C during
    AppInit2:
    ```
    /usr/include/boost/thread/pthread/condition_variable_fwd.hpp:81: boost::condition_variable::~condition_variable(): Assertion `!ret' failed.
    /usr/include/boost/thread/pthread/mutex.hpp:108: boost::mutex::~mutex(): Assertion `!posix::pthread_mutex_destroy(&m)' failed.
    ```
    
    I was assuming that `threadGroup->join_all();` would always have been
    called when entering the Shutdown(). However this is not the case in
    bitcoind's AppInit2-non-zero-exit case "was left out intentionally
    here".
    de9de2de36
  15. http: Force-exit event loop after predefined time
    This makes sure that the event loop eventually terminates, even if an
    event (like an open timeout, or a hanging connection) happens to be
    holding it up.
    ec908d5f7a
  16. laanwj force-pushed on Sep 28, 2015
  17. laanwj commented at 1:09 pm on September 28, 2015: member
    Processed @theuni ’s comments. WIll merge as soon as Travis passes.
  18. theuni commented at 1:35 pm on September 28, 2015: member
    Thanks. ut ACK.
  19. laanwj merged this on Sep 28, 2015
  20. laanwj closed this on Sep 28, 2015

  21. laanwj referenced this in commit 1a9f19a78d on Sep 28, 2015
  22. laanwj referenced this in commit 856be4fe46 on Nov 11, 2015
  23. laanwj referenced this in commit 1ec9198c68 on Nov 13, 2015
  24. laanwj referenced this in commit febcc13b18 on Nov 13, 2015
  25. laanwj referenced this in commit a264c32e33 on Nov 13, 2015
  26. zkbot referenced this in commit fb2f98e00b on Oct 23, 2017
  27. sickpig referenced this in commit 46b5b86be5 on Mar 9, 2018
  28. sickpig referenced this in commit dadc2880a1 on Mar 9, 2018
  29. sickpig referenced this in commit 6d4a55878a on Mar 12, 2018
  30. sickpig referenced this in commit 6db640a393 on Mar 12, 2018
  31. sickpig referenced this in commit 76cf243311 on Mar 12, 2018
  32. sickpig referenced this in commit 4428056252 on Mar 12, 2018
  33. marlengit referenced this in commit 297ac08c3a on Sep 25, 2018
  34. MarcoFalke 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: 2024-10-05 01:12 UTC

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