diff --git a/server/core/buffer.c b/server/core/buffer.c index 991e78b1b..6f9a162be 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -201,6 +201,36 @@ GWBUF *rval; return rval; } +/** + * Clone whole GWBUF list instead of single buffer. + * + * @param buf head of the list to be cloned till the tail of it + * + * @return head of the cloned list or NULL if the list was empty. + */ +GWBUF* gwbuf_clone_all( + GWBUF* buf) +{ + GWBUF* rval; + GWBUF* clonebuf; + + if (buf == NULL) + { + return NULL; + } + /** Store the head of the list to rval. */ + clonebuf = gwbuf_clone(buf); + rval = clonebuf; + + while (buf->next) + { + buf = buf->next; + clonebuf->next = gwbuf_clone(buf); + clonebuf = clonebuf->next; + } + return rval; +} + GWBUF *gwbuf_clone_portion( GWBUF *buf, diff --git a/server/core/modutil.c b/server/core/modutil.c index 5824de9e2..2e6651595 100644 --- a/server/core/modutil.c +++ b/server/core/modutil.c @@ -121,6 +121,41 @@ unsigned char *ptr; return 1; } +/** + * Calculate the length of MySQL packet and how much is missing from the GWBUF + * passed as parameter. + * + * This routine assumes that there is only one MySQL packet in the buffer. + * + * @param buf buffer list including the query, may consist of + * multiple buffers + * @param nbytes_missing pointer to missing bytecount + * + * @return the length of MySQL packet and writes missing bytecount to + * nbytes_missing. + */ +int modutil_MySQL_query_len( + GWBUF* buf, + int* nbytes_missing) +{ + int len; + int buflen; + uint8_t data; + + if (!modutil_is_SQL(buf)) + { + len = 0; + goto retblock; + } + len = MYSQL_GET_PACKET_LEN((uint8_t *)GWBUF_DATA(buf)); + *nbytes_missing = len-1; + buflen = gwbuf_length(buf); + + *nbytes_missing -= buflen-5; + +retblock: + return len; +} /** @@ -178,7 +213,7 @@ GWBUF *addition; /** * Extract the SQL from a COM_QUERY packet and return in a NULL terminated buffer. - * The buffer shoudl be freed by the caller when it is no longer required. + * The buffer should be freed by the caller when it is no longer required. * * If the packet is not a COM_QUERY packet then the function will return NULL * diff --git a/server/include/buffer.h b/server/include/buffer.h index 76eebe63d..df426baca 100644 --- a/server/include/buffer.h +++ b/server/include/buffer.h @@ -184,6 +184,7 @@ extern GWBUF *gwbuf_rtrim(GWBUF *head, unsigned int length); extern unsigned int gwbuf_length(GWBUF *head); extern GWBUF *gwbuf_clone_portion(GWBUF *head, size_t offset, size_t len); extern GWBUF *gwbuf_clone_transform(GWBUF *head, gwbuf_type_t type); +extern GWBUF *gwbuf_clone_all(GWBUF* head); extern void gwbuf_set_type(GWBUF *head, gwbuf_type_t type); extern int gwbuf_add_property(GWBUF *buf, char *name, char *value); extern char *gwbuf_get_property(GWBUF *buf, char *name); @@ -195,7 +196,6 @@ void gwbuf_add_buffer_object(GWBUF* buf, void* data, void (*donefun_fp)(void *)); void* gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id); - EXTERN_C_BLOCK_END diff --git a/server/include/modutil.h b/server/include/modutil.h index 762757617..fac39cbcc 100644 --- a/server/include/modutil.h +++ b/server/include/modutil.h @@ -42,6 +42,8 @@ extern GWBUF *modutil_replace_SQL(GWBUF *, char *); extern char *modutil_get_query(GWBUF* buf); extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *); GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf); +int modutil_MySQL_query_len(GWBUF* buf, int* nbytes_missing); + GWBUF *modutil_create_mysql_err_msg( int packet_number, diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index db772c7e8..5fc945277 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -737,12 +737,12 @@ char *ptr; int length, rval, residual = 0; GWBUF *clone = NULL; - if (my_session->branch_session && my_session->branch_session->state == SESSION_STATE_ROUTER_READY) + if (my_session->branch_session && + my_session->branch_session->state == SESSION_STATE_ROUTER_READY) { - if (my_session->residual) { - clone = gwbuf_clone(queue); + clone = gwbuf_clone_all(queue); if (my_session->residual < GWBUF_LENGTH(clone)) { @@ -764,22 +764,22 @@ GWBUF *clone = NULL; { char *dummy; - modutil_MySQL_Query(queue, &dummy, &length, &residual); - clone = gwbuf_clone(queue); + length = modutil_MySQL_query_len(queue, &residual); + clone = gwbuf_clone_all(queue); my_session->residual = residual; - } free(ptr); } else if (packet_is_required(queue)) { - clone = gwbuf_clone(queue); + clone = gwbuf_clone_all(queue); } - } + } /* Pass the query downstream */ - rval = my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, - queue); + rval = my_session->down.routeQuery( + my_session->down.instance, + my_session->down.session, + queue); if (clone) { my_session->n_duped++; diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index a5992b9e1..e5f96f088 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -668,8 +668,8 @@ int gw_read_client_event( "%lu [gw_read_client_event] session " "creation failed. fd %d, " "state = MYSQL_AUTH_FAILED.", - protocol->owner_dcb->fd, - pthread_self()))); + pthread_self(), + protocol->owner_dcb->fd))); /** Send ERR 1045 to client */ mysql_send_auth_error( diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 23cb59a2f..0b59e4593 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -1637,7 +1637,9 @@ mysql_send_auth_error ( * Buffer contains at least one of the following: * complete [complete] [partial] mysql packet * - * return pointer to gwbuf containing a complete packet or + * @param p_readbuf Address of read buffer pointer + * + * @return pointer to gwbuf containing a complete packet or * NULL if no complete packet was found. */ GWBUF* gw_MySQL_get_next_packet( diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index add5217a6..c38cc73be 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -410,12 +410,12 @@ BACKEND *master_host = NULL; LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, "%lu [newSession] Examine server in port %d with " - "%d connections. Status is %d, " + "%d connections. Status is %s, " "inst->bitvalue is %d", pthread_self(), inst->servers[i]->server->port, inst->servers[i]->current_connection_count, - inst->servers[i]->server->status, + STRSRVSTATUS(inst->servers[i]->server), inst->bitmask))); } @@ -971,7 +971,7 @@ static int handle_state_switch(DCB* dcb,DCB_REASON reason, void * routersession) SESSION* session = dcb->session; ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES*)routersession; SERVICE* service = session->service; - ROUTER* router = service->router; + ROUTER* router = (ROUTER *)service->router; switch(reason) {