From 9554bd105da340512bea18be68c8f4391bd4bc7c Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 24 Feb 2017 15:10:50 -0500 Subject: [PATCH] Fix race in close frames during reads --- CHANGELOG.md | 1 + include/beast/websocket/impl/close.ipp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 710b879b..cee21d97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ WebSocket * Fix race in pings during reads +* Fix race in close frames during reads -------------------------------------------------------------------------------- diff --git a/include/beast/websocket/impl/close.ipp b/include/beast/websocket/impl/close.ipp index 0ad5992b..6bf3a452 100644 --- a/include/beast/websocket/impl/close.ipp +++ b/include/beast/websocket/impl/close.ipp @@ -147,25 +147,33 @@ operator()(error_code ec, bool again) boost::asio::error::operation_aborted)); return; } - // fall through + d.ws.wr_block_ = &d; + // [[fallthrough]] case 1: // send close frame + BOOST_ASSERT(d.ws.wr_block_ == &d); d.state = 99; d.ws.wr_close_ = true; - BOOST_ASSERT(! d.ws.wr_block_); - d.ws.wr_block_ = &d; boost::asio::async_write(d.ws.stream_, d.fb.data(), std::move(*this)); return; case 2: + BOOST_ASSERT(! d.ws.wr_block_); + d.ws.wr_block_ = &d; d.state = 3; + // The current context is safe but might not be + // the same as the one for this operation (since + // we are being called from a write operation). + // Call post to make sure we are invoked the same + // way as the final handler for this operation. d.ws.get_io_service().post( bind_handler(std::move(*this), ec)); return; case 3: + BOOST_ASSERT(d.ws.wr_block_ == &d); if(d.ws.failed_ || d.ws.wr_close_) { // call handler