diff --git a/server/core/dcb.c b/server/core/dcb.c index 4c9dd0324..e7c74b6bc 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1046,7 +1046,7 @@ int dcb_read_SSL( int rc; int n; int nread = 0; - + int ssl_errno = 0; CHK_DCB(dcb); if (dcb->fd <= 0) @@ -1062,7 +1062,7 @@ int dcb_read_SSL( while (true) { int bufsize; - int ssl_errno = 0; + ssl_errno = 0; rc = ioctl(dcb->fd, FIONREAD, &b); pending = SSL_pending(dcb->ssl); if (rc == -1) @@ -1096,9 +1096,9 @@ int dcb_read_SSL( if(ssl_errno != SSL_ERROR_WANT_READ && ssl_errno != SSL_ERROR_WANT_WRITE && ssl_errno != SSL_ERROR_NONE) - { n = -1; - } + else + n = 0; goto return_n; } } @@ -1192,7 +1192,7 @@ int dcb_read_SSL( } } } - + n = -1; gwbuf_free(buffer); goto return_n; } @@ -1595,7 +1595,7 @@ dcb_write_SSL(DCB *dcb, GWBUF *queue) if (w < 0) { - int ssl_errno = ERR_get_error(); + int ssl_errno = SSL_get_error(dcb->ssl,w); if (LOG_IS_ENABLED(LOGFILE_DEBUG)) { @@ -1633,6 +1633,17 @@ dcb_write_SSL(DCB *dcb, GWBUF *queue) dcb, STRDCBSTATE(dcb->state), 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; LOGIF(LD,(skygw_log_write_flush(LD,"[dcb_accept_SSL] SSL_accept done for %s", dcb->remote))); - break; + return rval; case -1: @@ -3035,10 +3046,10 @@ int dcb_accept_SSL(DCB* dcb) { rval = -1; 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, - errnum, - strerror(errno)); + SSL_get_version(dcb->ssl), + errnum); if(errnum == SSL_ERROR_SSL || errnum == SSL_ERROR_SYSCALL) { @@ -3104,8 +3115,7 @@ int dcb_connect_SSL(DCB* dcb) case -1: errnum = SSL_get_error(dcb->ssl,rval); - if(errnum == SSL_ERROR_WANT_READ || errnum == SSL_ERROR_WANT_WRITE || - errnum == SSL_ERROR_WANT_X509_LOOKUP) + if(errnum == SSL_ERROR_WANT_READ || errnum == SSL_ERROR_WANT_WRITE) { /** Not all of the data has been read. Go back to the poll queue and wait for more.*/ diff --git a/server/core/gateway.c b/server/core/gateway.c index 794ed5304..1805e483d 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -40,7 +40,16 @@ * @endverbatim */ #define _XOPEN_SOURCE 700 +#define OPENSSL_THREAD_DEFINES #include + + #include + #if defined(OPENSSL_THREADS) +#define HAVE_OPENSSL_THREADS 1 + #else +#define HAVE_OPENSSL_THREADS 0 + #endif + #include #include #include @@ -196,9 +205,46 @@ static bool resolve_maxscale_conf_fname( static char* check_dir_access(char* dirname,bool,bool); static int set_user(); -static void maxscale_ssl_lock(int mode,int n,const char* file, int line); -static unsigned long maxscale_ssl_id(); -static SPINLOCK* ssl_locks; + +/** SSL multi-threading functions and structures */ + +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 * gateway. @@ -1374,23 +1420,21 @@ int main(int argc, char **argv) } /** OpenSSL initialization */ - - 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) + if(!HAVE_OPENSSL_THREADS) { + char* logerr = "OpenSSL library does not support multi-threading"; + print_log_n_stderr(true, true, logerr, logerr, eno); rc = MAXSCALE_INTERNALERROR; 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