c++ - Boost.Asio: SSL Server and Client. Server SIGSEGV and Client Short Read error -


i have built ssl samples of boost , have run them no obvious problems. have written own code using http server , ssl examples references. when run code got error client:

handshake failed. error: short read 

and server:

debug: connectionmanager::connectionmanager() debug: server::server(boost::asio::io_service&, short unsigned int) debug: std::__cxx11::string server::hpasswordhandler() const debug: void server::startaccept() debug: connection::connection(boost::asio::io_service&, boost::asio::ssl::context&, connectionmanager&) debug: boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >::lowest_layer_type& connection::socket() debug: void server::haccept(const boost::system::error_code&) debug: void connection::start() debug: void server::startaccept() debug: connection::connection(boost::asio::io_service&, boost::asio::ssl::context&, connectionmanager&) debug: boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >::lowest_layer_type& connection::socket() segmentation fault 

the debug: thing tried make little debugging. segmentation fault happens when connect server.

so ideas?

my server code:

#include <iostream> #include <sstream> #include <locale> #include <string> #include <set> #include <boost/enable_shared_from_this.hpp> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp> #include <boost/thread.hpp>  inline void debug_msg(const std::string &instr) {     std::string res = "debug: ";     res += instr;     res += "\n";     std::cout << res;     std::cout.flush(); // since don't use std::endl }  #if defined(debug) && !defined(ndebug) #define _func_debug_    debug_msg(__pretty_function__); #else #define _func_debug_ #endif  typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket_t;  class connectionmanager;  class connection :     public boost::enable_shared_from_this<connection> { public:     connection(const connection&) = delete;     connection &operator=(const connection&) = delete;     explicit connection(         boost::asio::io_service &io_service,         boost::asio::ssl::context &context,         connectionmanager &connectionmanager) :         socket_(io_service, context),         connectionmanager_(connectionmanager) {         _func_debug_     }     ssl_socket_t::lowest_layer_type &socket() {         _func_debug_         return socket_.lowest_layer();     }     void start() {         _func_debug_         socket_.async_handshake(                 boost::asio::ssl::stream_base::server,                 boost::bind(&connection::hhandshake,                     this,                     boost::asio::placeholders::error));     }     void stop() {         _func_debug_         socket_.lowest_layer().cancel();         socket_.shutdown();         socket_.lowest_layer().close();     } protected:     ssl_socket_t socket_;     connectionmanager &connectionmanager_;     boost::asio::streambuf readbuffer_;     std::string message_;     void hhandshake(const boost::system::error_code &error) {         _func_debug_         if (!error) {             boost::asio::async_read_until(socket_, readbuffer_, '\0',                 boost::bind(&connection::hreaduntil, this,                     boost::asio::placeholders::error,                     boost::asio::placeholders::bytes_transferred));         }         else if (error != boost::asio::error::operation_aborted) {             notifyconnectionmanagertostop();         }     }     void hreaduntil(         const boost::system::error_code &error,         size_t bytes_transferred) {         _func_debug_         if (!error) {             std::string s;             std::istream is(&readbuffer_);             std::getline(is, s, '\0');             std::cout << "message: " << s << std::endl;             message_ = "server received message!";             message_ += std::string("", 1);             boost::asio::async_write(socket_,                 boost::asio::buffer(message_, message_.size()),                 boost::bind(&connection::hwrite, this,                     boost::asio::placeholders::error,                     boost::asio::placeholders::bytes_transferred));         }         else if (error != boost::asio::error::operation_aborted) {             // if operation aborted, connection manager             // knows it, since sockets             // can stopped connection manager             notifyconnectionmanagertostop();         }     }     void hwrite(         const boost::system::error_code &error,         size_t bytes_transferred) {         _func_debug_         if (!error) {             // nothing else do.         }         else if (error != boost::asio::error::operation_aborted) {             notifyconnectionmanagertostop();         }     }     void notifyconnectionmanagertostop(); };  typedef boost::shared_ptr<connection> connection_ptr;  class connectionmanager { public:     connectionmanager(const connectionmanager&) = delete;     connectionmanager &operator=(const connectionmanager&) = delete;     connectionmanager() {         _func_debug_     }     void start(connection_ptr connection) {         _func_debug_         connections_.insert(connection);         connection->start();     }     void stop(connection_ptr connection) {         _func_debug_         connections_.erase(connection);         connection->stop();     }     void stopall() {         _func_debug_         (auto connection : connections_)             connection->stop();         connections_.clear();     } protected:     std::set<connection_ptr> connections_; };  void connection::notifyconnectionmanagertostop() {     _func_debug_     connectionmanager_.stop(shared_from_this()); }  class server { public:     server(const server &) = delete;     server &operator=(const server &) = delete;      server(         boost::asio::io_service &io_service,         unsigned short port) :         io_service_(io_service),         acceptor_(io_service,             boost::asio::ip::tcp::endpoint(                 boost::asio::ip::tcp::v4(), port)),         context_(boost::asio::ssl::context::sslv23)     {         _func_debug_         context_.set_options(             boost::asio::ssl::context::default_workarounds |             boost::asio::ssl::context::no_sslv2 |             boost::asio::ssl::context::single_dh_use         );         context_.set_password_callback(boost::bind(&server::hpasswordhandler,             this));         context_.use_certificate_chain_file("server.crt");         context_.use_private_key_file("server.key",             boost::asio::ssl::context::pem);         context_.use_tmp_dh_file("dh1024.pem");         startaccept();     } protected:     boost::asio::io_service &io_service_;     boost::asio::ip::tcp::acceptor acceptor_;     boost::asio::ssl::context context_;     connectionmanager connection_manager_;     connection_ptr new_connection_;     std::string hpasswordhandler() const {         _func_debug_         return "somehow return password";     }     void haccept(const boost::system::error_code &error) {         _func_debug_         if (!error) {             new_connection_->start();             startaccept();         }         else {             new_connection_.reset();         }     }     void startaccept() {         _func_debug_         new_connection_.reset(new connection(io_service_,             context_, connection_manager_));         acceptor_.async_accept(new_connection_->socket(),             boost::bind(&server::haccept, this,                 boost::asio::placeholders::error));     } };  int main(int argc, char **argv) {     try {         if (argc != 2) {             std::cerr << "usage: program <port>" << std::endl;             return 1;         }         boost::asio::io_service io_service;         server server(io_service, std::atoi(argv[1]));         boost::thread t(boost::bind(&boost::asio::io_service::run,             &io_service));         std::cin.get();         io_service.stop();         t.join();         return 0;     }     catch (std::exception &e) {         std::cerr << "exception: " << e.what() << std::endl;         return 2;     } } 

