MXS-1931: Remove use of gw_MySQL_get_next_packet

The function implemented redundant functionality and replacement with
modutil_get_next_MySQL_packet was planned.

When faced with a packet header spread over multiple buffers, the packet
length calculation would read past the buffer end. This is fixed by taking
modutil_get_next_MySQL_packet into use.

Identical behavior to the old function is achieved by calling
gwbuf_make_contiguous for each packet to store them in a contiguous area
of memory. This should be either removed and only done when
RCAP_TYPE_CONTIGUOUS_INPUT is requested or be made an innate feature of
statement based routing.
This commit is contained in:
Markus Mäkelä
2018-06-18 20:42:23 +03:00
parent 45f39e7fdd
commit 8eaa265168
3 changed files with 18 additions and 120 deletions

View File

@ -1576,6 +1576,17 @@ static bool reauthenticate_client(MXS_SESSION* session, GWBUF* packetbuf)
return rval;
}
// Helper function for debug assertions
static bool only_one_packet(GWBUF* buffer)
{
ss_dassert(buffer);
uint8_t header[4] = {};
gwbuf_copy_data(buffer, 0, MYSQL_HEADER_LEN, header);
size_t packet_len = gw_mysql_get_byte3(header);
size_t buffer_len = gwbuf_length(buffer);
return packet_len + MYSQL_HEADER_LEN == buffer_len;
}
/**
* Detect if buffer includes partial mysql packet or multiple packets.
* Store partial packet to dcb_readqueue. Send complete packets one by one
@ -1597,15 +1608,15 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
GWBUF* packetbuf;
do
{
/**
* Collect incoming bytes to a buffer until complete packet has
* arrived and then return the buffer.
*/
// TODO: This should be replaced with modutil_get_next_MySQL_packet.
packetbuf = gw_MySQL_get_next_packet(p_readbuf);
// Process client request one packet at a time
packetbuf = modutil_get_next_MySQL_packet(p_readbuf);
// TODO: Do this only when RCAP_TYPE_CONTIGUOUS_INPUT is requested
packetbuf = gwbuf_make_contiguous(packetbuf);
if (packetbuf != NULL)
{
ss_dassert(only_one_packet(packetbuf));
CHK_GWBUF(packetbuf);
MySQLProtocol* proto = (MySQLProtocol*)session->client_dcb->protocol;
@ -1619,24 +1630,7 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
if (rcap_type_required(capabilities, RCAP_TYPE_CONTIGUOUS_INPUT))
{
if (!GWBUF_IS_CONTIGUOUS(packetbuf))
{
// TODO: As long as gw_MySQL_get_next_packet is used above, the buffer
// TODO: will be contiguous. That function should be replaced with
// TODO: modutil_get_next_MySQL_packet.
GWBUF* tmp = gwbuf_make_contiguous(packetbuf);
if (tmp)
{
packetbuf = tmp;
}
else
{
// TODO: A memory allocation failure. We should close the dcb
// TODO: and terminate the session.
rc = 0;
goto return_rc;
}
}
ss_dassert(GWBUF_IS_CONTIGUOUS(packetbuf));
if (rcap_type_required(capabilities, RCAP_TYPE_TRANSACTION_TRACKING))
{