mirror of
https://github.com/debauchee/barrier.git
synced 2025-07-17 00:25:40 +02:00
Made socket self-aware of when it is in a fatal state #4697
Added code to cleanly terminate connection on fatal socket state #4697
This commit is contained in:
parent
e4f86a8934
commit
5b3fa48902
6 changed files with 84 additions and 40 deletions
|
@ -52,7 +52,8 @@ SecureSocket::SecureSocket(
|
|||
SocketMultiplexer* socketMultiplexer) :
|
||||
TCPSocket(events, socketMultiplexer),
|
||||
m_secureReady(false),
|
||||
m_maxRetry(MAX_RETRY_COUNT)
|
||||
m_maxRetry(MAX_RETRY_COUNT),
|
||||
m_fatal(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -62,12 +63,14 @@ SecureSocket::SecureSocket(
|
|||
ArchSocket socket) :
|
||||
TCPSocket(events, socketMultiplexer, socket),
|
||||
m_secureReady(false),
|
||||
m_maxRetry(MAX_RETRY_COUNT)
|
||||
m_maxRetry(MAX_RETRY_COUNT),
|
||||
m_fatal(false)
|
||||
{
|
||||
}
|
||||
|
||||
SecureSocket::~SecureSocket()
|
||||
{
|
||||
isFatal(true);
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
SSL_shutdown(m_ssl->m_ssl);
|
||||
|
||||
|
@ -78,13 +81,15 @@ SecureSocket::~SecureSocket()
|
|||
SSL_CTX_free(m_ssl->m_context);
|
||||
m_ssl->m_context = NULL;
|
||||
}
|
||||
|
||||
ARCH->sleep(1);
|
||||
delete m_ssl;
|
||||
}
|
||||
|
||||
void
|
||||
SecureSocket::close()
|
||||
{
|
||||
isFatal(true);
|
||||
|
||||
SSL_shutdown(m_ssl->m_ssl);
|
||||
|
||||
TCPSocket::close();
|
||||
|
@ -114,17 +119,23 @@ SecureSocket::secureRead(void* buffer, UInt32 n)
|
|||
LOG((CLOG_DEBUG2 "reading secure socket"));
|
||||
r = SSL_read(m_ssl->m_ssl, buffer, n);
|
||||
|
||||
bool fatal;
|
||||
static int retry;
|
||||
|
||||
checkResult(r, fatal, retry);
|
||||
// Check result will cleanup the connection in the case of a fatal
|
||||
checkResult(r, retry);
|
||||
|
||||
if (retry) {
|
||||
r = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isFatal()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return r > 0 ? (UInt32)r : 0;
|
||||
// According to SSL spec, r must not be negative and not have an error code
|
||||
// from SSL_get_error(). If this happens, it is itself an error. Let the
|
||||
// parent handle the case
|
||||
return (UInt32)r;
|
||||
}
|
||||
|
||||
UInt32
|
||||
|
@ -132,20 +143,27 @@ SecureSocket::secureWrite(const void* buffer, UInt32 n)
|
|||
{
|
||||
int r = 0;
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
LOG((CLOG_DEBUG2 "writing secure socket"));
|
||||
LOG((CLOG_DEBUG2 "writing secure socket:%p", this));
|
||||
|
||||
r = SSL_write(m_ssl->m_ssl, buffer, n);
|
||||
|
||||
bool fatal;
|
||||
static int retry;
|
||||
|
||||
checkResult(r, fatal, retry);
|
||||
// Check result will cleanup the connection in the case of a fatal
|
||||
checkResult(r, retry);
|
||||
|
||||
if (retry) {
|
||||
r = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isFatal()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return r > 0 ? (UInt32)r : 0;
|
||||
// According to SSL spec, r must not be negative and not have an error code
|
||||
// from SSL_get_error(). If this happens, it is itself an error. Let the
|
||||
// parent handle the case
|
||||
return (UInt32)r;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -260,12 +278,11 @@ SecureSocket::secureAccept(int socket)
|
|||
LOG((CLOG_DEBUG2 "accepting secure socket"));
|
||||
int r = SSL_accept(m_ssl->m_ssl);
|
||||
|
||||
bool fatal;
|
||||
static int retry;
|
||||
|
||||
checkResult(r, fatal, retry);
|
||||
checkResult(r, retry);
|
||||
|
||||
if (fatal) {
|
||||
if (isFatal()) {
|
||||
// tell user and sleep so the socket isn't hammered.
|
||||
LOG((CLOG_ERR "failed to accept secure socket"));
|
||||
LOG((CLOG_INFO "client connection may not be secure"));
|
||||
|
@ -304,12 +321,11 @@ SecureSocket::secureConnect(int socket)
|
|||
LOG((CLOG_DEBUG2 "connecting secure socket"));
|
||||
int r = SSL_connect(m_ssl->m_ssl);
|
||||
|
||||
bool fatal;
|
||||
static int retry;
|
||||
|
||||
checkResult(r, fatal, retry);
|
||||
checkResult(r, retry);
|
||||
|
||||
if (fatal) {
|
||||
if (isFatal()) {
|
||||
LOG((CLOG_ERR "failed to connect secure socket"));
|
||||
return -1;
|
||||
}
|
||||
|
@ -362,13 +378,11 @@ SecureSocket::showCertificate()
|
|||
}
|
||||
|
||||
void
|
||||
SecureSocket::checkResult(int n, bool& fatal, int& retry)
|
||||
SecureSocket::checkResult(int n, int& retry)
|
||||
{
|
||||
// ssl errors are a little quirky. the "want" errors are normal and
|
||||
// should result in a retry.
|
||||
|
||||
fatal = false;
|
||||
|
||||
int errorCode = SSL_get_error(m_ssl->m_ssl, n);
|
||||
switch (errorCode) {
|
||||
case SSL_ERROR_NONE:
|
||||
|
@ -378,8 +392,8 @@ SecureSocket::checkResult(int n, bool& fatal, int& retry)
|
|||
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
// connection closed
|
||||
retry = 0;
|
||||
LOG((CLOG_DEBUG2 "SSL connection has been closed"));
|
||||
isFatal(true);
|
||||
LOG((CLOG_DEBUG "SSL connection has been closed"));
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
|
@ -389,7 +403,7 @@ SecureSocket::checkResult(int n, bool& fatal, int& retry)
|
|||
retry += 1;
|
||||
// If there are a lot of retrys, it's worth warning about
|
||||
if ( retry % 5 == 0 ) {
|
||||
LOG((CLOG_INFO "need to retry the same SSL function(%d) retry:%d", errorCode, retry));
|
||||
LOG((CLOG_DEBUG "need to retry the same SSL function(%d) retry:%d", errorCode, retry));
|
||||
}
|
||||
else if ( retry == (maxRetry() / 2) ) {
|
||||
LOG((CLOG_WARN "need to retry the same SSL function(%d) retry:%d", errorCode, retry));
|
||||
|
@ -416,27 +430,27 @@ SecureSocket::checkResult(int n, bool& fatal, int& retry)
|
|||
}
|
||||
}
|
||||
|
||||
fatal = true;
|
||||
isFatal(true);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SSL:
|
||||
LOG((CLOG_ERR "a failure in the SSL library occurred"));
|
||||
fatal = true;
|
||||
isFatal(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG((CLOG_ERR "unknown secure socket error"));
|
||||
fatal = true;
|
||||
isFatal(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// If the retry max would exceed the allowed, treat it as a fatal error
|
||||
if (retry > maxRetry()) {
|
||||
LOG((CLOG_ERR "Maximum retry count exceeded:%d",retry));
|
||||
fatal = true;
|
||||
isFatal(true);
|
||||
}
|
||||
|
||||
if (fatal) {
|
||||
if (isFatal()) {
|
||||
retry = 0;
|
||||
showError();
|
||||
disconnect();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue