Fix for CRC in fake rotate events

This commit is contained in:
Mark Riddoch
2015-01-30 14:55:14 +00:00
parent a786d76852
commit 5ac736a14e
2 changed files with 32 additions and 24 deletions

View File

@ -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;

View File

@ -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;