3 Copyright (c) 2008, Arvid Norberg
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #ifndef TORRENT_SSL_STREAM_HPP_INCLUDED
34 #define TORRENT_SSL_STREAM_HPP_INCLUDED
36 #include "libtorrent/socket.hpp"
37 #if BOOST_VERSION < 103500
38 #include <asio/ssl.hpp>
40 #include <boost/asio/ssl.hpp>
42 // openssl seems to believe it owns
43 // this name in every single scope
46 namespace libtorrent
{
48 template <class Stream
>
53 explicit ssl_stream(io_service
& io_service
)
54 : m_context(io_service
, asio::ssl::context::sslv23_client
)
55 , m_sock(io_service
, m_context
)
57 m_context
.set_verify_mode(asio::ssl::context::verify_none
);
60 typedef Stream next_layer_type
;
61 typedef typename
Stream::lowest_layer_type lowest_layer_type
;
62 typedef typename
Stream::endpoint_type endpoint_type
;
63 typedef typename
Stream::protocol_type protocol_type
;
64 typedef typename
asio::ssl::stream
<Stream
> sock_type
;
66 typedef boost::function
<void(error_code
const&)> handler_type
;
68 template <class Handler
>
69 void async_connect(endpoint_type
const& endpoint
, Handler
const& handler
)
71 // the connect is split up in the following steps:
73 // 2. perform SSL client handshake
75 // to avoid unnecessary copying of the handler,
76 // store it in a shared_ptr
77 boost::shared_ptr
<handler_type
> h(new handler_type(handler
));
79 m_sock
.next_layer().async_connect(endpoint
80 , boost::bind(&ssl_stream::connected
, this, _1
, h
));
83 template <class Mutable_Buffers
, class Handler
>
84 void async_read_some(Mutable_Buffers
const& buffers
, Handler
const& handler
)
86 m_sock
.async_read_some(buffers
, handler
);
89 template <class Mutable_Buffers
>
90 std::size_t read_some(Mutable_Buffers
const& buffers
, error_code
& ec
)
92 return m_sock
.read_some(buffers
, ec
);
95 #ifndef BOOST_NO_EXCEPTIONS
96 template <class Mutable_Buffers
>
97 std::size_t read_some(Mutable_Buffers
const& buffers
)
99 return m_sock
.read_some(buffers
);
102 template <class IO_Control_Command
>
103 void io_control(IO_Control_Command
& ioc
)
105 m_sock
.next_layer().io_control(ioc
);
109 template <class IO_Control_Command
>
110 void io_control(IO_Control_Command
& ioc
, error_code
& ec
)
112 m_sock
.next_layer().io_control(ioc
, ec
);
115 template <class Const_Buffers
, class Handler
>
116 void async_write_some(Const_Buffers
const& buffers
, Handler
const& handler
)
118 m_sock
.async_write_some(buffers
, handler
);
121 #ifndef BOOST_NO_EXCEPTIONS
122 void bind(endpoint_type
const& endpoint
)
124 m_sock
.next_layer().bind(endpoint
);
128 void bind(endpoint_type
const& endpoint
, error_code
& ec
)
130 m_sock
.next_layer().bind(endpoint
, ec
);
133 #ifndef BOOST_NO_EXCEPTIONS
134 void open(protocol_type
const& p
)
136 m_sock
.next_layer().open(p
);
140 void open(protocol_type
const& p
, error_code
& ec
)
142 m_sock
.next_layer().open(p
, ec
);
147 return const_cast<sock_type
&>(m_sock
).next_layer().is_open();
150 #ifndef BOOST_NO_EXCEPTIONS
153 m_sock
.next_layer().close();
157 void close(error_code
& ec
)
159 m_sock
.next_layer().close(ec
);
162 #ifndef BOOST_NO_EXCEPTIONS
163 endpoint_type
remote_endpoint() const
165 return const_cast<sock_type
&>(m_sock
).next_layer().remote_endpoint();
169 endpoint_type
remote_endpoint(error_code
& ec
) const
171 return const_cast<sock_type
&>(m_sock
).next_layer().remote_endpoint(ec
);
174 #ifndef BOOST_NO_EXCEPTIONS
175 endpoint_type
local_endpoint() const
177 return const_cast<sock_type
&>(m_sock
).next_layer().local_endpoint();
181 endpoint_type
local_endpoint(error_code
& ec
) const
183 return const_cast<sock_type
&>(m_sock
).next_layer().local_endpoint(ec
);
186 io_service
& get_io_service()
188 return m_sock
.get_io_service();
191 lowest_layer_type
& lowest_layer()
193 return m_sock
.lowest_layer();
196 next_layer_type
& next_layer()
198 return m_sock
.next_layer();
203 void connected(error_code
const& e
, boost::shared_ptr
<handler_type
> h
)
211 m_sock
.async_handshake(asio::ssl::stream_base::client
212 , boost::bind(&ssl_stream::handshake
, this, _1
, h
));
215 void handshake(error_code
const& e
, boost::shared_ptr
<handler_type
> h
)
220 asio::ssl::context m_context
;
221 asio::ssl::stream
<Stream
> m_sock
;