Fixed successful SSL_accept calls causing another call to SSL_accept.

This commit is contained in:
Markus Makela
2015-06-11 12:00:03 +03:00
parent 03470bcd70
commit bb427128a9
2 changed files with 81 additions and 43 deletions

View File

@ -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.*/

View File

@ -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();
}