makes all tracker requests 'stopped' when aborting
[libtorrent.git] / include / libtorrent / ssl_stream.hpp
blob363c819f63e017c53590d6189efb927cbc1e9729
1 /*
3 Copyright (c) 2008, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
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>
39 #else
40 #include <boost/asio/ssl.hpp>
41 #endif
42 // openssl seems to believe it owns
43 // this name in every single scope
44 #undef set_key
46 namespace libtorrent {
48 template <class Stream>
49 class ssl_stream
51 public:
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:
72 // 1. connect to peer
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);
107 #endif
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);
126 #endif
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);
138 #endif
140 void open(protocol_type const& p, error_code& ec)
142 m_sock.next_layer().open(p, ec);
145 bool is_open() const
147 return const_cast<sock_type&>(m_sock).next_layer().is_open();
150 #ifndef BOOST_NO_EXCEPTIONS
151 void close()
153 m_sock.next_layer().close();
155 #endif
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();
167 #endif
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();
179 #endif
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();
201 private:
203 void connected(error_code const& e, boost::shared_ptr<handler_type> h)
205 if (e)
207 (*h)(e);
208 return;
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)
217 (*h)(e);
220 asio::ssl::context m_context;
221 asio::ssl::stream<Stream> m_sock;
226 #endif