Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
f8ea19e5
Commit
f8ea19e5
authored
Apr 02, 2012
by
antirez
Browse files
DUMP/RESTORE now use CRC64 instead of truncated SHA1.
parent
9510d65d
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/cluster.c
View file @
f8ea19e5
#include "redis.h"
#include "redis.h"
#include "
sha1
.h"
#include "
endianconv
.h"
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <fcntl.h>
...
@@ -1464,8 +1464,8 @@ void clusterCommand(redisClient *c) {
...
@@ -1464,8 +1464,8 @@ void clusterCommand(redisClient *c) {
/* Generates a DUMP-format representation of the object 'o', adding it to the
/* Generates a DUMP-format representation of the object 'o', adding it to the
* io stream pointed by 'rio'. This function can't fail. */
* io stream pointed by 'rio'. This function can't fail. */
void createDumpPayload(rio *payload, robj *o) {
void createDumpPayload(rio *payload, robj *o) {
unsigned
char
hash
[
20
],
buf
[
2
];
unsigned char buf[2];
SHA1_CTX
ctx
;
uint64_t crc
;
/* Serialize the object in a RDB-like format. It consist of an object type
/* Serialize the object in a RDB-like format. It consist of an object type
* byte followed by the serialized object. This is understood by RESTORE. */
* byte followed by the serialized object. This is understood by RESTORE. */
...
@@ -1474,35 +1474,34 @@ void createDumpPayload(rio *payload, robj *o) {
...
@@ -1474,35 +1474,34 @@ void createDumpPayload(rio *payload, robj *o) {
redisAssert(rdbSaveObject(payload,o));
redisAssert(rdbSaveObject(payload,o));
/* Write the footer, this is how it looks like:
/* Write the footer, this is how it looks like:
* ----------------+---------------------+--------------+
* ----------------+---------------------+--------------
-
+
* ... RDB payload | 2 bytes RDB version | 8 bytes
SHA1
|
* ... RDB payload | 2 bytes RDB version | 8 bytes
CRC64
|
* ----------------+---------------------+--------------+
* ----------------+---------------------+--------------
-
+
*
The SHA1 is just 8 bytes of truncated SHA1 of everything excluding itself
.
*
RDB version and CRC are both in little endian
.
* The 2 bytes RDB version is a little endian unsigned integer.
*/
*/
/* RDB version */
/* RDB version */
buf[0] = REDIS_RDB_VERSION & 0xff;
buf[0] = REDIS_RDB_VERSION & 0xff;
buf[1] = (REDIS_RDB_VERSION >> 8) & 0xff;
buf[1] = (REDIS_RDB_VERSION >> 8) & 0xff;
payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,buf,2);
payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,buf,2);
/* Truncated SHA1 */
/* CRC64 */
SHA1Init
(
&
ctx
);
crc = crc64((unsigned char*)payload->io.buffer.ptr,
SHA1Update
(
&
ctx
,(
unsigned
char
*
)
payload
->
io
.
buffer
.
ptr
,
sdslen(payload->io.buffer.ptr));
sdslen
(
payload
->
io
.
buffer
.
ptr
));
memrev64ifbe(&crc);
SHA1Final
(
hash
,
&
ctx
);
payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,&crc,8);
payload
->
io
.
buffer
.
ptr
=
sdscatlen
(
payload
->
io
.
buffer
.
ptr
,
hash
,
8
);
}
}
/* Verify that the RDB version of the dump payload matches the one of this Redis
/* Verify that the RDB version of the dump payload matches the one of this Redis
* instance and that the
truncated SHA1
is ok.
* instance and that the
checksum
is ok.
* If the DUMP payload looks valid REDIS_OK is returned, otherwise REDIS_ERR
* If the DUMP payload looks valid REDIS_OK is returned, otherwise REDIS_ERR
* is returned. */
* is returned. */
int verifyDumpPayload(unsigned char *p, size_t len) {
int verifyDumpPayload(unsigned char *p, size_t len) {
unsigned
char
hash
[
20
],
*
footer
;
unsigned char *footer;
SHA1_CTX
ctx
;
uint16_t rdbver;
uint16_t rdbver;
uint64_t crc;
/* At least 2 bytes of RDB version and 8 of
truncated SHA
should be present. */
/* At least 2 bytes of RDB version and 8 of
CRC64
should be present. */
if (len < 10) return REDIS_ERR;
if (len < 10) return REDIS_ERR;
footer = p+(len-10);
footer = p+(len-10);
...
@@ -1510,11 +1509,10 @@ int verifyDumpPayload(unsigned char *p, size_t len) {
...
@@ -1510,11 +1509,10 @@ int verifyDumpPayload(unsigned char *p, size_t len) {
rdbver = (footer[1] << 8) | footer[0];
rdbver = (footer[1] << 8) | footer[0];
if (rdbver != REDIS_RDB_VERSION) return REDIS_ERR;
if (rdbver != REDIS_RDB_VERSION) return REDIS_ERR;
/* Verify truncated SHA1 */
/* Verify CRC64 */
SHA1Init
(
&
ctx
);
crc = crc64(p,len-8);
SHA1Update
(
&
ctx
,
p
,
len
-
8
);
memrev64ifbe(&crc);
SHA1Final
(
hash
,
&
ctx
);
return (memcmp(&crc,footer+2,8) == 0) ? REDIS_OK : REDIS_ERR;
return
(
memcmp
(
hash
,
footer
+
2
,
8
)
==
0
)
?
REDIS_OK
:
REDIS_ERR
;
}
}
/* DUMP keyname
/* DUMP keyname
...
@@ -1561,7 +1559,7 @@ void restoreCommand(redisClient *c) {
...
@@ -1561,7 +1559,7 @@ void restoreCommand(redisClient *c) {
return;
return;
}
}
/* Verify
truncated SHA1 and RDB version
. */
/* Verify
RDB version and data checksum
. */
if (verifyDumpPayload(c->argv[3]->ptr,sdslen(c->argv[3]->ptr)) == REDIS_ERR) {
if (verifyDumpPayload(c->argv[3]->ptr,sdslen(c->argv[3]->ptr)) == REDIS_ERR) {
addReplyError(c,"DUMP payload version or checksum are wrong");
addReplyError(c,"DUMP payload version or checksum are wrong");
return;
return;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment