2016-10-13 4 views
0

Boost Asio SSLストリームを使用してasync_handshakeを開始し、ハンドシェークが完了する前にストリームをキャンセル/閉じるためにデッドラインタイマーを実装すると、プログラムはバッファオーバーフロー例外でクラッシュします、私はまだLinuxを試していない)。ソケットがclose dで、外部ハンドラの実行が終了した後で、run()コマンドが完了する前にクラッシュが発生します。Boost.Asio async_handshakeをキャンセルすることはできません

SSLハンドシェイクの進行中にソケットを閉じることができない理由はありますか?これはBoost Asioのバグですか?

class Connection 
{ 
    void connect_handler(const boost::system::error_code &err) 
    { 
     ... 
     ssock->async_handshake(boost::asio::ssl::stream_base::client, 
        boost::bind(&Connection::handle_handshake, this, _1)); 
     ... 
    } 

    void handle_handshake(const boost::system::error_code &err) 
    { 
     // CONNECTED SECURELY 
    } 

    void handle_timeout() 
    { 
     // HANDLE SSL SHUTDOWN IF ALREADY CONNECTED... 
     ... 
     ssock->shutdown(boost::asio::ip::tcp::socket::shutdown_both); 
     ssock->close(); 
     delete ssock; 
    } 

    ... 

    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> *ssock; 
}; 

handle_handshake()は、IOサービスによって呼び出される前にio_service::run()方法でクラッシュしますhandle_timeout()を呼び出して、明確にします。

+0

あなたの 'Connection'オブジェクトは' timeout'の後にまだスコープ内にありますか? [boost-async-functions-and-shared-ptrs](http://stackoverflow.com/questions/11356742/boost-async-functions-and-shared-ptrs/19622084#19622084) – kenba

+0

を参照してください。 'io_service'は' Connection'クラスのメンバです。このメンバ上の 'io_service :: run()'メソッドは終了する前にクラッシュするので、OpenSSLの内部的な問題のようです。タイムアウトは、すべての標準TCPジョブで正常に機能します。 – owacoder

+0

'io_service'を接続のメンバーにするのは珍しいことですが、それは通常上位のオブジェクトです。私はあなたの 'Connection'クラスから取り出し、そのスコープが(少なくとも)' main() 'の終わりまで続くことを保証することをお勧めします... – kenba

答えて

0

問題は、非同期ハンドラが完了する前にソケットオブジェクトが破棄されていることです。保留中/キューに入れられたハンドラをキャンセルするには、このようなio_service::stop()を使用します。

io_service.stop(); // Stop the IO service to prevent handlers from executing 
ssock->shutdown(boost::asio::ip::tcp::socket::shutdown_both); 
ssock->close(); 
delete ssock; 

はありませんので、それはBoost.Asio自体のバグではありません。

関連する問題