【问题标题】:BIO_do_handshake return 0BIO_do_handshake 返回 0
【发布时间】:2014-05-11 11:28:39
【问题描述】:

我正在尝试编写一个非阻塞连接,当我执行 BIO_do_handshake() 时,使用下面的代码它总是返回 0。我知道你不一定需要 'do_handshake()',但一切似乎看来应该这样做以确保握手完成。

我应该调用 BIO_should_retry() 吗?

void SSLAdaptor::Connect( SSL_CTX *ctx
                        , const std::string &hostname
                        , int port
                        , bool nonBlocking )
{

struct hostent *hp;
struct sockaddr_in addr;
SOCKET sockFD;

if( !( hp = gethostbyname( hostname.c_str() ) ) )
{
    return;
}

memset( &addr, 0, sizeof( addr ) );

addr.sin_addr= *( struct in_addr* )hp->h_addr_list[0];
addr.sin_family=AF_INET;
addr.sin_port=htons(port);

if( ( sockFD =socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) <0 )
{
    return;
}

if(connect(sockFD,(struct sockaddr *)&addr, sizeof(addr))<0)
{
    return;
}

SSL *ssl;
BIO *sbio;

ssl = SSL_new( ctx );

sbio = BIO_new_socket( sockFD, BIO_NOCLOSE );
SSL_set_bio( ssl, sbio, sbio );

if( SSL_connect( ssl ) <= 0 )
{
     return;
}

long hsReturn = BIO_do_handshake( sbio );

if ( hsReturn <= 0 ) 
{
    return;
}

}

我的(非阻塞)BIO 读取返回垃圾: 实际:↨♥ +o 1E¿={û²∙ìφáD'öQñ↨▼≈☺ 预期:这是一条测试消息

int SSLSocket::BIORead( std::string &buffer, const int size )
{
int bytesRead = -1;
std::vector<char> readBuffer(size);

std::cout << "Before BIO_read() call" << std::endl;
bytesRead = BIO_read( m_bio, readBuffer.data(), size );
std::cout << "After BIO_read() call" << std::endl;
std::cout << "BIO_read() read   : " << bytesRead << " bytes" << std::endl;

std::string tmpBuffer = std::string( readBuffer.begin(), readBuffer.end() );
std::cout << "BIO_read() buffer : " << tmpBuffer << " bytes" << std::endl;

if ( bytesRead < 0 ) 
{
    //  Check if should retry read, if not then an error on the connection
    //  has occurred and the user notified.
    if ( BIO_should_retry( m_bio ) )
    {
        bytesRead = 0;
    }
    else
    {
      // real error
      bytesRead = -1;
  }
}
else if ( bytesRead == 0 ) 
{
    //  Nothing was read
    bytesRead = 0;
}
else
{
    buffer = std::string( readBuffer.begin(), readBuffer.end() );
}

return bytesRead;
}

【问题讨论】:

  • 添加了检查:if (BIO_should_retry(sbio) == false),这总是返回 false

标签: c++ openssl open-source


【解决方案1】:

SSL_connect 已经进行了握手,但您必须正确使用它与非阻塞套接字,例如检查 SSL_ERROR_WANT_READ、SSL_ERROR_WANT_WRITE 并等待所需条件,只要 SSL_connect 返回

【讨论】:

  • 抱歉,您的意思是在连接或使用 bio_write 和 bio_read 时进行 WANT_READ/WRITE 检查?
  • 如果套接字在 SSL_connect 期间是非阻塞的,您也必须在那里使用这些检查,请参阅文档 openssl.org/docs/ssl/SSL_connect.html
  • 请不要混合使用 SSL 和 BIO。如果您使用 SSL,请使用 SSL_read、SSL_write、SSL_connect。套接字 bio 上的 BIO_read/write 将直接在套接字上读/写,例如read 将得到加密的数据。并且请为 SSL_connect 添加正确的错误检查(打印错误信息)和非阻塞情况的正确处理。
猜你喜欢
  • 2013-03-30
  • 2015-06-15
  • 1970-01-01
  • 2015-06-21
  • 2016-10-28
  • 2019-02-20
  • 2015-06-17
  • 2012-01-04
  • 2018-02-23
相关资源
最近更新 更多