my client code:

#include <iostream> #include <string> #include <boost/bind.hpp> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp>  class client { protected:     boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;     std::string message_;     boost::asio::streambuf readbuffer_;     bool hverifycertificate(bool preverified,         boost::asio::ssl::verify_context &ctx) {         return preverified;     }     void hconnect(const boost::system::error_code &error) {         if (!error) {             socket_.async_handshake(boost::asio::ssl::stream_base::client,                 boost::bind(&client::hhandshake, this,                     boost::asio::placeholders::error));         }         else {             std::cout << "connect failed. error: " <<                 error.message() << std::endl;         }     }     void hreaduntil(const boost::system::error_code &error,             size_t bytes_transferred) {         if (!error) {             std::string s;             std::istream is(&readbuffer_);             std::getline(is, s, '\0');             std::cout << s << std::endl;         }         else {             std::cout << "read failed. error: " <<                 error.message() << std::endl;         }     }     void hwrite(const boost::system::error_code &error,         size_t bytes_transferred) {         if (!error) {             boost::asio::async_read_until(socket_, readbuffer_, '\0',                 boost::bind(&client::hreaduntil, this,                     boost::asio::placeholders::error,                     boost::asio::placeholders::bytes_transferred));         }         else {             std::cout << "write failed. error: " <<                 error.message() << std::endl;         }     }     void hhandshake(const boost::system::error_code &error) {         if (!error) {             std::cout << "to send message type something: ";             std::getline(std::cin, message_);             message_ += std::string("", 1); // append null character             boost::asio::async_write(socket_,                 boost::asio::buffer(message_, message_.size()),                 boost::bind(&client::hwrite, this,                     boost::asio::placeholders::error,                     boost::asio::placeholders::bytes_transferred));         }         else {             std::cout << "handshake failed. error: " <<                 error.message() << std::endl;         }     } public:     client(boost::asio::io_service &io_service,         boost::asio::ssl::context& context,         boost::asio::ip::tcp::resolver::iterator endpoint_iterator)         : socket_(io_service, context) {         socket_.set_verify_mode(boost::asio::ssl::verify_peer);         socket_.set_verify_callback(boost::bind(&client::hverifycertificate,             this, _1, _2));         boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,             boost::bind(&client::hconnect, this,                 boost::asio::placeholders::error));     } };  int main(int argc, char **argv) {     try {         if (argc != 3) {             std::cerr << "usage: program <host> <port>" << std::endl;             return 1;         }         boost::asio::io_service io_service;         boost::asio::ip::tcp::resolver resolver(io_service);         boost::asio::ip::tcp::resolver::query query(argv[1], argv[2]);         boost::asio::ip::tcp::resolver::iterator iterator =             resolver.resolve(query);         boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);         ctx.load_verify_file("server.crt");         client client(io_service, ctx, iterator);         io_service.run();         return 0;     }     catch (std::exception &e) {         std::cerr << "exception: " << e.what() << std::endl;         return 1;     } } 

i have used the description here generate ssl related files.

well, simple bug. forgot starting new connection through connection manager connection object deleted , receive segmentation fault. problem solved. :d


Comments

Popular posts from this blog

php - Admin SDK -- get information about the group -

dns - How To Use Custom Nameserver On Free Cloudflare? -

Python Error - TypeError: input expected at most 1 arguments, got 3 -