From edb1c18e837378e0ff36f2fcca5f9572fb58fc6a Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 14 Apr 2016 17:40:06 +0300 Subject: [PATCH] Added missing check for error packets A missing else branch caused the binlogrouter to crash when it requests non-existent binlog file. --- server/modules/routing/binlog/blr_master.c | 70 ++++++++++++---------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/server/modules/routing/binlog/blr_master.c b/server/modules/routing/binlog/blr_master.c index 977888e3f..32fdf61d7 100644 --- a/server/modules/routing/binlog/blr_master.c +++ b/server/modules/routing/binlog/blr_master.c @@ -104,6 +104,7 @@ static void blr_distribute_error_message(ROUTER_INSTANCE *router, char *message, int blr_write_data_into_binlog(ROUTER_INSTANCE *router, uint32_t data_len, uint8_t *buf); void extract_checksum(ROUTER_INSTANCE* router, uint8_t *cksumptr, uint8_t len); +static void blr_terminate_master_replication(ROUTER_INSTANCE *router, uint8_t* ptr, int len); static int keepalive = 1; @@ -1054,6 +1055,10 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt) router->checksum_size = hdr.event_size - MYSQL_CHECKSUM_LEN; router->partial_checksum_bytes = 0; } + else + { + blr_terminate_master_replication(router, ptr, len); + } if (hdr.ok == 0) { @@ -1663,38 +1668,7 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt) } else { - unsigned long mysql_errno = extract_field(ptr + 5, 16); - char *msg_err = NULL; - int msg_len = 0; - msg_err = (char *)ptr + 7 + 6; // err msg starts after 7 bytes + 6 of status message - msg_len = len - 7 - 6; // msg len is decreased by 7 and 6 - msg_err = (char *)malloc(msg_len + 1); - strncpy(msg_err, (char *)ptr + 7 + 6, msg_len); - /* NULL terminate error string */ - *(msg_err + msg_len) = '\0'; - - spinlock_acquire(&router->lock); - - /* set mysql_errno */ - router->m_errno = mysql_errno; - - /* set io error message */ - if (router->m_errmsg) - { - free(router->m_errmsg); - } - router->m_errmsg = msg_err; - - /* Force stopped state */ - router->master_state = BLRM_SLAVE_STOPPED; - - spinlock_release(&router->lock); - - MXS_ERROR("Error packet in binlog stream.%s @ %lu.", - router->binlog_name, - router->current_pos); - - router->stats.n_binlog_errors++; + blr_terminate_master_replication(router, ptr, len); } } @@ -2800,3 +2774,35 @@ void extract_checksum(ROUTER_INSTANCE* router, uint8_t *cksumptr, uint8_t len) router->partial_checksum_bytes++; } } + +/** + * Stop the slave connection and log errors + * + * @param router Router instance + * @param ptr Pointer to the start of the packet + * @param len Length of the packet + */ +static void blr_terminate_master_replication(ROUTER_INSTANCE* router, uint8_t* ptr, int len) +{ + unsigned long mysql_errno = extract_field(ptr + 5, 16); + int msg_len = len - 7 - 6; // msg len is decreased by 7 and 6 + char *msg_err = (char *)malloc(msg_len + 1); + + strncpy(msg_err, (char *)ptr + 7 + 6, msg_len); + *(msg_err + msg_len) = '\0'; + + spinlock_acquire(&router->lock); + + char* old_errmsg = router->m_errmsg; + router->m_errmsg = msg_err; + router->m_errno = mysql_errno; + router->master_state = BLRM_SLAVE_STOPPED; + router->stats.n_binlog_errors++; + + spinlock_release(&router->lock); + + free(old_errmsg); + MXS_ERROR("Error packet in binlog stream.%s @ %lu.", + router->binlog_name, router->current_pos); + +}