Como encerrar normalmente um cliente boost asio ssl?
O cliente faz algumassl::stream<tcp_socket>::async_read_some()
/ssl::stream<tcp_socket>::async_write()
chamadas e em algum momento precisa sair, ou seja, precisa desligar a conexão.
Chamandossl::stream<tcp_socket>::lowest_layer().close()
funciona, mas (como esperado) o servidor (umopenssl s_server -state ...
comando) relata um erro ao fechar a conexão.
Olhar para a API da maneira certa parece ser chamarssl::stream<tcp_socket>::async_shutdown()
.
Agora, existem basicamente 2 situações em que é necessário um desligamento:
1) O cliente está noasync_read_some()
retorno de chamada e reage a um comando 'sair' do servidor. Ligando de láasync_shutdown()
gera um erro de 'leitura curta' no retorno de chamada de desligamento.
Isso é surpreendente, mas, depois de pesquisar no Google, esse parece ser um comportamento normal - parece que é preciso verificar se é um erro real ou não:
// const boost::system::error_code &ec
if (ec.category() == asio::error::get_ssl_category() &&
ec.value() == ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)) {
// -> not a real error, just a normal TLS shutdown
}
O servidor TLS parece estar feliz, no entanto - ele informa:
DONE
shutting down SSL
CONNECTION CLOSED
2) Aasync_read_some()
está ativo - mas um usuário decide sair do cliente (por exemplo, através de um comando do stdin). Ao ligarasync_shutdown()
a partir desse contexto, acontece o seguinte:
async_read_some()
retorno de chamada é executado com um código de erro 'leitura curta' - tipo de esperado agoraaasync_shutdown()
retorno de chamada é executado com umdescriptografia falhou ou registro incorreto mac código de erro - isso é inesperadoO lado do servidor não relata um erro.
Assim, minha pergunta como desligar corretamente um cliente TLS com boost asio.