Fix for CRC in fake rotate events
This commit is contained in:
@ -681,6 +681,11 @@ static REP_HEADER phdr;
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkt_length = gwbuf_length(pkt);
|
pkt_length = gwbuf_length(pkt);
|
||||||
|
/*
|
||||||
|
* Loop over all the packets while we still have some data
|
||||||
|
* and the packet length is enough to hold a replication event
|
||||||
|
* header.
|
||||||
|
*/
|
||||||
while (pkt && pkt_length > 24)
|
while (pkt && pkt_length > 24)
|
||||||
{
|
{
|
||||||
reslen = GWBUF_LENGTH(pkt);
|
reslen = GWBUF_LENGTH(pkt);
|
||||||
@ -708,6 +713,7 @@ static REP_HEADER phdr;
|
|||||||
{
|
{
|
||||||
len = EXTRACT24(pdata) + 4;
|
len = EXTRACT24(pdata) + 4;
|
||||||
}
|
}
|
||||||
|
/* len is now the payload length for the packet we are working on */
|
||||||
|
|
||||||
if (reslen < len && pkt_length >= len)
|
if (reslen < len && pkt_length >= len)
|
||||||
{
|
{
|
||||||
@ -787,10 +793,17 @@ static REP_HEADER phdr;
|
|||||||
n_bufs = 1;
|
n_bufs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ptr now points at the current message in a contiguous buffer,
|
||||||
|
* this buffer is either within the GWBUF or in a malloc'd
|
||||||
|
* copy if the message straddles GWBUF's.
|
||||||
|
*/
|
||||||
|
|
||||||
if (len < BINLOG_EVENT_HDR_LEN)
|
if (len < BINLOG_EVENT_HDR_LEN)
|
||||||
{
|
{
|
||||||
char *msg = "";
|
char *msg = "";
|
||||||
|
|
||||||
|
/* Packet is too small to be a binlog event */
|
||||||
if (ptr[4] == 0xfe) /* EOF Packet */
|
if (ptr[4] == 0xfe) /* EOF Packet */
|
||||||
{
|
{
|
||||||
msg = "end of file";
|
msg = "end of file";
|
||||||
@ -812,7 +825,7 @@ static REP_HEADER phdr;
|
|||||||
|
|
||||||
blr_extract_header(ptr, &hdr);
|
blr_extract_header(ptr, &hdr);
|
||||||
|
|
||||||
if (hdr.event_size != len - 5)
|
if (hdr.event_size != len - 5) /* Sanity check */
|
||||||
{
|
{
|
||||||
LOGIF(LE,(skygw_log_write(
|
LOGIF(LE,(skygw_log_write(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
@ -843,8 +856,10 @@ static REP_HEADER phdr;
|
|||||||
phdr = hdr;
|
phdr = hdr;
|
||||||
if (hdr.ok == 0)
|
if (hdr.ok == 0)
|
||||||
{
|
{
|
||||||
#define CHECK_CRC 1
|
/*
|
||||||
#if CHECK_CRC
|
* First check that the checksum we calculate matches the
|
||||||
|
* checksum in the packet we received.
|
||||||
|
*/
|
||||||
uint32_t chksum, pktsum;
|
uint32_t chksum, pktsum;
|
||||||
|
|
||||||
chksum = crc32(0L, NULL, 0);
|
chksum = crc32(0L, NULL, 0);
|
||||||
@ -870,7 +885,6 @@ static REP_HEADER phdr;
|
|||||||
blr_master_delayed_connect(router);
|
blr_master_delayed_connect(router);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
router->stats.n_binlogs++;
|
router->stats.n_binlogs++;
|
||||||
router->lastEventReceived = hdr.event_type;
|
router->lastEventReceived = hdr.event_type;
|
||||||
|
|
||||||
|
|||||||
@ -888,7 +888,8 @@ if (hkheartbeat - beat1 > 1) LOGIF(LE, (skygw_log_write(
|
|||||||
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
||||||
"Slave reached end of file for binlog file %s at %u "
|
"Slave reached end of file for binlog file %s at %u "
|
||||||
"which is not the file currently being downloaded. "
|
"which is not the file currently being downloaded. "
|
||||||
"Master binlog is %s, %lu.",
|
"Master binlog is %s, %lu. This may be caused by a "
|
||||||
|
"previous failure of the master.",
|
||||||
slave->binlogfile, slave->binlog_pos,
|
slave->binlogfile, slave->binlog_pos,
|
||||||
router->binlog_name, router->binlog_position)));
|
router->binlog_name, router->binlog_position)));
|
||||||
if (blr_slave_fake_rotate(router, slave))
|
if (blr_slave_fake_rotate(router, slave))
|
||||||
@ -1014,11 +1015,7 @@ uint32_t chksum;
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
binlognamelen = strlen(slave->binlogfile);
|
binlognamelen = strlen(slave->binlogfile);
|
||||||
|
len = 19 + 8 + 4 + binlognamelen;
|
||||||
if (slave->nocrc)
|
|
||||||
len = 19 + 8 + binlognamelen;
|
|
||||||
else
|
|
||||||
len = 19 + 8 + 4 + binlognamelen;
|
|
||||||
|
|
||||||
// Build a fake rotate event
|
// Build a fake rotate event
|
||||||
resp = gwbuf_alloc(len + 5);
|
resp = gwbuf_alloc(len + 5);
|
||||||
@ -1037,20 +1034,17 @@ uint32_t chksum;
|
|||||||
memcpy(ptr, slave->binlogfile, binlognamelen);
|
memcpy(ptr, slave->binlogfile, binlognamelen);
|
||||||
ptr += binlognamelen;
|
ptr += binlognamelen;
|
||||||
|
|
||||||
if (!slave->nocrc)
|
/*
|
||||||
{
|
* Now add the CRC to the fake binlog rotate event.
|
||||||
/*
|
*
|
||||||
* Now add the CRC to the fake binlog rotate event.
|
* The algorithm is first to compute the checksum of an empty buffer
|
||||||
*
|
* and then the checksum of the event portion of the message, ie we do not
|
||||||
* The algorithm is first to compute the checksum of an empty buffer
|
* include the length, sequence number and ok byte that makes up the first
|
||||||
* and then the checksum of the event portion of the message, ie we do not
|
* 5 bytes of the message. We also do not include the 4 byte checksum itself.
|
||||||
* include the length, sequence number and ok byte that makes up the first
|
*/
|
||||||
* 5 bytes of the message. We also do not include the 4 byte checksum itself.
|
chksum = crc32(0L, NULL, 0);
|
||||||
*/
|
chksum = crc32(chksum, GWBUF_DATA(resp) + 5, hdr.event_size - 4);
|
||||||
chksum = crc32(0L, NULL, 0);
|
encode_value(ptr, chksum, 32);
|
||||||
chksum = crc32(chksum, GWBUF_DATA(resp) + 5, hdr.event_size - 4);
|
|
||||||
encode_value(ptr, chksum, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
slave->dcb->func.write(slave->dcb, resp);
|
slave->dcb->func.write(slave->dcb, resp);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user