Realistic 3D camera system
3D camera system components
openssl_stream_service.hpp
Go to the documentation of this file.
1 //
2 // ssl/old/detail/stream_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
6 // Copyright (c) 2005-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 //
11 
12 #ifndef ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP
13 #define ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP
14 
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 # pragma once
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 
19 #include "asio/detail/config.hpp"
20 #include <cstddef>
21 #include <climits>
22 #include <memory>
23 #include <boost/config.hpp>
24 #include <boost/noncopyable.hpp>
25 #include <boost/function.hpp>
26 #include <boost/bind.hpp>
28 #include "asio/error.hpp"
29 #include "asio/io_service.hpp"
31 #include "asio/ssl/stream_base.hpp"
34 #include "asio/strand.hpp"
35 #include "asio/system_error.hpp"
36 
38 
39 namespace asio {
40 namespace ssl {
41 namespace old {
42 namespace detail {
43 
45  : public asio::detail::service_base<openssl_stream_service>
46 {
47 private:
48  enum { max_buffer_size = INT_MAX };
49 
50  //Base handler for asyncrhonous operations
51  template <typename Stream>
52  class base_handler
53  {
54  public:
55  typedef boost::function<
56  void (const asio::error_code&, size_t)> func_t;
57 
58  base_handler(asio::io_service& io_service)
59  : op_(NULL)
60  , io_service_(io_service)
61  , work_(io_service)
62  {}
63 
64  void do_func(const asio::error_code& error, size_t size)
65  {
66  func_(error, size);
67  }
68 
69  void set_operation(openssl_operation<Stream>* op) { op_ = op; }
70  void set_func(func_t func) { func_ = func; }
71 
72  ~base_handler()
73  {
74  delete op_;
75  }
76 
77  private:
78  func_t func_;
80  asio::io_service& io_service_;
82  }; // class base_handler
83 
84  // Handler for asynchronous IO (write/read) operations
85  template<typename Stream, typename Handler>
86  class io_handler
87  : public base_handler<Stream>
88  {
89  public:
90  io_handler(Handler handler, asio::io_service& io_service)
91  : base_handler<Stream>(io_service)
92  , handler_(handler)
93  {
94  this->set_func(boost::bind(
95  &io_handler<Stream, Handler>::handler_impl,
96  this, boost::arg<1>(), boost::arg<2>() ));
97  }
98 
99  private:
100  Handler handler_;
101  void handler_impl(const asio::error_code& error, size_t size)
102  {
103  std::auto_ptr<io_handler<Stream, Handler> > this_ptr(this);
104  handler_(error, size);
105  }
106  }; // class io_handler
107 
108  // Handler for asyncrhonous handshake (connect, accept) functions
109  template <typename Stream, typename Handler>
110  class handshake_handler
111  : public base_handler<Stream>
112  {
113  public:
115  : base_handler<Stream>(io_service)
116  , handler_(handler)
117  {
118  this->set_func(boost::bind(
119  &handshake_handler<Stream, Handler>::handler_impl,
120  this, boost::arg<1>(), boost::arg<2>() ));
121  }
122 
123  private:
124  Handler handler_;
125  void handler_impl(const asio::error_code& error, size_t)
126  {
127  std::auto_ptr<handshake_handler<Stream, Handler> > this_ptr(this);
128  handler_(error);
129  }
130 
131  }; // class handshake_handler
132 
133  // Handler for asyncrhonous shutdown
134  template <typename Stream, typename Handler>
135  class shutdown_handler
136  : public base_handler<Stream>
137  {
138  public:
139  shutdown_handler(Handler handler, asio::io_service& io_service)
140  : base_handler<Stream>(io_service),
141  handler_(handler)
142  {
143  this->set_func(boost::bind(
144  &shutdown_handler<Stream, Handler>::handler_impl,
145  this, boost::arg<1>(), boost::arg<2>() ));
146  }
147 
148  private:
149  Handler handler_;
150  void handler_impl(const asio::error_code& error, size_t)
151  {
152  std::auto_ptr<shutdown_handler<Stream, Handler> > this_ptr(this);
153  handler_(error);
154  }
155  }; // class shutdown_handler
156 
157 public:
158  // The implementation type.
159  typedef struct impl_struct
160  {
161  ::SSL* ssl;
162  ::BIO* ext_bio;
164  } * impl_type;
165 
166  // Construct a new stream socket service for the specified io_service.
168  : asio::detail::service_base<openssl_stream_service>(io_service),
169  strand_(io_service)
170  {
171  }
172 
173  // Destroy all user-defined handler objects owned by the service.
175  {
176  }
177 
178  // Return a null stream implementation.
179  impl_type null() const
180  {
181  return 0;
182  }
183 
184  // Create a new stream implementation.
185  template <typename Stream, typename Context_Service>
186  void create(impl_type& impl, Stream& /*next_layer*/,
188  {
189  impl = new impl_struct;
190  impl->ssl = ::SSL_new(context.impl());
191  ::SSL_set_mode(impl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
192  ::SSL_set_mode(impl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
193  ::BIO* int_bio = 0;
194  impl->ext_bio = 0;
195  ::BIO_new_bio_pair(&int_bio, 8192, &impl->ext_bio, 8192);
196  ::SSL_set_bio(impl->ssl, int_bio, int_bio);
197  }
198 
199  // Destroy a stream implementation.
200  template <typename Stream>
201  void destroy(impl_type& impl, Stream& /*next_layer*/)
202  {
203  if (impl != 0)
204  {
205  ::BIO_free(impl->ext_bio);
206  ::SSL_free(impl->ssl);
207  delete impl;
208  impl = 0;
209  }
210  }
211 
212  // Perform SSL handshaking.
213  template <typename Stream>
214  asio::error_code handshake(impl_type& impl, Stream& next_layer,
216  {
217  try
218  {
220  type == stream_base::client ?
221  &ssl_wrap<mutex_type>::SSL_connect:
222  &ssl_wrap<mutex_type>::SSL_accept,
223  next_layer,
224  impl->recv_buf,
225  impl->ssl,
226  impl->ext_bio);
227  op.start();
228  }
229  catch (asio::system_error& e)
230  {
231  ec = e.code();
232  return ec;
233  }
234 
235  ec = asio::error_code();
236  return ec;
237  }
238 
239  // Start an asynchronous SSL handshake.
240  template <typename Stream, typename Handler>
241  void async_handshake(impl_type& impl, Stream& next_layer,
242  stream_base::handshake_type type, Handler handler)
243  {
244  typedef handshake_handler<Stream, Handler> connect_handler;
245 
246  connect_handler* local_handler =
247  new connect_handler(handler, get_io_service());
248 
250  (
251  type == stream_base::client ?
252  &ssl_wrap<mutex_type>::SSL_connect:
253  &ssl_wrap<mutex_type>::SSL_accept,
254  next_layer,
255  impl->recv_buf,
256  impl->ssl,
257  impl->ext_bio,
259  (
260  &base_handler<Stream>::do_func,
261  local_handler,
262  boost::arg<1>(),
263  boost::arg<2>()
264  ),
265  strand_
266  );
267  local_handler->set_operation(op);
268 
269  strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
270  }
271 
272  // Shut down SSL on the stream.
273  template <typename Stream>
274  asio::error_code shutdown(impl_type& impl, Stream& next_layer,
275  asio::error_code& ec)
276  {
277  try
278  {
280  &ssl_wrap<mutex_type>::SSL_shutdown,
281  next_layer,
282  impl->recv_buf,
283  impl->ssl,
284  impl->ext_bio);
285  op.start();
286  }
287  catch (asio::system_error& e)
288  {
289  ec = e.code();
290  return ec;
291  }
292 
293  ec = asio::error_code();
294  return ec;
295  }
296 
297  // Asynchronously shut down SSL on the stream.
298  template <typename Stream, typename Handler>
299  void async_shutdown(impl_type& impl, Stream& next_layer, Handler handler)
300  {
301  typedef shutdown_handler<Stream, Handler> disconnect_handler;
302 
303  disconnect_handler* local_handler =
304  new disconnect_handler(handler, get_io_service());
305 
307  (
308  &ssl_wrap<mutex_type>::SSL_shutdown,
309  next_layer,
310  impl->recv_buf,
311  impl->ssl,
312  impl->ext_bio,
314  (
315  &base_handler<Stream>::do_func,
316  local_handler,
317  boost::arg<1>(),
318  boost::arg<2>()
319  ),
320  strand_
321  );
322  local_handler->set_operation(op);
323 
324  strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
325  }
326 
327  // Write some data to the stream.
328  template <typename Stream, typename Const_Buffers>
329  std::size_t write_some(impl_type& impl, Stream& next_layer,
330  const Const_Buffers& buffers, asio::error_code& ec)
331  {
332  size_t bytes_transferred = 0;
333  try
334  {
337  asio::const_buffer, Const_Buffers>::first(buffers);
338 
339  std::size_t buffer_size = asio::buffer_size(buffer);
340  if (buffer_size > max_buffer_size)
341  buffer_size = max_buffer_size;
342  else if (buffer_size == 0)
343  {
344  ec = asio::error_code();
345  return 0;
346  }
347 
348  boost::function<int (SSL*)> send_func =
349  boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
350  asio::buffer_cast<const void*>(buffer),
351  static_cast<int>(buffer_size));
353  send_func,
354  next_layer,
355  impl->recv_buf,
356  impl->ssl,
357  impl->ext_bio
358  );
359  bytes_transferred = static_cast<size_t>(op.start());
360  }
361  catch (asio::system_error& e)
362  {
363  ec = e.code();
364  return 0;
365  }
366 
367  ec = asio::error_code();
368  return bytes_transferred;
369  }
370 
371  // Start an asynchronous write.
372  template <typename Stream, typename Const_Buffers, typename Handler>
373  void async_write_some(impl_type& impl, Stream& next_layer,
374  const Const_Buffers& buffers, Handler handler)
375  {
376  typedef io_handler<Stream, Handler> send_handler;
377 
380  asio::const_buffer, Const_Buffers>::first(buffers);
381 
382  std::size_t buffer_size = asio::buffer_size(buffer);
383  if (buffer_size > max_buffer_size)
384  buffer_size = max_buffer_size;
385  else if (buffer_size == 0)
386  {
388  handler, asio::error_code(), 0));
389  return;
390  }
391 
392  send_handler* local_handler = new send_handler(handler, get_io_service());
393 
394  boost::function<int (SSL*)> send_func =
395  boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
396  asio::buffer_cast<const void*>(buffer),
397  static_cast<int>(buffer_size));
398 
400  (
401  send_func,
402  next_layer,
403  impl->recv_buf,
404  impl->ssl,
405  impl->ext_bio,
407  (
408  &base_handler<Stream>::do_func,
409  local_handler,
410  boost::arg<1>(),
411  boost::arg<2>()
412  ),
413  strand_
414  );
415  local_handler->set_operation(op);
416 
417  strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
418  }
419 
420  // Read some data from the stream.
421  template <typename Stream, typename Mutable_Buffers>
422  std::size_t read_some(impl_type& impl, Stream& next_layer,
423  const Mutable_Buffers& buffers, asio::error_code& ec)
424  {
425  size_t bytes_transferred = 0;
426  try
427  {
430  asio::mutable_buffer, Mutable_Buffers>::first(buffers);
431 
432  std::size_t buffer_size = asio::buffer_size(buffer);
433  if (buffer_size > max_buffer_size)
434  buffer_size = max_buffer_size;
435  else if (buffer_size == 0)
436  {
437  ec = asio::error_code();
438  return 0;
439  }
440 
441  boost::function<int (SSL*)> recv_func =
442  boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
443  asio::buffer_cast<void*>(buffer),
444  static_cast<int>(buffer_size));
445  openssl_operation<Stream> op(recv_func,
446  next_layer,
447  impl->recv_buf,
448  impl->ssl,
449  impl->ext_bio
450  );
451 
452  bytes_transferred = static_cast<size_t>(op.start());
453  }
454  catch (asio::system_error& e)
455  {
456  ec = e.code();
457  return 0;
458  }
459 
460  ec = asio::error_code();
461  return bytes_transferred;
462  }
463 
464  // Start an asynchronous read.
465  template <typename Stream, typename Mutable_Buffers, typename Handler>
466  void async_read_some(impl_type& impl, Stream& next_layer,
467  const Mutable_Buffers& buffers, Handler handler)
468  {
469  typedef io_handler<Stream, Handler> recv_handler;
470 
473  asio::mutable_buffer, Mutable_Buffers>::first(buffers);
474 
475  std::size_t buffer_size = asio::buffer_size(buffer);
476  if (buffer_size > max_buffer_size)
477  buffer_size = max_buffer_size;
478  else if (buffer_size == 0)
479  {
481  handler, asio::error_code(), 0));
482  return;
483  }
484 
485  recv_handler* local_handler = new recv_handler(handler, get_io_service());
486 
487  boost::function<int (SSL*)> recv_func =
488  boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
489  asio::buffer_cast<void*>(buffer),
490  static_cast<int>(buffer_size));
491 
493  (
494  recv_func,
495  next_layer,
496  impl->recv_buf,
497  impl->ssl,
498  impl->ext_bio,
500  (
501  &base_handler<Stream>::do_func,
502  local_handler,
503  boost::arg<1>(),
504  boost::arg<2>()
505  ),
506  strand_
507  );
508  local_handler->set_operation(op);
509 
510  strand_.post(boost::bind(&openssl_operation<Stream>::start, op));
511  }
512 
513  // Peek at the incoming data on the stream.
514  template <typename Stream, typename Mutable_Buffers>
515  std::size_t peek(impl_type& /*impl*/, Stream& /*next_layer*/,
516  const Mutable_Buffers& /*buffers*/, asio::error_code& ec)
517  {
518  ec = asio::error_code();
519  return 0;
520  }
521 
522  // Determine the amount of data that may be read without blocking.
523  template <typename Stream>
524  std::size_t in_avail(impl_type& /*impl*/, Stream& /*next_layer*/,
525  asio::error_code& ec)
526  {
527  ec = asio::error_code();
528  return 0;
529  }
530 
531 private:
532  asio::io_service::strand strand_;
533 
535 
536  template<typename Mutex>
537  struct ssl_wrap
538  {
539  static Mutex ssl_mutex_;
540 
541  static int SSL_accept(SSL *ssl)
542  {
543  typename Mutex::scoped_lock lock(ssl_mutex_);
544  return ::SSL_accept(ssl);
545  }
546 
547  static int SSL_connect(SSL *ssl)
548  {
549  typename Mutex::scoped_lock lock(ssl_mutex_);
550  return ::SSL_connect(ssl);
551  }
552 
553  static int SSL_shutdown(SSL *ssl)
554  {
555  typename Mutex::scoped_lock lock(ssl_mutex_);
556  return ::SSL_shutdown(ssl);
557  }
558  };
559 };
560 
561 template<typename Mutex>
562 Mutex openssl_stream_service::ssl_wrap<Mutex>::ssl_mutex_;
563 
564 } // namespace detail
565 } // namespace old
566 } // namespace ssl
567 } // namespace asio
568 
570 
571 #endif // ASIO_SSL_OLD_DETAIL_OPENSSL_STREAM_SERVICE_HPP
void shutdown_handler(const asio::error_code &)
Definition: stream.cpp:48
asio::error_code handshake(impl_type &impl, Stream &next_layer, stream_base::handshake_type type, asio::error_code &ec)
void send_handler(const asio::error_code &, std::size_t)
Provides core I/O functionality.
Definition: io_service.hpp:184
void async_shutdown(impl_type &impl, Stream &next_layer, Handler handler)
Holds a buffer that cannot be modified.
Definition: buffer.hpp:211
post(ASIO_MOVE_ARG(CompletionHandler) handler)
Request the io_service to invoke the given handler and return immediately.
Class to inform the io_service when it has work to do.
Definition: io_service.hpp:626
pylon Camera Software Suite for Linux for Use with Basler Gigabit the pylon Viewer and the IP Configurator applications might not be available System I340 and I350 series Although the pylon software will work with any GigE network we would recommend to use one of these adapters USB For U3V devices a USB3 capable USB controller is necessary For best performance and stability we highly recommend a kernel the following settings should be i e
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Definition: buffer.hpp:706
Provides serialised handler execution.
Definition: strand.hpp:85
asio::io_service & get_io_service()
Get the io_service object that owns the service.
Definition: io_service.hpp:143
struct asio::ssl::old::detail::openssl_stream_service::impl_struct * impl_type
Perform handshaking as a client.
Definition: stream_base.hpp:34
std::size_t buffer_size(const mutable_buffer &b)
Get the number of bytes in a modifiable buffer.
Definition: buffer.hpp:357
handshake_type
Different handshake types.
Definition: stream_base.hpp:31
const MutableBufferSequence & buffers
Definition: read.hpp:521
std::size_t peek(impl_type &, Stream &, const Mutable_Buffers &, asio::error_code &ec)
void async_write_some(impl_type &impl, Stream &next_layer, const Const_Buffers &buffers, Handler handler)
std::size_t write_some(impl_type &impl, Stream &next_layer, const Const_Buffers &buffers, asio::error_code &ec)
Holds a buffer that can be modified.
Definition: buffer.hpp:91
int bind(socket_type s, const socket_addr_type *addr, std::size_t addrlen, asio::error_code &ec)
Definition: socket_ops.ipp:278
std::size_t read_some(impl_type &impl, Stream &next_layer, const Mutable_Buffers &buffers, asio::error_code &ec)
Class to represent an error code value.
Definition: error_code.hpp:80
error_code code() const
Get the error code associated with the exception.
void async_read_some(impl_type &impl, Stream &next_layer, const Mutable_Buffers &buffers, Handler handler)
std::size_t in_avail(impl_type &, Stream &, asio::error_code &ec)
asio::error_code shutdown(impl_type &impl, Stream &next_layer, asio::error_code &ec)
binder1< Handler, Arg1 > bind_handler(Handler handler, const Arg1 &arg1)
void handshake_handler(const asio::error_code &)
Definition: stream.cpp:40
void create(impl_type &impl, Stream &, basic_context< Context_Service > &context)
impl_type impl()
Get the underlying implementation in the native type.
void async_handshake(impl_type &impl, Stream &next_layer, stream_base::handshake_type type, Handler handler)
void connect_handler(const asio::error_code &e, debug_stream_socket *s)
void shutdown_service()
Destroy all user-defined handler objects owned by the service.