check protocol state to determine real ok packet
This commit is contained in:
@ -8,7 +8,6 @@
|
||||
set(MARIADB_CONNECTOR_C_REPO "https://github.com/MariaDB/mariadb-connector-c.git"
|
||||
CACHE STRING "MariaDB Connector-C Git repository")
|
||||
|
||||
|
||||
# Connector-C tag to use
|
||||
set(MARIADB_CONNECTOR_C_TAG "v3.0.3"
|
||||
CACHE STRING "MariaDB Connector-C Git tag")
|
||||
|
@ -353,6 +353,7 @@ typedef struct
|
||||
int ignore_replies; /*< How many replies should be discarded */
|
||||
GWBUF* stored_query; /*< Temporarily stored queries */
|
||||
bool collect_result; /*< Collect the next result set as one buffer */
|
||||
int num_eof_packets; /*< Signal number to indicate is current packet is ok packet*/
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t protocol_chk_tail;
|
||||
#endif
|
||||
@ -492,7 +493,7 @@ char* create_auth_fail_str(char *username, char *hostaddr, bool password, char *
|
||||
void init_response_status(GWBUF* buf, uint8_t cmd, int* npackets, size_t* nbytes);
|
||||
bool read_complete_packet(DCB *dcb, GWBUF **readbuf);
|
||||
bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session);
|
||||
void mxs_mysql_get_session_track_info(GWBUF *buff, uint32_t server_capabilities);
|
||||
void mxs_mysql_get_session_track_info(GWBUF *buff, MySQLProtocol *proto);
|
||||
mysql_tx_state_t parse_trx_state(const char *str);
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <maxscale/buffer.h>
|
||||
#include <maxscale/protocol/mysql.h>
|
||||
|
||||
MySQLProtocol proto;
|
||||
|
||||
static const uint8_t resultset1[] =
|
||||
{
|
||||
/* BEGIN;*/
|
||||
@ -117,52 +119,98 @@ static const uint8_t resultset2[] =
|
||||
0xFE, 0x00, 0x00, 0x21, 0x40
|
||||
};
|
||||
|
||||
/**
|
||||
* SET AUTOCOMMIT=0;
|
||||
* CREATE TABLE t1(a VARCHAR(20), b INT, c INT, d INT);
|
||||
* INSERT INTO t1 VALUES ('', 100, 200, 300);
|
||||
* SELECT * FROM t1;
|
||||
**/
|
||||
static const uint8_t resultset3[] =
|
||||
{
|
||||
0x28, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0x40, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x0F, 0x0A,
|
||||
0x61, 0x75, 0x74, 0x6F, 0x63, 0x6F, 0x6D, 0x6D,
|
||||
0x69, 0x74, 0x03, 0x4F, 0x46, 0x46, 0x02, 0x01,
|
||||
0x31, 0x05, 0x09, 0x08, 0x49, 0x5F, 0x52, 0x5F,
|
||||
0x5F, 0x5F, 0x53, 0x5F, 0x1D, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x0F, 0x0A, 0x61, 0x75, 0x74, 0x6F,
|
||||
0x63, 0x6F, 0x6D, 0x6D, 0x69, 0x74, 0x03, 0x4F,
|
||||
0x46, 0x46, 0x02, 0x01, 0x31, 0x07, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
|
||||
0x40, 0x00, 0x00, 0x00, 0x0B, 0x05, 0x09, 0x08,
|
||||
0x49, 0x5F, 0x5F, 0x5F, 0x57, 0x5F, 0x5F, 0x5F,
|
||||
0x01, 0x00, 0x00, 0x01, 0x04, 0x20, 0x00, 0x00,
|
||||
0x02, 0x03, 0x64, 0x65, 0x66, 0x04, 0x74, 0x65,
|
||||
0x73, 0x74, 0x02, 0x74, 0x31, 0x02, 0x74, 0x31,
|
||||
0x01, 0x61, 0x01, 0x61, 0x0C, 0x21, 0x00, 0x3C,
|
||||
0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x20, 0x00, 0x00, 0x03, 0x03, 0x64, 0x65,
|
||||
0x66, 0x04, 0x74, 0x65, 0x73, 0x74, 0x02, 0x74,
|
||||
0x31, 0x02, 0x74, 0x31, 0x01, 0x62, 0x01, 0x62,
|
||||
0x0C, 0x3F, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||
0x04, 0x03, 0x64, 0x65, 0x66, 0x04, 0x74, 0x65,
|
||||
0x73, 0x74, 0x02, 0x74, 0x31, 0x02, 0x74, 0x31,
|
||||
0x01, 0x63, 0x01, 0x63, 0x0C, 0x3F, 0x00, 0x0B,
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x20, 0x00, 0x00, 0x05, 0x03, 0x64, 0x65,
|
||||
0x66, 0x04, 0x74, 0x65, 0x73, 0x74, 0x02, 0x74,
|
||||
0x31, 0x02, 0x74, 0x31, 0x01, 0x64, 0x01, 0x64,
|
||||
0x0C, 0x3F, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
|
||||
0x06, 0xFE, 0x00, 0x00, 0x21, 0x00, 0x05, 0x00,
|
||||
0x00, 0x07, 0xFE, 0x00, 0x00, 0x21, 0x00
|
||||
};
|
||||
|
||||
/* functional test , test packet by packet */
|
||||
void test1()
|
||||
{
|
||||
GWBUF *buffer;
|
||||
uint32_t server_capabilities = GW_MYSQL_CAPABILITIES_SESSION_TRACK;
|
||||
proto.server_capabilities = GW_MYSQL_CAPABILITIES_SESSION_TRACK;
|
||||
proto.num_eof_packets = 0;
|
||||
ss_dfprintf(stderr,"test_session_track : Functional tests.\n");
|
||||
//BEGIN
|
||||
buffer = gwbuf_alloc_and_load(PACKET_1_LEN, resultset1+PACKET_1_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_state"), "T_______", 8) == 0);
|
||||
gwbuf_free(buffer);
|
||||
//COMMIT
|
||||
buffer = gwbuf_alloc_and_load(PACKET_2_LEN, resultset1+PACKET_2_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_state"), "________", 8) == 0);
|
||||
gwbuf_free(buffer);
|
||||
//START TRANSACTION
|
||||
buffer = gwbuf_alloc_and_load(PACKET_3_LEN, resultset1+PACKET_3_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_state"), "T_______", 8) == 0);
|
||||
gwbuf_free(buffer);
|
||||
//START TRANSACTION READ ONLY
|
||||
buffer = gwbuf_alloc_and_load(PACKET_4_LEN, resultset1+PACKET_4_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_characteristics"),
|
||||
"START TRANSACTION READ ONLY;", 28) == 0);
|
||||
gwbuf_free(buffer);
|
||||
//COMMIT
|
||||
buffer = gwbuf_alloc_and_load(PACKET_5_LEN, resultset1+PACKET_5_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(gwbuf_get_property(buffer, (char *)"trx_characteristics") == NULL);
|
||||
ss_dassert(gwbuf_get_property(buffer, (char *)"trx_state") == NULL);
|
||||
gwbuf_free(buffer);
|
||||
//SET AUTOCOMMIT=0;
|
||||
buffer = gwbuf_alloc_and_load(PACKET_6_LEN, resultset1+PACKET_6_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"autocommit"), "OFF", 3) == 0);
|
||||
gwbuf_free(buffer);
|
||||
//INSERT INTO t1 VALUES(1);
|
||||
buffer = gwbuf_alloc_and_load(PACKET_7_LEN, resultset1+PACKET_7_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_state"), "I___W___", 8) == 0);
|
||||
gwbuf_free(buffer);
|
||||
//COMMIT
|
||||
buffer = gwbuf_alloc_and_load(PACKET_8_LEN, resultset1+PACKET_8_IDX);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_state"), "________", 8) == 0);
|
||||
gwbuf_free(buffer);
|
||||
}
|
||||
@ -171,10 +219,23 @@ void test1()
|
||||
void test2()
|
||||
{
|
||||
GWBUF *buffer;
|
||||
uint32_t server_capabilities = GW_MYSQL_CAPABILITIES_SESSION_TRACK;
|
||||
ss_dfprintf(stderr, "test_session_track: multi results test\n");
|
||||
proto.server_capabilities = GW_MYSQL_CAPABILITIES_SESSION_TRACK;
|
||||
proto.num_eof_packets = 0;
|
||||
buffer = gwbuf_alloc_and_load(sizeof(resultset2), resultset2);
|
||||
mxs_mysql_get_session_track_info(buffer, server_capabilities);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_state"), "I_R_W___", 8) == 0);
|
||||
gwbuf_free(buffer);
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
GWBUF *buffer;
|
||||
proto.server_capabilities = GW_MYSQL_CAPABILITIES_SESSION_TRACK;
|
||||
proto.num_eof_packets = 0;
|
||||
ss_dfprintf(stderr, "test_session_track: protocol state test\n");
|
||||
buffer = gwbuf_alloc_and_load(sizeof(resultset2), resultset2);
|
||||
mxs_mysql_get_session_track_info(buffer, &proto);
|
||||
ss_dassert(strncmp(gwbuf_get_property(buffer, (char *)"trx_state"), "I_R_W___", 8) == 0);
|
||||
gwbuf_free(buffer);
|
||||
}
|
||||
@ -183,5 +244,6 @@ int main(int argc, char **argv)
|
||||
{
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
return 0;
|
||||
}
|
@ -771,7 +771,7 @@ gw_read_and_write(DCB *dcb)
|
||||
}
|
||||
|
||||
/** Get sesion track info from ok packet and save it to gwbuf properties */
|
||||
mxs_mysql_get_session_track_info(tmp, proto->server_capabilities);
|
||||
mxs_mysql_get_session_track_info(tmp, proto);
|
||||
|
||||
read_buffer = tmp;
|
||||
|
||||
|
@ -71,6 +71,7 @@ MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd)
|
||||
p->extra_capabilities = 0;
|
||||
p->ignore_replies = 0;
|
||||
p->collect_result = false;
|
||||
p->num_eof_packets = 0;
|
||||
#if defined(SS_DEBUG)
|
||||
p->protocol_chk_top = CHK_NUM_PROTOCOL;
|
||||
p->protocol_chk_tail = CHK_NUM_PROTOCOL;
|
||||
@ -1774,10 +1775,7 @@ void mxs_mysql_execute_kill_user(MXS_SESSION* issuer, const char* user, kill_typ
|
||||
* @param packet_offset Ok packet offset in this buff
|
||||
* @param packet_len Ok packet lengh
|
||||
*/
|
||||
void mxs_mysql_parse_ok_packet(GWBUF *buff,
|
||||
size_t packet_offset,
|
||||
size_t packet_len,
|
||||
uint32_t server_capabilities)
|
||||
void mxs_mysql_parse_ok_packet(GWBUF *buff, size_t packet_offset, size_t packet_len)
|
||||
{
|
||||
uint8_t local_buf[packet_len];
|
||||
uint8_t *ptr = local_buf;
|
||||
@ -1791,8 +1789,6 @@ void mxs_mysql_parse_ok_packet(GWBUF *buff,
|
||||
ptr += 2; // status
|
||||
ptr += 2; // number of warnings
|
||||
|
||||
if (server_capabilities & GW_MYSQL_CAPABILITIES_SESSION_TRACK)
|
||||
{
|
||||
if (ptr < (local_buf + packet_len))
|
||||
{
|
||||
ptr += mxs_leint_consume(&ptr); // info
|
||||
@ -1845,28 +1841,45 @@ void mxs_mysql_parse_ok_packet(GWBUF *buff,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check every packet type, if is ok packet then parse it
|
||||
* @param buff Buffer contain multi compelte packets
|
||||
* @param server_capabilities Server capabilities
|
||||
*/
|
||||
void mxs_mysql_get_session_track_info(GWBUF *buff, uint32_t server_capabilities)
|
||||
void mxs_mysql_get_session_track_info(GWBUF *buff, MySQLProtocol *proto)
|
||||
{
|
||||
size_t offset = 0;
|
||||
uint8_t header_and_command[MYSQL_HEADER_LEN+1];
|
||||
|
||||
if (proto->server_capabilities & GW_MYSQL_CAPABILITIES_SESSION_TRACK)
|
||||
{
|
||||
while (gwbuf_copy_data(buff, offset, MYSQL_HEADER_LEN+1, header_and_command) == (MYSQL_HEADER_LEN+1))
|
||||
{
|
||||
size_t packet_len = gw_mysql_get_byte3(header_and_command) + MYSQL_HEADER_LEN;
|
||||
uint8_t cmd = header_and_command[MYSQL_COM_OFFSET];
|
||||
if (packet_len > MYSQL_OK_PACKET_MIN_LEN && cmd == MYSQL_REPLY_OK)
|
||||
if (packet_len > MYSQL_OK_PACKET_MIN_LEN && cmd == MYSQL_REPLY_OK && proto->num_eof_packets == 0)
|
||||
{
|
||||
buff->gwbuf_type |= GWBUF_TYPE_REPLY_OK;
|
||||
mxs_mysql_parse_ok_packet(buff, offset, packet_len, server_capabilities);
|
||||
mxs_mysql_parse_ok_packet(buff, offset, packet_len);
|
||||
}
|
||||
offset += packet_len;
|
||||
|
||||
/* first packet of result set */
|
||||
if ((proto->current_command == MXS_COM_QUERY ||
|
||||
proto->current_command == MXS_COM_STMT_FETCH ||
|
||||
proto->current_command == MXS_COM_STMT_EXECUTE) &&
|
||||
proto->num_eof_packets == 0 &&
|
||||
cmd > MYSQL_REPLY_OK &&
|
||||
cmd < MYSQL_REPLY_LOCAL_INFILE)
|
||||
{
|
||||
proto->num_eof_packets = 2;
|
||||
}
|
||||
|
||||
if (cmd == MYSQL_REPLY_EOF && proto->num_eof_packets > 0)
|
||||
{
|
||||
proto->num_eof_packets--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user