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