MXS-3055: Prevent sending of an extra COM_QUIT

If the protocol routes a COM_QUIT packet to the backend, it must not
generate a packet when it is shutting down. This could cause unexpected
write errors if the backend server managed to close the socket before the
write was done.
This commit is contained in:
Markus Mäkelä
2020-07-02 08:11:16 +03:00
parent a655c5d08c
commit 608eb95284
3 changed files with 13 additions and 2 deletions

View File

@ -340,6 +340,7 @@ typedef struct
bool collect_result; /*< Collect the next result set as one buffer */ bool collect_result; /*< Collect the next result set as one buffer */
bool changing_user; bool changing_user;
bool track_state; /*< Track session state */ bool track_state; /*< Track session state */
bool send_com_quit;
uint32_t num_eof_packets; /*< Encountered eof packet number, used for check uint32_t num_eof_packets; /*< Encountered eof packet number, used for check
* packet type */ * packet type */
bool large_query; /*< Whether to ignore the command byte of the next bool large_query; /*< Whether to ignore the command byte of the next

View File

@ -1286,6 +1286,12 @@ static int gw_MySQLWrite_backend(DCB* dcb, GWBUF* queue)
} }
else else
{ {
if (cmd == MXS_COM_QUIT)
{
backend_protocol->send_com_quit = false;
}
if (GWBUF_IS_IGNORABLE(queue)) if (GWBUF_IS_IGNORABLE(queue))
{ {
/** The response to this command should be ignored */ /** The response to this command should be ignored */
@ -1398,8 +1404,11 @@ static int gw_backend_close(DCB* dcb)
mxb_assert(dcb->session || dcb->persistentstart); mxb_assert(dcb->session || dcb->persistentstart);
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol; MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
/** Send COM_QUIT to the backend being closed */ if (proto->send_com_quit && proto->protocol_auth_state == MXS_AUTH_STATE_COMPLETE)
dcb_write(dcb, mysql_create_com_quit(NULL, 0)); {
// Send a COM_QUIT to the backend being closed, we haven't routed one to it yet.
dcb_write(dcb, mysql_create_com_quit(NULL, 0));
}
/** Free protocol data */ /** Free protocol data */
mysql_protocol_done(dcb); mysql_protocol_done(dcb);

View File

@ -64,6 +64,7 @@ MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd)
p->num_eof_packets = 0; p->num_eof_packets = 0;
p->large_query = false; p->large_query = false;
p->track_state = false; p->track_state = false;
p->send_com_quit = true;
/*< Assign fd with protocol */ /*< Assign fd with protocol */
p->fd = fd; p->fd = fd;
p->owner_dcb = dcb; p->owner_dcb = dcb;