Fixed successful SSL_accept calls causing another call to SSL_accept.
This commit is contained in:
@ -1046,7 +1046,7 @@ int dcb_read_SSL(
|
|||||||
int rc;
|
int rc;
|
||||||
int n;
|
int n;
|
||||||
int nread = 0;
|
int nread = 0;
|
||||||
|
int ssl_errno = 0;
|
||||||
CHK_DCB(dcb);
|
CHK_DCB(dcb);
|
||||||
|
|
||||||
if (dcb->fd <= 0)
|
if (dcb->fd <= 0)
|
||||||
@ -1062,7 +1062,7 @@ int dcb_read_SSL(
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
int bufsize;
|
int bufsize;
|
||||||
int ssl_errno = 0;
|
ssl_errno = 0;
|
||||||
rc = ioctl(dcb->fd, FIONREAD, &b);
|
rc = ioctl(dcb->fd, FIONREAD, &b);
|
||||||
pending = SSL_pending(dcb->ssl);
|
pending = SSL_pending(dcb->ssl);
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
@ -1096,9 +1096,9 @@ int dcb_read_SSL(
|
|||||||
if(ssl_errno != SSL_ERROR_WANT_READ &&
|
if(ssl_errno != SSL_ERROR_WANT_READ &&
|
||||||
ssl_errno != SSL_ERROR_WANT_WRITE &&
|
ssl_errno != SSL_ERROR_WANT_WRITE &&
|
||||||
ssl_errno != SSL_ERROR_NONE)
|
ssl_errno != SSL_ERROR_NONE)
|
||||||
{
|
|
||||||
n = -1;
|
n = -1;
|
||||||
}
|
else
|
||||||
|
n = 0;
|
||||||
goto return_n;
|
goto return_n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1192,7 +1192,7 @@ int dcb_read_SSL(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
n = -1;
|
||||||
gwbuf_free(buffer);
|
gwbuf_free(buffer);
|
||||||
goto return_n;
|
goto return_n;
|
||||||
}
|
}
|
||||||
@ -1595,7 +1595,7 @@ dcb_write_SSL(DCB *dcb, GWBUF *queue)
|
|||||||
|
|
||||||
if (w < 0)
|
if (w < 0)
|
||||||
{
|
{
|
||||||
int ssl_errno = ERR_get_error();
|
int ssl_errno = SSL_get_error(dcb->ssl,w);
|
||||||
|
|
||||||
if (LOG_IS_ENABLED(LOGFILE_DEBUG))
|
if (LOG_IS_ENABLED(LOGFILE_DEBUG))
|
||||||
{
|
{
|
||||||
@ -1633,6 +1633,17 @@ dcb_write_SSL(DCB *dcb, GWBUF *queue)
|
|||||||
dcb,
|
dcb,
|
||||||
STRDCBSTATE(dcb->state),
|
STRDCBSTATE(dcb->state),
|
||||||
dcb->fd,ssl_errno)));
|
dcb->fd,ssl_errno)));
|
||||||
|
if(ssl_errno == SSL_ERROR_SSL ||
|
||||||
|
ssl_errno == SSL_ERROR_SYSCALL)
|
||||||
|
{
|
||||||
|
while((ssl_errno = ERR_get_error()) != 0)
|
||||||
|
{
|
||||||
|
char errbuf[140];
|
||||||
|
ERR_error_string(ssl_errno,errbuf);
|
||||||
|
skygw_log_write(LE,"%s",errbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3016,7 +3027,7 @@ int dcb_accept_SSL(DCB* dcb)
|
|||||||
rval = 1;
|
rval = 1;
|
||||||
LOGIF(LD,(skygw_log_write_flush(LD,"[dcb_accept_SSL] SSL_accept done for %s",
|
LOGIF(LD,(skygw_log_write_flush(LD,"[dcb_accept_SSL] SSL_accept done for %s",
|
||||||
dcb->remote)));
|
dcb->remote)));
|
||||||
break;
|
return rval;
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
|
|
||||||
@ -3035,10 +3046,10 @@ int dcb_accept_SSL(DCB* dcb)
|
|||||||
{
|
{
|
||||||
rval = -1;
|
rval = -1;
|
||||||
skygw_log_write(LE,
|
skygw_log_write(LE,
|
||||||
"Error: Fatal error in SSL_accept for %s: (SSL error code: %d):%s",
|
"Error: Fatal error in SSL_accept for %s: (SSL version: %s SSL error code: %d)",
|
||||||
dcb->remote,
|
dcb->remote,
|
||||||
errnum,
|
SSL_get_version(dcb->ssl),
|
||||||
strerror(errno));
|
errnum);
|
||||||
if(errnum == SSL_ERROR_SSL ||
|
if(errnum == SSL_ERROR_SSL ||
|
||||||
errnum == SSL_ERROR_SYSCALL)
|
errnum == SSL_ERROR_SYSCALL)
|
||||||
{
|
{
|
||||||
@ -3104,8 +3115,7 @@ int dcb_connect_SSL(DCB* dcb)
|
|||||||
case -1:
|
case -1:
|
||||||
errnum = SSL_get_error(dcb->ssl,rval);
|
errnum = SSL_get_error(dcb->ssl,rval);
|
||||||
|
|
||||||
if(errnum == SSL_ERROR_WANT_READ || errnum == SSL_ERROR_WANT_WRITE ||
|
if(errnum == SSL_ERROR_WANT_READ || errnum == SSL_ERROR_WANT_WRITE)
|
||||||
errnum == SSL_ERROR_WANT_X509_LOOKUP)
|
|
||||||
{
|
{
|
||||||
/** Not all of the data has been read. Go back to the poll
|
/** Not all of the data has been read. Go back to the poll
|
||||||
queue and wait for more.*/
|
queue and wait for more.*/
|
||||||
|
|||||||
@ -40,7 +40,16 @@
|
|||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define _XOPEN_SOURCE 700
|
#define _XOPEN_SOURCE 700
|
||||||
|
#define OPENSSL_THREAD_DEFINES
|
||||||
#include <my_config.h>
|
#include <my_config.h>
|
||||||
|
|
||||||
|
#include <openssl/opensslconf.h>
|
||||||
|
#if defined(OPENSSL_THREADS)
|
||||||
|
#define HAVE_OPENSSL_THREADS 1
|
||||||
|
#else
|
||||||
|
#define HAVE_OPENSSL_THREADS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
@ -196,9 +205,46 @@ static bool resolve_maxscale_conf_fname(
|
|||||||
|
|
||||||
static char* check_dir_access(char* dirname,bool,bool);
|
static char* check_dir_access(char* dirname,bool,bool);
|
||||||
static int set_user();
|
static int set_user();
|
||||||
static void maxscale_ssl_lock(int mode,int n,const char* file, int line);
|
|
||||||
static unsigned long maxscale_ssl_id();
|
/** SSL multi-threading functions and structures */
|
||||||
static SPINLOCK* ssl_locks;
|
|
||||||
|
struct CRYPTO_dynlock_value
|
||||||
|
{
|
||||||
|
SPINLOCK lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct CRYPTO_dynlock_value *ssl_create_dynlock(const char* file, int line)
|
||||||
|
{
|
||||||
|
struct CRYPTO_dynlock_value* lock = malloc(sizeof(struct CRYPTO_dynlock_value));
|
||||||
|
if(lock)
|
||||||
|
{
|
||||||
|
spinlock_init(&lock->lock);
|
||||||
|
}
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ssl_lock_dynlock(int mode,struct CRYPTO_dynlock_value * n,const char* file, int line)
|
||||||
|
{
|
||||||
|
if(mode & CRYPTO_LOCK)
|
||||||
|
{
|
||||||
|
spinlock_acquire(&n->lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spinlock_release(&n->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ssl_free_dynlock(struct CRYPTO_dynlock_value * n,const char* file, int line)
|
||||||
|
{
|
||||||
|
free(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void maxscale_ssl_id(CRYPTO_THREADID* id)
|
||||||
|
{
|
||||||
|
CRYPTO_THREADID_set_numeric(id,pthread_self());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for SIGHUP signal. Reload the configuration for the
|
* Handler for SIGHUP signal. Reload the configuration for the
|
||||||
* gateway.
|
* gateway.
|
||||||
@ -1374,23 +1420,21 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** OpenSSL initialization */
|
/** OpenSSL initialization */
|
||||||
|
if(!HAVE_OPENSSL_THREADS)
|
||||||
SSL_library_init();
|
|
||||||
SSL_load_error_strings();
|
|
||||||
OPENSSL_add_all_algorithms_noconf();
|
|
||||||
|
|
||||||
int n_locks = CRYPTO_num_locks();
|
|
||||||
if((ssl_locks = malloc(n_locks*sizeof(SPINLOCK))) == NULL)
|
|
||||||
{
|
{
|
||||||
|
char* logerr = "OpenSSL library does not support multi-threading";
|
||||||
|
print_log_n_stderr(true, true, logerr, logerr, eno);
|
||||||
rc = MAXSCALE_INTERNALERROR;
|
rc = MAXSCALE_INTERNALERROR;
|
||||||
goto return_main;
|
goto return_main;
|
||||||
}
|
}
|
||||||
|
SSL_library_init();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
OPENSSL_add_all_algorithms_noconf();
|
||||||
|
CRYPTO_set_dynlock_create_callback(ssl_create_dynlock);
|
||||||
|
CRYPTO_set_dynlock_destroy_callback(ssl_free_dynlock);
|
||||||
|
CRYPTO_set_dynlock_lock_callback(ssl_lock_dynlock);
|
||||||
|
CRYPTO_THREADID_set_callback(maxscale_ssl_id);
|
||||||
|
|
||||||
for(i = 0;i<n_locks;i++)
|
|
||||||
spinlock_init(&ssl_locks[i]);
|
|
||||||
|
|
||||||
CRYPTO_set_locking_callback(maxscale_ssl_lock);
|
|
||||||
CRYPTO_set_id_callback(maxscale_ssl_id);
|
|
||||||
/* register exit function for embedded MySQL library */
|
/* register exit function for embedded MySQL library */
|
||||||
l = atexit(libmysqld_done);
|
l = atexit(libmysqld_done);
|
||||||
|
|
||||||
@ -2023,19 +2067,3 @@ static int set_user(char* user)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void maxscale_ssl_lock(int mode,int n,const char* file, int line)
|
|
||||||
{
|
|
||||||
if(mode & CRYPTO_LOCK)
|
|
||||||
{
|
|
||||||
spinlock_acquire(&ssl_locks[n]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spinlock_release(&ssl_locks[n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long maxscale_ssl_id()
|
|
||||||
{
|
|
||||||
return (unsigned long)pthread_self();
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user