ssl connection fixes
This commit is contained in:
parent
872d4e9a11
commit
e39ca5b012
|
|
@ -14,6 +14,7 @@
|
||||||
#include <amqpcpp.h>
|
#include <amqpcpp.h>
|
||||||
#include <amqpcpp/libev.h>
|
#include <amqpcpp/libev.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom handler
|
* Custom handler
|
||||||
|
|
@ -66,7 +67,11 @@ int main()
|
||||||
MyHandler handler(loop);
|
MyHandler handler(loop);
|
||||||
|
|
||||||
// init the SSL library
|
// init the SSL library
|
||||||
// SSL_library_init();
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
SSL_library_init();
|
||||||
|
#else
|
||||||
|
OPENSSL_init_ssl(0, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
// make a connection
|
// make a connection
|
||||||
AMQP::Address address("amqp://guest:guest@localhost/");
|
AMQP::Address address("amqp://guest:guest@localhost/");
|
||||||
|
|
|
||||||
|
|
@ -139,11 +139,14 @@ private:
|
||||||
}
|
}
|
||||||
else if (_closed)
|
else if (_closed)
|
||||||
{
|
{
|
||||||
|
// start the state that closes the connection
|
||||||
|
auto *nextstate = new SslShutdown(_connection, _socket, std::move(_ssl), _finalized, _handler);
|
||||||
|
|
||||||
// we forget the current socket to prevent that it gets destructed
|
// we forget the current socket to prevent that it gets destructed
|
||||||
_socket = -1;
|
_socket = -1;
|
||||||
|
|
||||||
// start the state that closes the connection
|
// report the next state
|
||||||
return new SslShutdown(_connection, _socket, std::move(_ssl), _finalized, _handler);
|
return nextstate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -263,7 +266,7 @@ public:
|
||||||
{
|
{
|
||||||
// tell the handler to monitor the socket if there is an out
|
// tell the handler to monitor the socket if there is an out
|
||||||
_handler->monitor(_connection, _socket, _state == state_sending ? readable | writable : readable);
|
_handler->monitor(_connection, _socket, _state == state_sending ? readable | writable : readable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ public:
|
||||||
_ssl(SslContext(OpenSSL::TLS_client_method())),
|
_ssl(SslContext(OpenSSL::TLS_client_method())),
|
||||||
_socket(socket),
|
_socket(socket),
|
||||||
_out(std::move(buffer))
|
_out(std::move(buffer))
|
||||||
{
|
{
|
||||||
// we will be using the ssl context as a client
|
// we will be using the ssl context as a client
|
||||||
OpenSSL::SSL_set_connect_state(_ssl);
|
OpenSSL::SSL_set_connect_state(_ssl);
|
||||||
|
|
||||||
|
|
@ -168,13 +168,13 @@ public:
|
||||||
|
|
||||||
// start the ssl handshake
|
// start the ssl handshake
|
||||||
int result = OpenSSL::SSL_do_handshake(_ssl);
|
int result = OpenSSL::SSL_do_handshake(_ssl);
|
||||||
|
|
||||||
// if the connection succeeds, we can move to the ssl-connected state
|
// if the connection succeeds, we can move to the ssl-connected state
|
||||||
if (result == 1) return nextstate(new SslConnected(_connection, _socket, std::move(_ssl), std::move(_out), _handler));
|
if (result == 1) return nextstate(new SslConnected(_connection, _socket, std::move(_ssl), std::move(_out), _handler));
|
||||||
|
|
||||||
// error was returned, so we must investigate what is going on
|
// error was returned, so we must investigate what is going on
|
||||||
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
||||||
|
|
||||||
// check the error
|
// check the error
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case SSL_ERROR_WANT_READ: return proceed(readable);
|
case SSL_ERROR_WANT_READ: return proceed(readable);
|
||||||
|
|
@ -217,15 +217,15 @@ public:
|
||||||
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
||||||
|
|
||||||
// check the error
|
// check the error
|
||||||
switch (error)
|
switch (error) {
|
||||||
{
|
|
||||||
// if openssl reports that socket readability or writability is needed,
|
// if openssl reports that socket readability or writability is needed,
|
||||||
// we wait for that until this situation is reached
|
// we wait for that until this situation is reached
|
||||||
case SSL_ERROR_WANT_READ: wait.readable(); break;
|
case SSL_ERROR_WANT_READ: wait.readable(); break;
|
||||||
case SSL_ERROR_WANT_WRITE: wait.active(); break;
|
case SSL_ERROR_WANT_WRITE: wait.active(); break;
|
||||||
|
|
||||||
// something is wrong, we proceed to the next state
|
// something is wrong, we proceed to the next state
|
||||||
default: return reportError(monitor);
|
default: return reportError(monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,28 @@ private:
|
||||||
bool _finalized;
|
bool _finalized;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the socket
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
bool close()
|
||||||
|
{
|
||||||
|
// skip if already closed
|
||||||
|
if (_socket < 0) return false;
|
||||||
|
|
||||||
|
// we're no longer interested in events
|
||||||
|
_handler->monitor(_connection, _socket, 0);
|
||||||
|
|
||||||
|
// close the socket
|
||||||
|
::close(_socket);
|
||||||
|
|
||||||
|
// forget the socket
|
||||||
|
_socket = -1;
|
||||||
|
|
||||||
|
// done
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report an error
|
* Report an error
|
||||||
* @param monitor object to check if connection still exists
|
* @param monitor object to check if connection still exists
|
||||||
|
|
@ -50,10 +72,7 @@ private:
|
||||||
TcpState *reporterror(const Monitor &monitor)
|
TcpState *reporterror(const Monitor &monitor)
|
||||||
{
|
{
|
||||||
// close the socket
|
// close the socket
|
||||||
close(_socket);
|
close();
|
||||||
|
|
||||||
// forget the socket
|
|
||||||
_socket = -1;
|
|
||||||
|
|
||||||
// if we have already told user space that connection is gone
|
// if we have already told user space that connection is gone
|
||||||
if (_finalized) return new TcpClosed(this);
|
if (_finalized) return new TcpClosed(this);
|
||||||
|
|
@ -76,14 +95,8 @@ private:
|
||||||
*/
|
*/
|
||||||
TcpState *proceed(const Monitor &monitor)
|
TcpState *proceed(const Monitor &monitor)
|
||||||
{
|
{
|
||||||
// we're no longer interested in events
|
|
||||||
_handler->monitor(_connection, _socket, 0);
|
|
||||||
|
|
||||||
// close the socket
|
// close the socket
|
||||||
close(_socket);
|
close();
|
||||||
|
|
||||||
// forget the socket
|
|
||||||
_socket = -1;
|
|
||||||
|
|
||||||
// if we have already told user space that connection is gone
|
// if we have already told user space that connection is gone
|
||||||
if (_finalized) return new TcpClosed(this);
|
if (_finalized) return new TcpClosed(this);
|
||||||
|
|
@ -108,7 +121,7 @@ private:
|
||||||
{
|
{
|
||||||
// error was returned, so we must investigate what is going on
|
// error was returned, so we must investigate what is going on
|
||||||
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
auto error = OpenSSL::SSL_get_error(_ssl, result);
|
||||||
|
|
||||||
// check the error
|
// check the error
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
|
|
@ -143,8 +156,8 @@ public:
|
||||||
_socket(socket),
|
_socket(socket),
|
||||||
_finalized(finalized)
|
_finalized(finalized)
|
||||||
{
|
{
|
||||||
// tell the handler to monitor the socket if there is an out
|
// wait until the socket is accessible
|
||||||
_handler->monitor(_connection, _socket, readable);
|
_handler->monitor(_connection, _socket, readable | writable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -152,14 +165,8 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual ~SslShutdown() noexcept
|
virtual ~SslShutdown() noexcept
|
||||||
{
|
{
|
||||||
// skip if socket is already gond
|
|
||||||
if (_socket < 0) return;
|
|
||||||
|
|
||||||
// we no longer have to monitor the socket
|
|
||||||
_handler->monitor(_connection, _socket, 0);
|
|
||||||
|
|
||||||
// close the socket
|
// close the socket
|
||||||
close(_socket);
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -182,7 +189,7 @@ public:
|
||||||
|
|
||||||
// close the connection
|
// close the connection
|
||||||
auto result = OpenSSL::SSL_shutdown(_ssl);
|
auto result = OpenSSL::SSL_shutdown(_ssl);
|
||||||
|
|
||||||
// if this is a success, we can proceed with the event loop
|
// if this is a success, we can proceed with the event loop
|
||||||
if (result > 0) return proceed(monitor);
|
if (result > 0) return proceed(monitor);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue