1 // 2 // ssl/detail/stream_core.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP 12 #define BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 20 #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 21 # include <boost/asio/deadline_timer.hpp> 22 #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 23 # include <boost/asio/steady_timer.hpp> 24 #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 25 #include <boost/asio/ssl/detail/engine.hpp> 26 #include <boost/asio/buffer.hpp> 27 28 #include <boost/asio/detail/push_options.hpp> 29 30 namespace boost { 31 namespace asio { 32 namespace ssl { 33 namespace detail { 34 35 struct stream_core 36 { 37 // According to the OpenSSL documentation, this is the buffer size that is 38 // sufficient to hold the largest possible TLS record. 39 enum { max_tls_record_size = 17 * 1024 }; 40 41 template <typename Executor> stream_coreboost::asio::ssl::detail::stream_core42 stream_core(SSL_CTX* context, const Executor& ex) 43 : engine_(context), 44 pending_read_(ex), 45 pending_write_(ex), 46 output_buffer_space_(max_tls_record_size), 47 output_buffer_(boost::asio::buffer(output_buffer_space_)), 48 input_buffer_space_(max_tls_record_size), 49 input_buffer_(boost::asio::buffer(input_buffer_space_)) 50 { 51 pending_read_.expires_at(neg_infin()); 52 pending_write_.expires_at(neg_infin()); 53 } 54 55 #if defined(BOOST_ASIO_HAS_MOVE) stream_coreboost::asio::ssl::detail::stream_core56 stream_core(stream_core&& other) 57 : engine_(BOOST_ASIO_MOVE_CAST(engine)(other.engine_)), 58 #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 59 pending_read_( 60 BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)( 61 other.pending_read_)), 62 pending_write_( 63 BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)( 64 other.pending_write_)), 65 #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 66 pending_read_( 67 BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)( 68 other.pending_read_)), 69 pending_write_( 70 BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)( 71 other.pending_write_)), 72 #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 73 output_buffer_space_( 74 BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)( 75 other.output_buffer_space_)), 76 output_buffer_(other.output_buffer_), 77 input_buffer_space_( 78 BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)( 79 other.input_buffer_space_)), 80 input_buffer_(other.input_buffer_), 81 input_(other.input_) 82 { 83 other.output_buffer_ = boost::asio::mutable_buffer(0, 0); 84 other.input_buffer_ = boost::asio::mutable_buffer(0, 0); 85 other.input_ = boost::asio::const_buffer(0, 0); 86 } 87 #endif // defined(BOOST_ASIO_HAS_MOVE) 88 ~stream_coreboost::asio::ssl::detail::stream_core89 ~stream_core() 90 { 91 } 92 93 #if defined(BOOST_ASIO_HAS_MOVE) operator =boost::asio::ssl::detail::stream_core94 stream_core& operator=(stream_core&& other) 95 { 96 if (this != &other) 97 { 98 engine_ = BOOST_ASIO_MOVE_CAST(engine)(other.engine_); 99 #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 100 pending_read_ = 101 BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)( 102 other.pending_read_); 103 pending_write_ = 104 BOOST_ASIO_MOVE_CAST(boost::asio::deadline_timer)( 105 other.pending_write_); 106 #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 107 pending_read_ = 108 BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)( 109 other.pending_read_); 110 pending_write_ = 111 BOOST_ASIO_MOVE_CAST(boost::asio::steady_timer)( 112 other.pending_write_); 113 #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 114 output_buffer_space_ = 115 BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)( 116 other.output_buffer_space_); 117 output_buffer_ = other.output_buffer_; 118 input_buffer_space_ = 119 BOOST_ASIO_MOVE_CAST(std::vector<unsigned char>)( 120 other.input_buffer_space_); 121 input_ = other.input_; 122 other.output_buffer_ = boost::asio::mutable_buffer(0, 0); 123 other.input_buffer_ = boost::asio::mutable_buffer(0, 0); 124 other.input_ = boost::asio::const_buffer(0, 0); 125 } 126 return *this; 127 } 128 #endif // defined(BOOST_ASIO_HAS_MOVE) 129 130 // The SSL engine. 131 engine engine_; 132 133 #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 134 // Timer used for storing queued read operations. 135 boost::asio::deadline_timer pending_read_; 136 137 // Timer used for storing queued write operations. 138 boost::asio::deadline_timer pending_write_; 139 140 // Helper function for obtaining a time value that always fires. neg_infinboost::asio::ssl::detail::stream_core141 static boost::asio::deadline_timer::time_type neg_infin() 142 { 143 return boost::posix_time::neg_infin; 144 } 145 146 // Helper function for obtaining a time value that never fires. pos_infinboost::asio::ssl::detail::stream_core147 static boost::asio::deadline_timer::time_type pos_infin() 148 { 149 return boost::posix_time::pos_infin; 150 } 151 152 // Helper function to get a timer's expiry time. expiryboost::asio::ssl::detail::stream_core153 static boost::asio::deadline_timer::time_type expiry( 154 const boost::asio::deadline_timer& timer) 155 { 156 return timer.expires_at(); 157 } 158 #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 159 // Timer used for storing queued read operations. 160 boost::asio::steady_timer pending_read_; 161 162 // Timer used for storing queued write operations. 163 boost::asio::steady_timer pending_write_; 164 165 // Helper function for obtaining a time value that always fires. neg_infinboost::asio::ssl::detail::stream_core166 static boost::asio::steady_timer::time_point neg_infin() 167 { 168 return (boost::asio::steady_timer::time_point::min)(); 169 } 170 171 // Helper function for obtaining a time value that never fires. pos_infinboost::asio::ssl::detail::stream_core172 static boost::asio::steady_timer::time_point pos_infin() 173 { 174 return (boost::asio::steady_timer::time_point::max)(); 175 } 176 177 // Helper function to get a timer's expiry time. expiryboost::asio::ssl::detail::stream_core178 static boost::asio::steady_timer::time_point expiry( 179 const boost::asio::steady_timer& timer) 180 { 181 return timer.expiry(); 182 } 183 #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 184 185 // Buffer space used to prepare output intended for the transport. 186 std::vector<unsigned char> output_buffer_space_; 187 188 // A buffer that may be used to prepare output intended for the transport. 189 boost::asio::mutable_buffer output_buffer_; 190 191 // Buffer space used to read input intended for the engine. 192 std::vector<unsigned char> input_buffer_space_; 193 194 // A buffer that may be used to read input intended for the engine. 195 boost::asio::mutable_buffer input_buffer_; 196 197 // The buffer pointing to the engine's unconsumed input. 198 boost::asio::const_buffer input_; 199 }; 200 201 } // namespace detail 202 } // namespace ssl 203 } // namespace asio 204 } // namespace boost 205 206 #include <boost/asio/detail/pop_options.hpp> 207 208 #endif // BOOST_ASIO_SSL_DETAIL_STREAM_CORE_HPP 209