Fixed queries getting stuck when the SSL records were of the maximum allowed size.

This commit is contained in:
Markus Makela
2015-06-05 11:00:51 +03:00
parent cc1f720ea3
commit e83799648a
3 changed files with 48 additions and 40 deletions

View File

@ -898,7 +898,7 @@ int dcb_read_SSL(
GWBUF **head) GWBUF **head)
{ {
GWBUF *buffer = NULL; GWBUF *buffer = NULL;
int b; int b,pending;
int rc; int rc;
int n; int n;
int nread = 0; int nread = 0;
@ -918,9 +918,9 @@ int dcb_read_SSL(
while (true) while (true)
{ {
int bufsize; int bufsize;
int ssl_errno = 0;
rc = ioctl(dcb->fd, FIONREAD, &b); rc = ioctl(dcb->fd, FIONREAD, &b);
pending = SSL_pending(dcb->ssl);
if (rc == -1) if (rc == -1)
{ {
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
@ -936,7 +936,7 @@ int dcb_read_SSL(
goto return_n; goto return_n;
} }
if (b == 0 && nread == 0) if (b == 0 && pending == 0 && nread == 0)
{ {
/** Handle closed client socket */ /** Handle closed client socket */
if (dcb_isclient(dcb)) if (dcb_isclient(dcb))
@ -947,15 +947,21 @@ int dcb_read_SSL(
/* try to read 1 byte, without consuming the socket buffer */ /* try to read 1 byte, without consuming the socket buffer */
r = SSL_peek(dcb->ssl, &c, sizeof(char)); r = SSL_peek(dcb->ssl, &c, sizeof(char));
if (r <= 0) if (r <= 0)
{
ssl_errno = SSL_get_error(dcb->ssl,r);
if(ssl_errno != SSL_ERROR_WANT_READ &&
ssl_errno != SSL_ERROR_WANT_WRITE &&
ssl_errno != SSL_ERROR_NONE)
{ {
n = -1; n = -1;
}
goto return_n; goto return_n;
} }
} }
n = 0; n = 0;
goto return_n; goto return_n;
} }
else if (b == 0) else if (b == 0 && pending == 0)
{ {
n = 0; n = 0;
goto return_n; goto return_n;
@ -984,39 +990,36 @@ int dcb_read_SSL(
goto return_n; goto return_n;
} }
int npending; n = SSL_read(dcb->ssl, GWBUF_DATA(buffer), bufsize);
n = 0;
do
{
n += SSL_read(dcb->ssl, GWBUF_DATA(buffer), bufsize);
dcb->stats.n_reads++; dcb->stats.n_reads++;
}while((npending = SSL_pending(dcb->ssl)) > 0);
int ssl_errno = 0;
if (n <= 0) if (n <= 0)
{ {
ssl_errno = ERR_get_error(); ssl_errno = SSL_get_error(dcb->ssl,n);
if(ssl_errno != SSL_ERROR_WANT_READ && ssl_errno != SSL_ERROR_NONE) if(ssl_errno != SSL_ERROR_WANT_READ &&
ssl_errno != SSL_ERROR_WANT_WRITE &&
ssl_errno != SSL_ERROR_NONE)
{ {
char errbuf[200];
ERR_error_string(ssl_errno,errbuf);
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : Read failed, dcb %p in state " "Error : Read failed, dcb %p in state "
"%s fd %d: %s.", "%s fd %d, SSL error %d: %s.",
dcb, dcb,
STRDCBSTATE(dcb->state), STRDCBSTATE(dcb->state),
dcb->fd, dcb->fd,
ERR_error_string(ssl_errno,NULL)))); ssl_errno,
errbuf)));
gwbuf_free(buffer); gwbuf_free(buffer);
goto return_n; goto return_n;
} }
} }
if(n > 0 && b > 0 && n < b) buffer->end = buffer->start + n;
{ #ifdef SS_DEBUG
gwbuf_rtrim(buffer,b - n);
LOGIF(LD,(skygw_log_write(LD,"[%lu] SSL: Truncated buffer to correct size from %d to %d bytes.\n", LOGIF(LD,(skygw_log_write(LD,"[%lu] SSL: Truncated buffer to correct size from %d to %d bytes.\n",
b,gwbuf_length(buffer)))); b,gwbuf_length(buffer))));
LOGIF(LD, LOGIF(LD,
@ -1025,9 +1028,7 @@ int dcb_read_SSL(
} }
); );
ss_dassert(GWBUF_LENGTH(buffer) == n); ss_dassert(GWBUF_LENGTH(buffer) == n);
#endif
}
nread += n; nread += n;
LOGIF(LD, (skygw_log_write( LOGIF(LD, (skygw_log_write(
@ -1039,11 +1040,19 @@ int dcb_read_SSL(
dcb, dcb,
STRDCBSTATE(dcb->state), STRDCBSTATE(dcb->state),
dcb->fd))); dcb->fd)));
/*< Append read data to the gwbuf */ /*< Append read data to the gwbuf */
*head = gwbuf_append(*head, buffer); *head = gwbuf_append(*head, buffer);
if(ssl_errno == SSL_ERROR_WANT_READ || ssl_errno == SSL_ERROR_NONE || rc = ioctl(dcb->fd, FIONREAD, &b);
ssl_errno == SSL_ERROR_WANT_X509_LOOKUP || SSL_ERROR_WANT_WRITE) pending = SSL_pending(dcb->ssl);
if(ssl_errno == SSL_ERROR_WANT_READ ||
ssl_errno == SSL_ERROR_WANT_WRITE ||
(b == 0 && pending == 0))
{
break; break;
}
} /*< while (true) */ } /*< while (true) */
return_n: return_n:
return n; return n;

View File

@ -1875,7 +1875,6 @@ int serviceInitSSL(SERVICE* service)
} }
service->ctx = SSL_CTX_new(service->method); service->ctx = SSL_CTX_new(service->method);
SSL_CTX_set_read_ahead(service->ctx,1);
if (SSL_CTX_use_certificate_file(service->ctx, service->ssl_cert, SSL_FILETYPE_PEM) <= 0) { if (SSL_CTX_use_certificate_file(service->ctx, service->ssl_cert, SSL_FILETYPE_PEM) <= 0) {
skygw_log_write(LE,"Error: Failed to set server SSL certificate."); skygw_log_write(LE,"Error: Failed to set server SSL certificate.");
return -1; return -1;

View File

@ -789,7 +789,7 @@ int gw_read_client_event(
nbytes_read = gwbuf_length(dcb->dcb_readqueue); nbytes_read = gwbuf_length(dcb->dcb_readqueue);
data = (uint8_t *)GWBUF_DATA(dcb->dcb_readqueue); data = (uint8_t *)GWBUF_DATA(dcb->dcb_readqueue);
int plen = MYSQL_GET_PACKET_LEN(data); int plen = MYSQL_GET_PACKET_LEN(data);
if (nbytes_read < 3 || nbytes_read < MYSQL_GET_PACKET_LEN(data)) if (nbytes_read < 3 || nbytes_read < MYSQL_GET_PACKET_LEN(data) + 4)
{ {
rc = 0; rc = 0;
goto return_rc; goto return_rc;