Partial fix to #463, http://bugs.skysql.com/show_bug.cgi?id=463
log_manager.cc: fixed block buffer overflow. Queries are logged to trace log and long queries exceed the bufsize in length. Those were written beyond allocated memory areas. mysql_client_server_protocol.h: added mysql_protocol_state_t to indicate whether MySQL protocol object is allocated, usable or freed. Freed means that memory allocations made by the protocol are freed. That is, command history etc. mysql_backend.c: gw_backend_hangup and gw_error_backend_event used to call error handling function although session was already closing. Added check for session state. mysql_client.c: route_by_statement lost some packets in case where query was sent in multiple packets. mysql_common.c: gw_MySQL_get_next_packet failed in packet handling with route_by_statement. When multi-packet query was merged into one, packet type wasn't copied. protocol_archive_srv_command and mysql_protocol_done didn't have proper locking in place which lead to occasional crashes.
This commit is contained in:
@ -65,7 +65,7 @@ static int gw_client_hangup_event(DCB *dcb);
|
||||
int mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mysql_message);
|
||||
int MySQLSendHandshake(DCB* dcb);
|
||||
static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue);
|
||||
static int route_by_statement(SESSION *, GWBUF *);
|
||||
static int route_by_statement(SESSION *, GWBUF **);
|
||||
|
||||
/*
|
||||
* The "module object" for the mysqld client protocol module.
|
||||
@ -534,7 +534,7 @@ int gw_read_client_event(
|
||||
if (nbytes_read == 0)
|
||||
{
|
||||
goto return_rc;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* if read queue existed appent read to it.
|
||||
* if length of read buffer is less than 3 or less than mysql packet
|
||||
@ -783,7 +783,7 @@ int gw_read_client_event(
|
||||
* Feed each statement completely and separately
|
||||
* to router.
|
||||
*/
|
||||
rc = route_by_statement(session, read_buffer);
|
||||
rc = route_by_statement(session, &read_buffer);
|
||||
|
||||
if (read_buffer != NULL)
|
||||
{
|
||||
@ -1383,7 +1383,7 @@ gw_client_hangup_event(DCB *dcb)
|
||||
#if defined(SS_DEBUG)
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Client hangup error handling.")));
|
||||
"Client hangup error handling.")));
|
||||
#endif
|
||||
dcb_close(dcb);
|
||||
return 1;
|
||||
@ -1399,7 +1399,9 @@ gw_client_hangup_event(DCB *dcb)
|
||||
* Return 1 in success. If the last packet is incomplete return success but
|
||||
* leave incomplete packet to readbuf.
|
||||
*/
|
||||
static int route_by_statement(SESSION *session, GWBUF *readbuf)
|
||||
static int route_by_statement(
|
||||
SESSION* session,
|
||||
GWBUF** p_readbuf)
|
||||
{
|
||||
int rc = -1;
|
||||
GWBUF* packetbuf;
|
||||
@ -1407,7 +1409,7 @@ static int route_by_statement(SESSION *session, GWBUF *readbuf)
|
||||
gwbuf_type_t prevtype;
|
||||
GWBUF* tmpbuf;
|
||||
|
||||
tmpbuf = readbuf;
|
||||
tmpbuf = *p_readbuf;
|
||||
while (tmpbuf != NULL)
|
||||
{
|
||||
ss_dassert(GWBUF_IS_TYPE_MYSQL(tmpbuf));
|
||||
@ -1416,9 +1418,9 @@ static int route_by_statement(SESSION *session, GWBUF *readbuf)
|
||||
#endif
|
||||
do
|
||||
{
|
||||
ss_dassert(GWBUF_IS_TYPE_MYSQL(readbuf));
|
||||
ss_dassert(GWBUF_IS_TYPE_MYSQL((*p_readbuf)));
|
||||
|
||||
packetbuf = gw_MySQL_get_next_packet(&readbuf);
|
||||
packetbuf = gw_MySQL_get_next_packet(p_readbuf);
|
||||
|
||||
ss_dassert(GWBUF_IS_TYPE_MYSQL(packetbuf));
|
||||
|
||||
@ -1447,7 +1449,7 @@ static int route_by_statement(SESSION *session, GWBUF *readbuf)
|
||||
goto return_rc;
|
||||
}
|
||||
}
|
||||
while (readbuf != NULL);
|
||||
while (*p_readbuf != NULL);
|
||||
|
||||
return_rc:
|
||||
return rc;
|
||||
|
Reference in New Issue
Block a user