DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
// // openssl_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP #define BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost { namespace asio { namespace ssl { namespace detail { typedef boost::function
ssl_primitive_func; typedef boost::function
user_handler_func; // Network send_/recv buffer implementation // // class net_buffer { static const int NET_BUF_SIZE = 16*1024 + 256; // SSL record size + spare unsigned char buf_[NET_BUF_SIZE]; unsigned char* data_start_; unsigned char* data_end_; public: net_buffer() { data_start_ = data_end_ = buf_; } unsigned char* get_unused_start() { return data_end_; } unsigned char* get_data_start() { return data_start_; } size_t get_unused_len() { return (NET_BUF_SIZE - (data_end_ - buf_)); } size_t get_data_len() { return (data_end_ - data_start_); } void data_added(size_t count) { data_end_ += count; data_end_ = data_end_ > (buf_ + NET_BUF_SIZE)? (buf_ + NET_BUF_SIZE): data_end_; } void data_removed(size_t count) { data_start_ += count; if (data_start_ >= data_end_) reset(); } void reset() { data_start_ = buf_; data_end_ = buf_; } bool has_data() { return (data_start_ < data_end_); } }; // class net_buffer // // Operation class // // template
class openssl_operation { public: // Constructor for asynchronous operations openssl_operation(ssl_primitive_func primitive, Stream& socket, net_buffer& recv_buf, SSL* session, BIO* ssl_bio, user_handler_func handler, boost::asio::io_service::strand& strand ) : primitive_(primitive) , user_handler_(handler) , strand_(&strand) , recv_buf_(recv_buf) , socket_(socket) , ssl_bio_(ssl_bio) , session_(session) { write_ = boost::bind( &openssl_operation::do_async_write, this, boost::arg<1>(), boost::arg<2>() ); read_ = boost::bind( &openssl_operation::do_async_read, this ); handler_= boost::bind( &openssl_operation::async_user_handler, this, boost::arg<1>(), boost::arg<2>() ); } // Constructor for synchronous operations openssl_operation(ssl_primitive_func primitive, Stream& socket, net_buffer& recv_buf, SSL* session, BIO* ssl_bio) : primitive_(primitive) , strand_(0) , recv_buf_(recv_buf) , socket_(socket) , ssl_bio_(ssl_bio) , session_(session) { write_ = boost::bind( &openssl_operation::do_sync_write, this, boost::arg<1>(), boost::arg<2>() ); read_ = boost::bind( &openssl_operation::do_sync_read, this ); handler_ = boost::bind( &openssl_operation::sync_user_handler, this, boost::arg<1>(), boost::arg<2>() ); } // Start operation // In case of asynchronous it returns 0, in sync mode returns success code // or throws an error... int start() { int rc = primitive_( session_ ); bool is_operation_done = (rc > 0); // For connect/accept/shutdown, the operation // is done, when return code is 1 // for write, it is done, when is retcode > 0 // for read, is is done when retcode > 0 int error_code = !is_operation_done ? ::SSL_get_error( session_, rc ) : 0; int sys_error_code = ERR_get_error(); bool is_read_needed = (error_code == SSL_ERROR_WANT_READ); bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE || ::BIO_ctrl_pending( ssl_bio_ )); bool is_shut_down_received = ((::SSL_get_shutdown( session_ ) & SSL_RECEIVED_SHUTDOWN) == SSL_RECEIVED_SHUTDOWN); bool is_shut_down_sent = ((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN); if (is_shut_down_sent && is_shut_down_received && is_operation_done) // SSL connection is shut down cleanly return handler_(boost::system::error_code(), 1); if (is_shut_down_received && !is_write_needed) return handler_(boost::asio::error::eof, 0); if (is_shut_down_received) // Shutdown has been requested, while we were reading or writing... // abort our action... return handler_(boost::asio::error::shut_down, 0); if (!is_operation_done && !is_read_needed && !is_write_needed && !is_shut_down_sent) { // The operation has failed... It is not completed and does // not want network communication nor does want to send shutdown out... if (error_code == SSL_ERROR_SYSCALL) { return handler_(boost::system::error_code( sys_error_code, boost::asio::error::system_category), rc); } else { return handler_(boost::system::error_code( error_code, boost::asio::error::get_ssl_category()), rc); } } if (!is_operation_done && !is_write_needed) { // We may have left over data that we can pass to SSL immediately if (recv_buf_.get_data_len() > 0) { // Pass the buffered data to SSL int written = ::BIO_write ( ssl_bio_, recv_buf_.get_data_start(), recv_buf_.get_data_len() ); if (written > 0) { recv_buf_.data_removed(written); } else if (written < 0) { if (!BIO_should_retry(ssl_bio_)) { // Some serios error with BIO.... return handler_(boost::asio::error::no_recovery, 0); } } return start(); } else if (is_read_needed) { return read_(); } } // Continue with operation, flush any SSL data out to network... return write_(is_operation_done, rc); } // Private implementation private: typedef boost::function
int_handler_func; typedef boost::function
write_func; typedef boost::function
read_func; ssl_primitive_func primitive_; user_handler_func user_handler_; boost::asio::io_service::strand* strand_; write_func write_; read_func read_; int_handler_func handler_; net_buffer send_buf_; // buffers for network IO // The recv buffer is owned by the stream, not the operation, since there can // be left over bytes after passing the data up to the application, and these // bytes need to be kept around for the next read operation issued by the // application. net_buffer& recv_buf_; Stream& socket_; BIO* ssl_bio_; SSL* session_; // int sync_user_handler(const boost::system::error_code& error, int rc) { if (!error) return rc; throw boost::system::system_error(error); } int async_user_handler(boost::system::error_code error, int rc) { if (rc < 0) { if (!error) error = boost::asio::error::no_recovery; rc = 0; } user_handler_(error, rc); return 0; } // Writes bytes asynchronously from SSL to NET int do_async_write(bool is_operation_done, int rc) { int len = ::BIO_ctrl_pending( ssl_bio_ ); if ( len ) { // There is something to write into net, do it... len = (int)send_buf_.get_unused_len() > len? len: send_buf_.get_unused_len(); if (len == 0) { // In case our send buffer is full, we have just to wait until // previous send to complete... return 0; } // Read outgoing data from bio len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len); if (len > 0) { unsigned char *data_start = send_buf_.get_unused_start(); send_buf_.data_added(len); BOOST_ASSERT(strand_); boost::asio::async_write ( socket_, boost::asio::buffer(data_start, len), strand_->wrap ( boost::bind ( &openssl_operation::async_write_handler, this, is_operation_done, rc, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); return 0; } else if (!BIO_should_retry(ssl_bio_)) { // Seems like fatal error // reading from SSL BIO has failed... handler_(boost::asio::error::no_recovery, 0); return 0; } } if (is_operation_done) { // Finish the operation, with success handler_(boost::system::error_code(), rc); return 0; } // OPeration is not done and writing to net has been made... // start operation again start(); return 0; } void async_write_handler(bool is_operation_done, int rc, const boost::system::error_code& error, size_t bytes_sent) { if (!error) { // Remove data from send buffer send_buf_.data_removed(bytes_sent); if (is_operation_done) handler_(boost::system::error_code(), rc); else // Since the operation was not completed, try it again... start(); } else handler_(error, rc); } int do_async_read() { // Wait for new data BOOST_ASSERT(strand_); socket_.async_read_some ( boost::asio::buffer(recv_buf_.get_unused_start(), recv_buf_.get_unused_len()), strand_->wrap ( boost::bind ( &openssl_operation::async_read_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) ) ); return 0; } void async_read_handler(const boost::system::error_code& error, size_t bytes_recvd) { if (!error) { recv_buf_.data_added(bytes_recvd); // Pass the received data to SSL int written = ::BIO_write ( ssl_bio_, recv_buf_.get_data_start(), recv_buf_.get_data_len() ); if (written > 0) { recv_buf_.data_removed(written); } else if (written < 0) { if (!BIO_should_retry(ssl_bio_)) { // Some serios error with BIO.... handler_(boost::asio::error::no_recovery, 0); return; } } // and try the SSL primitive again start(); } else { // Error in network level... // SSL can't continue either... handler_(error, 0); } } // Syncronous functions... int do_sync_write(bool is_operation_done, int rc) { int len = ::BIO_ctrl_pending( ssl_bio_ ); if ( len ) { // There is something to write into net, do it... len = (int)send_buf_.get_unused_len() > len? len: send_buf_.get_unused_len(); // Read outgoing data from bio len = ::BIO_read( ssl_bio_, send_buf_.get_unused_start(), len); if (len > 0) { size_t sent_len = boost::asio::write( socket_, boost::asio::buffer(send_buf_.get_unused_start(), len) ); send_buf_.data_added(len); send_buf_.data_removed(sent_len); } else if (!BIO_should_retry(ssl_bio_)) { // Seems like fatal error // reading from SSL BIO has failed... throw boost::system::system_error(boost::asio::error::no_recovery); } } if (is_operation_done) // Finish the operation, with success return rc; // Operation is not finished, start again. return start(); } int do_sync_read() { size_t len = socket_.read_some ( boost::asio::buffer(recv_buf_.get_unused_start(), recv_buf_.get_unused_len()) ); // Write data to ssl recv_buf_.data_added(len); // Pass the received data to SSL int written = ::BIO_write ( ssl_bio_, recv_buf_.get_data_start(), recv_buf_.get_data_len() ); if (written > 0) { recv_buf_.data_removed(written); } else if (written < 0) { if (!BIO_should_retry(ssl_bio_)) { // Some serios error with BIO.... throw boost::system::system_error(boost::asio::error::no_recovery); } } // Try the operation again return start(); } }; // class openssl_operation } // namespace detail } // namespace ssl } // namespace asio } // namespace boost #include
#endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_OPERATION_HPP
openssl_operation.hpp
Page URL
File URL
Prev
3/5
Next
Download
( 13 KB )
Note: The DriveHQ service banners will NOT be displayed if the file owner is a paid member.
Comments
Total ratings:
0
Average rating:
Not Rated
Would you like to comment?
Join DriveHQ
for a free account, or
Logon
if you are already a member.