Is it possible to do async_handshake after reading from socket prior using Boost::asio?

我是研究僧i 提交于 2020-06-01 17:14:13

问题


I have a boost::asio::ssl::stream<boost::asio::ip::tcp::socket> typed socket. When boost first accepts a connection to this socket, I want to peek at some bytes. However, peeking is not something you can do properly/safely. So I read the bytes I need and have them in a buffer.

typedef socket_type boost::asio::ssl::stream<boost::asio::ip::tcp::socket>;
void OnAccept(std::shared_ptr<socket_type> socket)
{
    boost::asio::mutable_buffers_1 sslBuffer(m_Buffer.data(), m_Buffer.size());
    // I'm going to read 4 bytes from the socket.
    boost::system::error_code ec;
    std::size_t readBytes = boost::asio::read(socket->next_layer(), boost::asio::buffer(sslBuffer, 4), ec);
    if(ec) { Stop(); return; } // pseudo

    // Check the bytes I read in the buffer

    socket->async_handshake(boost::asio::ssl::stream_base::server, sslBuffer, &handler);
}

At this point, async_handshake's handler will be called but it will tell me it got an unexpected message error code from ssl. This makes sense: the message it's doing the handshake with is missing the first 4 bytes likely!

What can I do to provide async_handshake with the proper buffer that informs it that there is already valid 4 bytes in it?


回答1:


After investigating the implementation of async_handshake's buffer overload method, it appears that the buffer must already have the handshake read in.

I attempted that but still encountered issues, I kept getting an error code saying that the SSL version was incorrect. I knew this was not the issue because not using the buffered overload of async_handshake worked fine!

The solution was then to also limit the buffer parameter's size.

typedef socket_type boost::asio::ssl::stream<boost::asio::ip::tcp::socket>;
void OnAccept(std::shared_ptr<socket_type> socket)
{
    const uint bytesToPeek = 4;
    boost::asio::mutable_buffers_1 sslBuffer(m_Buffer.data(), m_Buffer.size());
    // I'm going to read 4 bytes from the socket.
    boost::system::error_code ec;
    std::size_t readBytes = boost::asio::read(socket->next_layer(), boost::asio::buffer(sslBuffer, bytesToPeek), ec);
    if(ec) { Stop(); return; } // pseudo

    // Check the bytes I read in the buffer

    // Read in the rest of the handshake.
    std::size_t bytesOfHandshake = socket->next_layer().read_some(boost::asio::buffer(sslBuffer+bytesToPeek, 4000));
    bytesOfHandshake += bytesToPeek;

    // Finish the handshake.
    socket->async_handshake(boost::asio::ssl::stream_base::server, boost::asio::buffer(sslBuffer, bytesOfHandshake), &handler);
}

Note that both the read and read_some calls in this should also be made async. I just wanted to demonstrate the answer without handlers.



来源:https://stackoverflow.com/questions/55765938/is-it-possible-to-do-async-handshake-after-reading-from-socket-prior-using-boost

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!