diff options
Diffstat (limited to 'boost/beast/websocket')
-rw-r--r-- | boost/beast/websocket/detail/decorator.hpp | 9 | ||||
-rw-r--r-- | boost/beast/websocket/detail/frame.hpp | 126 | ||||
-rw-r--r-- | boost/beast/websocket/detail/hybi13.ipp | 21 | ||||
-rw-r--r-- | boost/beast/websocket/detail/mask.hpp | 55 | ||||
-rw-r--r-- | boost/beast/websocket/detail/mask.ipp | 66 | ||||
-rw-r--r-- | boost/beast/websocket/detail/pmd_extension.ipp | 10 | ||||
-rw-r--r-- | boost/beast/websocket/detail/prng.hpp | 79 | ||||
-rw-r--r-- | boost/beast/websocket/detail/prng.ipp | 294 | ||||
-rw-r--r-- | boost/beast/websocket/impl/accept.hpp | 14 | ||||
-rw-r--r-- | boost/beast/websocket/impl/close.hpp | 2 | ||||
-rw-r--r-- | boost/beast/websocket/impl/handshake.hpp | 2 | ||||
-rw-r--r-- | boost/beast/websocket/impl/ping.hpp | 7 | ||||
-rw-r--r-- | boost/beast/websocket/impl/read.hpp | 23 | ||||
-rw-r--r-- | boost/beast/websocket/impl/stream.hpp | 12 | ||||
-rw-r--r-- | boost/beast/websocket/impl/stream_impl.hpp | 56 | ||||
-rw-r--r-- | boost/beast/websocket/impl/teardown.hpp | 4 | ||||
-rw-r--r-- | boost/beast/websocket/impl/write.hpp | 2 | ||||
-rw-r--r-- | boost/beast/websocket/option.hpp | 9 | ||||
-rw-r--r-- | boost/beast/websocket/stream.hpp | 3 |
19 files changed, 245 insertions, 549 deletions
diff --git a/boost/beast/websocket/detail/decorator.hpp b/boost/beast/websocket/detail/decorator.hpp index cab7f9a298..03c1c8f637 100644 --- a/boost/beast/websocket/detail/decorator.hpp +++ b/boost/beast/websocket/detail/decorator.hpp @@ -11,7 +11,6 @@ #define BOOST_BEAST_WEBSOCKET_DETAIL_DECORATOR_HPP #include <boost/beast/websocket/rfc6455.hpp> -#include <boost/beast/core/detail/type_traits.hpp> #include <boost/core/exchange.hpp> #include <boost/type_traits/make_void.hpp> #include <algorithm> @@ -213,7 +212,7 @@ struct decorator::vtable_impl<F, true> void move(storage& dst, storage& src) noexcept { - auto& f = *reinterpret_cast<F*>(&src.buf_); + auto& f = *beast::detail::launder_cast<F*>(&src.buf_); ::new (&dst.buf_) F(std::move(f)); } @@ -221,7 +220,7 @@ struct decorator::vtable_impl<F, true> void destroy(storage& dst) noexcept { - reinterpret_cast<F*>(&dst.buf_)->~F(); + beast::detail::launder_cast<F*>(&dst.buf_)->~F(); } static @@ -229,7 +228,7 @@ struct decorator::vtable_impl<F, true> invoke_req(storage& dst, request_type& req) { maybe_invoke<F, request_type>{}( - *reinterpret_cast<F*>(&dst.buf_), req); + *beast::detail::launder_cast<F*>(&dst.buf_), req); } static @@ -237,7 +236,7 @@ struct decorator::vtable_impl<F, true> invoke_res(storage& dst, response_type& res) { maybe_invoke<F, response_type>{}( - *reinterpret_cast<F*>(&dst.buf_), res); + *beast::detail::launder_cast<F*>(&dst.buf_), res); } static diff --git a/boost/beast/websocket/detail/frame.hpp b/boost/beast/websocket/detail/frame.hpp index 1603bb556e..f217e04a52 100644 --- a/boost/beast/websocket/detail/frame.hpp +++ b/boost/beast/websocket/detail/frame.hpp @@ -14,20 +14,10 @@ #include <boost/beast/websocket/error.hpp> #include <boost/beast/websocket/rfc6455.hpp> #include <boost/beast/websocket/detail/utf8_checker.hpp> -#include <boost/beast/core/buffers_suffix.hpp> #include <boost/beast/core/flat_static_buffer.hpp> -#include <boost/beast/core/static_string.hpp> #include <boost/asio/buffer.hpp> #include <boost/assert.hpp> -// This is for <boost/endian/buffers.hpp> -#if BOOST_WORKAROUND(BOOST_MSVC, > 0) -# pragma warning (push) -# pragma warning (disable: 4127) // conditional expression is constant -#endif -#include <boost/endian/buffers.hpp> -#if BOOST_WORKAROUND(BOOST_MSVC, > 0) -# pragma warning (pop) -#endif +#include <boost/endian/conversion.hpp> #include <cstdint> namespace boost { @@ -35,56 +25,6 @@ namespace beast { namespace websocket { namespace detail { -inline -std::uint16_t -big_uint16_to_native(void const* buf) -{ - auto const p = static_cast< - std::uint8_t const*>(buf); - return (p[0]<<8) + p[1]; -} - -inline -std::uint64_t -big_uint64_to_native(void const* buf) -{ - auto const p = static_cast< - std::uint8_t const*>(buf); - return - (static_cast<std::uint64_t>(p[0])<<56) + - (static_cast<std::uint64_t>(p[1])<<48) + - (static_cast<std::uint64_t>(p[2])<<40) + - (static_cast<std::uint64_t>(p[3])<<32) + - (static_cast<std::uint64_t>(p[4])<<24) + - (static_cast<std::uint64_t>(p[5])<<16) + - (static_cast<std::uint64_t>(p[6])<< 8) + - p[7]; -} - -inline -std::uint32_t -little_uint32_to_native(void const* buf) -{ - auto const p = static_cast< - std::uint8_t const*>(buf); - return - p[0] + - (static_cast<std::uint32_t>(p[1])<< 8) + - (static_cast<std::uint32_t>(p[2])<<16) + - (static_cast<std::uint32_t>(p[3])<<24); -} - -inline -void -native_to_little_uint32(std::uint32_t v, void* buf) -{ - auto p = static_cast<std::uint8_t*>(buf); - p[0] = v & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; -} - // frame header opcodes enum class opcode : std::uint8_t { @@ -193,7 +133,6 @@ template<class DynamicBuffer> void write(DynamicBuffer& db, frame_header const& fh) { - using namespace boost::endian; std::size_t n; std::uint8_t b[14]; b[0] = (fh.fin ? 0x80 : 0x00) | static_cast<std::uint8_t>(fh.op); @@ -212,19 +151,24 @@ write(DynamicBuffer& db, frame_header const& fh) else if(fh.len <= 65535) { b[1] |= 126; - ::new(&b[2]) big_uint16_buf_t{ - (std::uint16_t)fh.len}; + auto len_be = endian::native_to_big( + static_cast<std::uint16_t>(fh.len)); + std::memcpy(&b[2], &len_be, sizeof(len_be)); n = 4; } else { b[1] |= 127; - ::new(&b[2]) big_uint64_buf_t{fh.len}; + auto len_be = endian::native_to_big( + static_cast<std::uint64_t>(fh.len)); + std::memcpy(&b[2], &len_be, sizeof(len_be)); n = 10; } if(fh.mask) { - native_to_little_uint32(fh.key, &b[n]); + auto key_le = endian::native_to_little( + static_cast<std::uint32_t>(fh.key)); + std::memcpy(&b[n], &key_le, sizeof(key_le)); n += 4; } db.commit(net::buffer_copy( @@ -254,8 +198,7 @@ read_close( Buffers const& bs, error_code& ec) { - using namespace boost::endian; - auto n = buffer_bytes(bs); + auto const n = buffer_bytes(bs); BOOST_ASSERT(n <= 125); if(n == 0) { @@ -269,36 +212,29 @@ read_close( ec = error::bad_close_size; return; } - buffers_suffix<Buffers> cb(bs); - { - std::uint8_t b[2]; - net::buffer_copy(net::buffer(b), cb); - cr.code = big_uint16_to_native(&b[0]); - cb.consume(2); - n -= 2; - if(! is_valid_close_code(cr.code)) - { - // invalid close code - ec = error::bad_close_code; - return; - } - } - if(n > 0) + + std::uint16_t code_be; + cr.reason.resize(n - 2); + std::array<net::mutable_buffer, 2> out_bufs{{ + net::mutable_buffer(&code_be, sizeof(code_be)), + net::mutable_buffer(&cr.reason[0], n - 2)}}; + + net::buffer_copy(out_bufs, bs); + + cr.code = endian::big_to_native(code_be); + if(! is_valid_close_code(cr.code)) { - cr.reason.resize(n); - net::buffer_copy( - net::buffer(&cr.reason[0], n), cb); - if(! check_utf8( - cr.reason.data(), cr.reason.size())) - { - // not valid utf-8 - ec = error::bad_close_payload; - return; - } + // invalid close code + ec = error::bad_close_code; + return; } - else + + if(n > 2 && !check_utf8( + cr.reason.data(), cr.reason.size())) { - cr.reason = ""; + // not valid utf-8 + ec = error::bad_close_payload; + return; } ec = {}; } diff --git a/boost/beast/websocket/detail/hybi13.ipp b/boost/beast/websocket/detail/hybi13.ipp index b0ed57756b..0cbab15372 100644 --- a/boost/beast/websocket/detail/hybi13.ipp +++ b/boost/beast/websocket/detail/hybi13.ipp @@ -27,18 +27,12 @@ void make_sec_ws_key(sec_ws_key_type& key) { auto g = make_prng(true); - char a[16]; - for(int i = 0; i < 16; i += 4) - { - auto const v = g(); - a[i ] = v & 0xff; - a[i+1] = (v >> 8) & 0xff; - a[i+2] = (v >> 16) & 0xff; - a[i+3] = (v >> 24) & 0xff; - } + std::uint32_t a[4]; + for (auto& v : a) + v = g(); key.resize(key.max_size()); key.resize(beast::detail::base64::encode( - key.data(), &a[0], 16)); + key.data(), &a[0], sizeof(a))); } void @@ -47,11 +41,12 @@ make_sec_ws_accept( string_view key) { BOOST_ASSERT(key.size() <= sec_ws_key_type::max_size_n); - static_string<sec_ws_key_type::max_size_n + 36> m(key); - m.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + using namespace beast::detail::string_literals; + auto const guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"_sv; beast::detail::sha1_context ctx; beast::detail::init(ctx); - beast::detail::update(ctx, m.data(), m.size()); + beast::detail::update(ctx, key.data(), key.size()); + beast::detail::update(ctx, guid.data(), guid.size()); char digest[beast::detail::sha1_context::digest_size]; beast::detail::finish(ctx, &digest[0]); accept.resize(accept.max_size()); diff --git a/boost/beast/websocket/detail/mask.hpp b/boost/beast/websocket/detail/mask.hpp index ade89fdae5..58797372e5 100644 --- a/boost/beast/websocket/detail/mask.hpp +++ b/boost/beast/websocket/detail/mask.hpp @@ -26,62 +26,27 @@ namespace detail { using prepared_key = std::array<unsigned char, 4>; -inline +BOOST_BEAST_DECL void -prepare_key(prepared_key& prepared, std::uint32_t key) -{ - prepared[0] = (key >> 0) & 0xff; - prepared[1] = (key >> 8) & 0xff; - prepared[2] = (key >> 16) & 0xff; - prepared[3] = (key >> 24) & 0xff; -} - -template<std::size_t N> -void -rol(std::array<unsigned char, N>& v, std::size_t n) -{ - auto v0 = v; - for(std::size_t i = 0; i < v.size(); ++i ) - v[i] = v0[(i + n) % v.size()]; -} +prepare_key(prepared_key& prepared, std::uint32_t key); // Apply mask in place // -inline +BOOST_BEAST_DECL void -mask_inplace(net::mutable_buffer& b, prepared_key& key) -{ - auto n = b.size(); - auto mask = key; // avoid aliasing - auto p = static_cast<unsigned char*>(b.data()); - while(n >= 4) - { - for(int i = 0; i < 4; ++i) - p[i] ^= mask[i]; - p += 4; - n -= 4; - } - if(n > 0) - { - for(std::size_t i = 0; i < n; ++i) - p[i] ^= mask[i]; - rol(key, n); - } -} +mask_inplace(net::mutable_buffer const& b, prepared_key& key); // Apply mask in place // -template< - class MutableBufferSequence, - class KeyType> +template<class MutableBufferSequence> void mask_inplace( MutableBufferSequence const& buffers, - KeyType& key) + prepared_key& key) { for(net::mutable_buffer b : beast::buffers_range_ref(buffers)) - mask_inplace(b, key); + detail::mask_inplace(b, key); } } // detail @@ -89,4 +54,10 @@ mask_inplace( } // beast } // boost + +#if BOOST_BEAST_HEADER_ONLY +#include <boost/beast/websocket/detail/mask.ipp> +#endif + + #endif diff --git a/boost/beast/websocket/detail/mask.ipp b/boost/beast/websocket/detail/mask.ipp new file mode 100644 index 0000000000..6c36d56bc1 --- /dev/null +++ b/boost/beast/websocket/detail/mask.ipp @@ -0,0 +1,66 @@ +// +// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +#ifndef BOOST_BEAST_WEBSOCKET_DETAIL_MASK_IPP +#define BOOST_BEAST_WEBSOCKET_DETAIL_MASK_IPP + +#include <boost/beast/websocket/detail/mask.hpp> + +namespace boost { +namespace beast { +namespace websocket { +namespace detail { + +void +prepare_key(prepared_key& prepared, std::uint32_t key) +{ + prepared[0] = (key >> 0) & 0xff; + prepared[1] = (key >> 8) & 0xff; + prepared[2] = (key >> 16) & 0xff; + prepared[3] = (key >> 24) & 0xff; +} + +inline +void +rol(prepared_key& v, std::size_t n) +{ + auto v0 = v; + for(std::size_t i = 0; i < v.size(); ++i ) + v[i] = v0[(i + n) % v.size()]; +} + +// Apply mask in place +// +void +mask_inplace(net::mutable_buffer const& b, prepared_key& key) +{ + auto n = b.size(); + auto const mask = key; // avoid aliasing + auto p = static_cast<unsigned char*>(b.data()); + while(n >= 4) + { + for(int i = 0; i < 4; ++i) + p[i] ^= mask[i]; + p += 4; + n -= 4; + } + if(n > 0) + { + for(std::size_t i = 0; i < n; ++i) + p[i] ^= mask[i]; + rol(key, n); + } +} + +} // detail +} // websocket +} // beast +} // boost + +#endif diff --git a/boost/beast/websocket/detail/pmd_extension.ipp b/boost/beast/websocket/detail/pmd_extension.ipp index 790998e8ff..005feec19d 100644 --- a/boost/beast/websocket/detail/pmd_extension.ipp +++ b/boost/beast/websocket/detail/pmd_extension.ipp @@ -52,11 +52,11 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list) for(auto const& ext : list) { - if(iequals(ext.first, "permessage-deflate")) + if(beast::iequals(ext.first, "permessage-deflate")) { for(auto const& param : ext.second) { - if(iequals(param.first, + if(beast::iequals(param.first, "server_max_window_bits")) { if(offer.server_max_window_bits != 0) @@ -84,7 +84,7 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list) return; // MUST decline } } - else if(iequals(param.first, + else if(beast::iequals(param.first, "client_max_window_bits")) { if(offer.client_max_window_bits != 0) @@ -112,7 +112,7 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list) offer.client_max_window_bits = -1; } } - else if(iequals(param.first, + else if(beast::iequals(param.first, "server_no_context_takeover")) { if(offer.server_no_context_takeover) @@ -131,7 +131,7 @@ pmd_read_impl(pmd_offer& offer, http::ext_list const& list) } offer.server_no_context_takeover = true; } - else if(iequals(param.first, + else if(beast::iequals(param.first, "client_no_context_takeover")) { if(offer.client_no_context_takeover) diff --git a/boost/beast/websocket/detail/prng.hpp b/boost/beast/websocket/detail/prng.hpp index 35409b5837..6eb474f2f0 100644 --- a/boost/beast/websocket/detail/prng.hpp +++ b/boost/beast/websocket/detail/prng.hpp @@ -11,8 +11,8 @@ #define BOOST_BEAST_WEBSOCKET_DETAIL_PRNG_HPP #include <boost/beast/core/detail/config.hpp> +#include <boost/config.hpp> #include <cstdint> -#include <limits> #include <random> namespace boost { @@ -20,66 +20,7 @@ namespace beast { namespace websocket { namespace detail { -// Type-erased UniformRandomBitGenerator -// with 32-bit unsigned integer value_type -// -class prng -{ -protected: - virtual ~prng() = default; - virtual prng& acquire() noexcept = 0; - virtual void release() noexcept = 0; - virtual std::uint32_t operator()() noexcept = 0; - -public: - using value_type = std::uint32_t; - - class ref - { - prng& p_; - - public: - ref& operator=(ref const&) = delete; - - ~ref() - { - p_.release(); - } - - explicit - ref(prng& p) noexcept - : p_(p.acquire()) - { - } - - ref(ref const& other) noexcept - : p_(other.p_.acquire()) - { - } - - value_type - operator()() noexcept - { - return p_(); - } - - static - value_type constexpr - min() noexcept - { - return (std::numeric_limits< - value_type>::min)(); - } - - static - value_type constexpr - max() noexcept - { - return (std::numeric_limits< - value_type>::max)(); - } - }; -}; +using generator = std::uint32_t(*)(); //------------------------------------------------------------------------------ @@ -90,25 +31,11 @@ BOOST_BEAST_DECL std::uint32_t const* prng_seed(std::seed_seq* ss = nullptr); -// Acquire a PRNG using the no-TLS implementation -// -BOOST_BEAST_DECL -prng::ref -make_prng_no_tls(bool secure); - -// Acquire a PRNG using the TLS implementation -// -#ifndef BOOST_NO_CXX11_THREAD_LOCAL -BOOST_BEAST_DECL -prng::ref -make_prng_tls(bool secure); -#endif - // Acquire a PRNG using the TLS implementation if it // is available, otherwise using the no-TLS implementation. // BOOST_BEAST_DECL -prng::ref +generator make_prng(bool secure); } // detail diff --git a/boost/beast/websocket/detail/prng.ipp b/boost/beast/websocket/detail/prng.ipp index 2807ca96e9..2d4e7f2771 100644 --- a/boost/beast/websocket/detail/prng.ipp +++ b/boost/beast/websocket/detail/prng.ipp @@ -13,14 +13,10 @@ #include <boost/beast/websocket/detail/prng.hpp> #include <boost/beast/core/detail/chacha.hpp> #include <boost/beast/core/detail/pcg.hpp> -#include <boost/align/aligned_alloc.hpp> -#include <boost/throw_exception.hpp> #include <atomic> #include <cstdlib> #include <mutex> -#include <new> #include <random> -#include <stdexcept> namespace boost { namespace beast { @@ -59,264 +55,92 @@ prng_seed(std::seed_seq* ss) //------------------------------------------------------------------------------ -template<class T> -class prng_pool +inline +std::uint32_t +make_nonce() { - std::mutex m_; - T* head_ = nullptr; - -public: - static - prng_pool& - instance() - { - static prng_pool p; - return p; - } - - ~prng_pool() - { - for(auto p = head_; p;) - { - auto next = p->next; - p->~T(); - boost::alignment::aligned_free(p); - p = next; - } - } + static std::atomic<std::uint32_t> nonce{0}; + return ++nonce; +} - prng::ref - acquire() - { - { - std::lock_guard< - std::mutex> g(m_); - if(head_) - { - auto p = head_; - head_ = head_->next; - return prng::ref(*p); - } - } - auto p = boost::alignment::aligned_alloc( - 16, sizeof(T)); - if(! p) - BOOST_THROW_EXCEPTION(std::bad_alloc{}); - return prng::ref(*(::new(p) T())); - } +inline +beast::detail::pcg make_pcg() +{ + auto const pv = prng_seed(); + return beast::detail::pcg{ + ((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^ + ((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^ + ((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^ + ((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]), make_nonce()}; +} - void - release(T& t) - { - std::lock_guard< - std::mutex> g(m_); - t.next = head_; - head_ = &t; - } -}; +#ifdef BOOST_NO_CXX11_THREAD_LOCAL -prng::ref -make_prng_no_tls(bool secure) +inline +std::uint32_t +secure_generate() { - class fast_prng final : public prng + struct generator { - int refs_ = 0; - beast::detail::pcg r_; - - public: - fast_prng* next = nullptr; - - fast_prng() - : r_( - []{ - auto const pv = prng_seed(); - return - ((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^ - ((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^ - ((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^ - ((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]); - }(), - []{ - static std::atomic< - std::uint32_t> nonce{0}; - return ++nonce; - }()) - { - } - - protected: - prng& - acquire() noexcept override + std::uint32_t operator()() { - ++refs_; - return *this; + std::lock_guard<std::mutex> guard{mtx}; + return gen(); } - void - release() noexcept override - { - if(--refs_ == 0) - prng_pool<fast_prng>::instance().release(*this); - } - - value_type - operator()() noexcept override - { - return r_(); - } + beast::detail::chacha<20> gen; + std::mutex mtx; }; - - class secure_prng final : public prng - { - int refs_ = 0; - beast::detail::chacha<20> r_; - - public: - secure_prng* next = nullptr; - - secure_prng() - : r_(prng_seed(), [] - { - static std::atomic< - std::uint64_t> nonce{0}; - return ++nonce; - }()) - { - } - - protected: - prng& - acquire() noexcept override - { - ++refs_; - return *this; - } - - void - release() noexcept override - { - if(--refs_ == 0) - prng_pool<secure_prng>::instance().release(*this); - } - - value_type - operator()() noexcept override - { - return r_(); - } - }; - - if(secure) - return prng_pool<secure_prng>::instance().acquire(); - - return prng_pool<fast_prng>::instance().acquire(); + static generator gen{beast::detail::chacha<20>{prng_seed(), make_nonce()}}; + return gen(); } -//------------------------------------------------------------------------------ - -#ifndef BOOST_NO_CXX11_THREAD_LOCAL - -prng::ref -make_prng_tls(bool secure) +inline +std::uint32_t +fast_generate() { - class fast_prng final : public prng + struct generator { - beast::detail::pcg r_; - - public: - fast_prng() - : r_( - []{ - auto const pv = prng_seed(); - return - ((static_cast<std::uint64_t>(pv[0])<<32)+pv[1]) ^ - ((static_cast<std::uint64_t>(pv[2])<<32)+pv[3]) ^ - ((static_cast<std::uint64_t>(pv[4])<<32)+pv[5]) ^ - ((static_cast<std::uint64_t>(pv[6])<<32)+pv[7]); - }(), - []{ - static std::atomic< - std::uint32_t> nonce{0}; - return ++nonce; - }()) - { - } - - protected: - prng& - acquire() noexcept override + std::uint32_t operator()() { - return *this; + std::lock_guard<std::mutex> guard{mtx}; + return gen(); } - void - release() noexcept override - { - } - - value_type - operator()() noexcept override - { - return r_(); - } + beast::detail::pcg gen; + std::mutex mtx; }; + static generator gen{make_pcg()}; + return gen(); +} - class secure_prng final : public prng - { - beast::detail::chacha<20> r_; - - public: - secure_prng() - : r_(prng_seed(), [] - { - static std::atomic< - std::uint64_t> nonce{0}; - return ++nonce; - }()) - { - } - - protected: - prng& - acquire() noexcept override - { - return *this; - } - - void - release() noexcept override - { - } - - value_type - operator()() noexcept override - { - return r_(); - } - }; +#else - if(secure) - { - thread_local secure_prng sp; - return prng::ref(sp); - } +inline +std::uint32_t +secure_generate() +{ + thread_local static beast::detail::chacha<20> gen{prng_seed(), make_nonce()}; + return gen(); +} - thread_local fast_prng fp; - return prng::ref(fp); +inline +std::uint32_t +fast_generate() +{ + thread_local static beast::detail::pcg gen{make_pcg()}; + return gen(); } #endif -//------------------------------------------------------------------------------ - -prng::ref +generator make_prng(bool secure) { -#ifdef BOOST_NO_CXX11_THREAD_LOCAL - return make_prng_no_tls(secure); -#else - return make_prng_tls(secure); -#endif + if (secure) + return &secure_generate; + else + return &fast_generate; } } // detail diff --git a/boost/beast/websocket/impl/accept.hpp b/boost/beast/websocket/impl/accept.hpp index 4b989b56c7..1e33d8b40a 100644 --- a/boost/beast/websocket/impl/accept.hpp +++ b/boost/beast/websocket/impl/accept.hpp @@ -21,7 +21,6 @@ #include <boost/beast/core/buffer_traits.hpp> #include <boost/beast/core/stream_traits.hpp> #include <boost/beast/core/detail/buffer.hpp> -#include <boost/beast/core/detail/type_traits.hpp> #include <boost/beast/version.hpp> #include <boost/asio/coroutine.hpp> #include <boost/asio/post.hpp> @@ -80,13 +79,8 @@ build_response( decorator_opt(res); decorator(res); if(! res.count(http::field::server)) - { - // VFALCO this is weird.. - BOOST_STATIC_ASSERT(sizeof( - BOOST_BEAST_VERSION_STRING) < 20); - static_string<20> s(BOOST_BEAST_VERSION_STRING); - res.set(http::field::server, s); - } + res.set(http::field::server, + string_view(BOOST_BEAST_VERSION_STRING)); }; auto err = [&](error e) @@ -172,7 +166,7 @@ template<class Handler> class stream<NextLayer, deflateSupported>::response_op : public beast::stable_async_base< Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { boost::weak_ptr<impl_type> wp_; error_code result_; // must come before res_ @@ -247,7 +241,7 @@ template<class Handler, class Decorator> class stream<NextLayer, deflateSupported>::accept_op : public beast::stable_async_base< Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { boost::weak_ptr<impl_type> wp_; http::request_parser<http::empty_body>& p_; diff --git a/boost/beast/websocket/impl/close.hpp b/boost/beast/websocket/impl/close.hpp index 03078d9232..d59374ccd3 100644 --- a/boost/beast/websocket/impl/close.hpp +++ b/boost/beast/websocket/impl/close.hpp @@ -38,7 +38,7 @@ template<class Handler> class stream<NextLayer, deflateSupported>::close_op : public beast::stable_async_base< Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { boost::weak_ptr<impl_type> wp_; error_code ev_; diff --git a/boost/beast/websocket/impl/handshake.hpp b/boost/beast/websocket/impl/handshake.hpp index 21fba99738..645b1a3a30 100644 --- a/boost/beast/websocket/impl/handshake.hpp +++ b/boost/beast/websocket/impl/handshake.hpp @@ -37,7 +37,7 @@ template<class Handler> class stream<NextLayer, deflateSupported>::handshake_op : public beast::stable_async_base<Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { struct data { diff --git a/boost/beast/websocket/impl/ping.hpp b/boost/beast/websocket/impl/ping.hpp index 350505c081..6f92d7c725 100644 --- a/boost/beast/websocket/impl/ping.hpp +++ b/boost/beast/websocket/impl/ping.hpp @@ -35,7 +35,7 @@ template<class Handler> class stream<NextLayer, deflateSupported>::ping_op : public beast::stable_async_base< Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { boost::weak_ptr<impl_type> wp_; detail::frame_buffer& fb_; @@ -115,7 +115,7 @@ public: template<class NextLayer, bool deflateSupported> template<class Executor> class stream<NextLayer, deflateSupported>::idle_ping_op - : public net::coroutine + : public asio::coroutine , public boost::empty_value<Executor> { boost::weak_ptr<impl_type> wp_; @@ -176,7 +176,8 @@ public: impl.op_idle_ping.emplace(std::move(*this)); impl.wr_block.lock(this); BOOST_ASIO_CORO_YIELD - net::post(this->get(), std::move(*this)); + net::post( + this->get_executor(), std::move(*this)); BOOST_ASSERT(impl.wr_block.is_locked(this)); } if(impl.check_stop_now(ec)) diff --git a/boost/beast/websocket/impl/read.hpp b/boost/beast/websocket/impl/read.hpp index 8be18e5975..86c8940fc7 100644 --- a/boost/beast/websocket/impl/read.hpp +++ b/boost/beast/websocket/impl/read.hpp @@ -48,7 +48,7 @@ template<class Handler, class MutableBufferSequence> class stream<NextLayer, deflateSupported>::read_some_op : public beast::async_base< Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { boost::weak_ptr<impl_type> wp_; MutableBufferSequence bs_; @@ -619,7 +619,7 @@ template<class Handler, class DynamicBuffer> class stream<NextLayer, deflateSupported>::read_op : public beast::async_base< Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { boost::weak_ptr<impl_type> wp_; DynamicBuffer& b_; @@ -664,21 +664,22 @@ public: auto& impl = *sp; using mutable_buffers_type = typename DynamicBuffer::mutable_buffers_type; - boost::optional<mutable_buffers_type> mb; BOOST_ASIO_CORO_REENTER(*this) { do { - mb = beast::detail::dynamic_buffer_prepare(b_, - clamp(impl.read_size_hint_db(b_), limit_), - ec, error::buffer_overflow); - if(impl.check_stop_now(ec)) - goto upcall; - // VFALCO TODO use boost::beast::bind_continuation BOOST_ASIO_CORO_YIELD - read_some_op<read_op, mutable_buffers_type>( - std::move(*this), sp, *mb); + { + auto mb = beast::detail::dynamic_buffer_prepare(b_, + clamp(impl.read_size_hint_db(b_), limit_), + ec, error::buffer_overflow); + if(impl.check_stop_now(ec)) + goto upcall; + read_some_op<read_op, mutable_buffers_type>( + std::move(*this), sp, *mb); + } + b_.commit(bytes_transferred); bytes_written_ += bytes_transferred; if(ec) diff --git a/boost/beast/websocket/impl/stream.hpp b/boost/beast/websocket/impl/stream.hpp index 150748c453..539e255192 100644 --- a/boost/beast/websocket/impl/stream.hpp +++ b/boost/beast/websocket/impl/stream.hpp @@ -25,11 +25,8 @@ #include <boost/beast/core/buffers_suffix.hpp> #include <boost/beast/core/flat_static_buffer.hpp> #include <boost/beast/core/detail/clamp.hpp> -#include <boost/beast/core/detail/type_traits.hpp> -#include <boost/asio/bind_executor.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/assert.hpp> -#include <boost/endian/buffers.hpp> #include <boost/make_shared.hpp> #include <boost/throw_exception.hpp> #include <algorithm> @@ -64,7 +61,7 @@ stream(Args&&... args) template<class NextLayer, bool deflateSupported> auto stream<NextLayer, deflateSupported>:: -get_executor() const noexcept -> +get_executor() noexcept -> executor_type { return impl_->stream().get_executor(); @@ -140,12 +137,7 @@ read_size_hint(DynamicBuffer& buffer) const static_assert( net::is_dynamic_buffer<DynamicBuffer>::value, "DynamicBuffer type requirements not met"); - auto const initial_size = (std::min)( - +tcp_frame_size, - buffer.max_size() - buffer.size()); - if(initial_size == 0) - return 1; // buffer is full - return read_size_hint(initial_size); + return impl_->read_size_hint_db(buffer); } //------------------------------------------------------------------------------ diff --git a/boost/beast/websocket/impl/stream_impl.hpp b/boost/beast/websocket/impl/stream_impl.hpp index ec5557c361..5bcd9c78ab 100644 --- a/boost/beast/websocket/impl/stream_impl.hpp +++ b/boost/beast/websocket/impl/stream_impl.hpp @@ -30,9 +30,7 @@ #include <boost/beast/core/static_buffer.hpp> #include <boost/beast/core/stream_traits.hpp> #include <boost/beast/core/detail/clamp.hpp> -#include <boost/beast/core/detail/type_traits.hpp> #include <boost/beast/version.hpp> -#include <boost/asio/bind_executor.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/core/empty_value.hpp> #include <boost/enable_shared_from_this.hpp> @@ -99,7 +97,8 @@ struct stream<NextLayer, deflateSupported>::impl_type bool wr_cont /* next write is a continuation */ = false; bool wr_frag /* autofrag the current message */ = false; bool wr_frag_opt /* autofrag option setting */ = true; - bool wr_compress /* compress current message */ = false; + bool wr_compress; /* compress current message */ + bool wr_compress_opt /* compress message setting */ = true; detail::opcode wr_opcode /* message type */ = detail::opcode::text; std::unique_ptr< std::uint8_t[]> wr_buf; // write buffer @@ -211,11 +210,14 @@ struct stream<NextLayer, deflateSupported>::impl_type timer.cancel(); } - // Called before each write frame + // Called just before sending + // the first frame of each message void begin_msg() { wr_frag = wr_frag_opt; + wr_compress = + this->pmd_enabled() && wr_compress_opt; // Maintain the write buffer if( this->pmd_enabled() || @@ -234,6 +236,8 @@ struct stream<NextLayer, deflateSupported>::impl_type wr_buf_size = wr_buf_opt; wr_buf.reset(); } + + // } //-------------------------------------------------------------------------- @@ -275,13 +279,6 @@ struct stream<NextLayer, deflateSupported>::impl_type return key; } - std::size_t - read_size_hint(std::size_t initial_size) const - { - return this->read_size_hint_pmd( - initial_size, rd_done, rd_remain, rd_fh); - } - template<class DynamicBuffer> std::size_t read_size_hint_db(DynamicBuffer& buffer) const @@ -291,7 +288,8 @@ struct stream<NextLayer, deflateSupported>::impl_type buffer.max_size() - buffer.size()); if(initial_size == 0) return 1; // buffer is full - return this->read_size_hint(initial_size); + return this->read_size_hint_pmd( + initial_size, rd_done, rd_remain, rd_fh); } template<class DynamicBuffer> @@ -771,10 +769,12 @@ parse_fh( { case 126: { - std::uint8_t tmp[2]; - BOOST_ASSERT(buffer_bytes(cb) >= sizeof(tmp)); - cb.consume(net::buffer_copy(net::buffer(tmp), cb)); - fh.len = detail::big_uint16_to_native(&tmp[0]); + + std::uint16_t len_be; + BOOST_ASSERT(buffer_bytes(cb) >= sizeof(len_be)); + cb.consume(net::buffer_copy( + net::mutable_buffer(&len_be, sizeof(len_be)), cb)); + fh.len = endian::big_to_native(len_be); if(fh.len < 126) { // length not canonical @@ -785,10 +785,11 @@ parse_fh( } case 127: { - std::uint8_t tmp[8]; - BOOST_ASSERT(buffer_bytes(cb) >= sizeof(tmp)); - cb.consume(net::buffer_copy(net::buffer(tmp), cb)); - fh.len = detail::big_uint64_to_native(&tmp[0]); + std::uint64_t len_be; + BOOST_ASSERT(buffer_bytes(cb) >= sizeof(len_be)); + cb.consume(net::buffer_copy( + net::mutable_buffer(&len_be, sizeof(len_be)), cb)); + fh.len = endian::big_to_native(len_be); if(fh.len < 65536) { // length not canonical @@ -800,10 +801,11 @@ parse_fh( } if(fh.mask) { - std::uint8_t tmp[4]; - BOOST_ASSERT(buffer_bytes(cb) >= sizeof(tmp)); - cb.consume(net::buffer_copy(net::buffer(tmp), cb)); - fh.key = detail::little_uint32_to_native(&tmp[0]); + std::uint32_t key_le; + BOOST_ASSERT(buffer_bytes(cb) >= sizeof(key_le)); + cb.consume(net::buffer_copy( + net::mutable_buffer(&key_le, sizeof(key_le)), cb)); + fh.key = endian::little_to_native(key_le); detail::prepare_key(rd_key, fh.key); } else @@ -909,12 +911,10 @@ write_close(DynamicBuffer& db, close_reason const& cr) if(fh.mask) detail::prepare_key(key, fh.key); { - std::uint8_t tmp[2]; - ::new(&tmp[0]) big_uint16_buf_t{ - (std::uint16_t)cr.code}; + auto code_be = endian::native_to_big<std::uint16_t>(cr.code); auto mb = db.prepare(2); net::buffer_copy(mb, - net::buffer(tmp)); + net::const_buffer(&code_be, sizeof(code_be))); if(fh.mask) detail::mask_inplace(mb, key); db.commit(2); diff --git a/boost/beast/websocket/impl/teardown.hpp b/boost/beast/websocket/impl/teardown.hpp index 8e0913762c..2e2f0ad7e3 100644 --- a/boost/beast/websocket/impl/teardown.hpp +++ b/boost/beast/websocket/impl/teardown.hpp @@ -14,7 +14,7 @@ #include <boost/beast/core/bind_handler.hpp> #include <boost/beast/core/stream_traits.hpp> #include <boost/beast/core/detail/bind_continuation.hpp> -#include <boost/beast/core/detail/type_traits.hpp> +#include <boost/beast/core/detail/is_invocable.hpp> #include <boost/asio/coroutine.hpp> #include <boost/asio/post.hpp> #include <memory> @@ -33,7 +33,7 @@ class teardown_tcp_op Handler, beast::executor_type< net::basic_stream_socket< Protocol, Executor>>> - , public net::coroutine + , public asio::coroutine { using socket_type = net::basic_stream_socket<Protocol, Executor>; diff --git a/boost/beast/websocket/impl/write.hpp b/boost/beast/websocket/impl/write.hpp index 318693f512..2a82b677b3 100644 --- a/boost/beast/websocket/impl/write.hpp +++ b/boost/beast/websocket/impl/write.hpp @@ -41,7 +41,7 @@ template<class Handler, class Buffers> class stream<NextLayer, deflateSupported>::write_some_op : public beast::async_base< Handler, beast::executor_type<stream>> - , public net::coroutine + , public asio::coroutine { enum { diff --git a/boost/beast/websocket/option.hpp b/boost/beast/websocket/option.hpp index 62ebfa4a2b..1133c4e1fa 100644 --- a/boost/beast/websocket/option.hpp +++ b/boost/beast/websocket/option.hpp @@ -11,15 +11,6 @@ #define BOOST_BEAST_WEBSOCKET_OPTION_HPP #include <boost/beast/core/detail/config.hpp> -#include <boost/beast/websocket/rfc6455.hpp> -#include <boost/beast/core/detail/type_traits.hpp> -#include <boost/throw_exception.hpp> -#include <algorithm> -#include <cstdint> -#include <functional> -#include <stdexcept> -#include <type_traits> -#include <utility> namespace boost { namespace beast { diff --git a/boost/beast/websocket/stream.hpp b/boost/beast/websocket/stream.hpp index a9d79d2de4..367a54537c 100644 --- a/boost/beast/websocket/stream.hpp +++ b/boost/beast/websocket/stream.hpp @@ -23,7 +23,6 @@ #include <boost/beast/core/role.hpp> #include <boost/beast/core/stream_traits.hpp> #include <boost/beast/core/string.hpp> -#include <boost/beast/core/detail/type_traits.hpp> #include <boost/beast/http/detail/type_traits.hpp> #include <boost/asio/async_result.hpp> #include <boost/asio/error.hpp> @@ -220,7 +219,7 @@ public: @return A copy of the executor that stream will use to dispatch handlers. */ executor_type - get_executor() const noexcept; + get_executor() noexcept; /** Get a reference to the next layer |