MaxRows: EOF/OK is not checked while receiving a large packet

EOF / OK packet is not being checked while receiving a large packet.
If so no extra data inspection will be done.
This commit is contained in:
MassimilianoPinto
2016-12-22 12:14:03 +01:00
parent c7dfd1b0bd
commit cb73263b93

View File

@ -674,26 +674,55 @@ static int handle_rows(MAXROWS_SESSION_DATA *csdata)
int rv = 1; int rv = 1;
bool insufficient = false; bool insufficient = false;
size_t buflen = gwbuf_length(csdata->res.data); size_t buflen = gwbuf_length(csdata->res.data);
// reset large packet indicator
csdata->large_packet = false;
while (!insufficient && (buflen - csdata->res.offset >= MYSQL_HEADER_LEN)) while (!insufficient && (buflen - csdata->res.offset >= MYSQL_HEADER_LEN))
{ {
bool pending_large_data = csdata->large_packet;
// header array holds a full EOF packet // header array holds a full EOF packet
uint8_t header[MAXROWS_EOF_PACKET_LEN]; uint8_t header[MAXROWS_EOF_PACKET_LEN];
gwbuf_copy_data(csdata->res.data, csdata->res.offset, MAXROWS_EOF_PACKET_LEN, header); gwbuf_copy_data(csdata->res.data, csdata->res.offset, MAXROWS_EOF_PACKET_LEN, header);
size_t packetlen = MYSQL_HEADER_LEN + MYSQL_GET_PACKET_LEN(header); size_t packetlen = MYSQL_HEADER_LEN + MYSQL_GET_PACKET_LEN(header);
// Mark the beginning of a large packet
if (packetlen >= MYSQL_PACKET_LENGTH_MAX)
{
csdata->large_packet = true;
}
if (csdata->res.offset + packetlen <= buflen) if (csdata->res.offset + packetlen <= buflen)
{ {
// We have at least one complete packet. /* Check for large packet packet terminator:
* min is 4 bytes "0x0 0x0 0x0 0xseq_no and
* max is 1 byte less than EOF_PACKET_LEN
* If true skip data processing.
*/
if (pending_large_data && (packetlen >= MYSQL_HEADER_LEN && packetlen < MAXROWS_EOF_PACKET_LEN))
{
// Update offset, number of rows and break
csdata->res.offset += packetlen;
csdata->res.n_rows++;
ss_dassert(csdata->res.offset == buflen);
break;
}
/*
* Check packet size against MYSQL_PACKET_LENGTH_MAX
* If true then break as received could be not complete
* EOF or OK packet could be seen after receiving the full large packet
*/
if (packetlen == (MYSQL_PACKET_LENGTH_MAX + MYSQL_HEADER_LEN))
{
// Mark the beginning of a large packet receiving
csdata->large_packet = true;
// Just update offset and break
csdata->res.offset += packetlen;
ss_dassert(csdata->res.offset == buflen);
break;
}
else
{
// Reset large packet indicator
csdata->large_packet = false;
}
// We have at least one complete packet and we can process the command byte.
int command = (int)MYSQL_GET_COMMAND(header); int command = (int)MYSQL_GET_COMMAND(header);
switch (command) switch (command)
@ -709,6 +738,7 @@ static int handle_rows(MAXROWS_SESSION_DATA *csdata)
{ {
MXS_NOTICE("Error packet seen while handling result set"); MXS_NOTICE("Error packet seen while handling result set");
} }
/* /*
* This is the ERR packet that could terminate a Multi-Resultset. * This is the ERR packet that could terminate a Multi-Resultset.
*/ */
@ -759,12 +789,6 @@ static int handle_rows(MAXROWS_SESSION_DATA *csdata)
if (!(flags & SERVER_MORE_RESULTS_EXIST)) if (!(flags & SERVER_MORE_RESULTS_EXIST))
{ {
// End of the resultset // End of the resultset
if (csdata->large_packet)
{
// Reset large packet indicator
csdata->large_packet = false;
}
if (csdata->instance->config.debug & MAXROWS_DEBUG_DECISIONS) if (csdata->instance->config.debug & MAXROWS_DEBUG_DECISIONS)
{ {
MXS_NOTICE("OK or EOF packet seen: the resultset has %lu rows.%s", MXS_NOTICE("OK or EOF packet seen: the resultset has %lu rows.%s",
@ -795,14 +819,6 @@ static int handle_rows(MAXROWS_SESSION_DATA *csdata)
csdata->state = MAXROWS_EXPECTING_RESPONSE; csdata->state = MAXROWS_EXPECTING_RESPONSE;
// Increase res.n_rows counter at the beginning of a large packet
if (csdata->large_packet)
{
// Turn off large packet indicator
csdata->large_packet = false;
csdata->res.n_rows++;
}
if (csdata->instance->config.debug & MAXROWS_DEBUG_DECISIONS) if (csdata->instance->config.debug & MAXROWS_DEBUG_DECISIONS)
{ {
MXS_NOTICE("EOF or OK packet seen with SERVER_MORE_RESULTS_EXIST flag:" MXS_NOTICE("EOF or OK packet seen with SERVER_MORE_RESULTS_EXIST flag:"