Skip to content

Commit

Permalink
gossmap: check checksums.
Browse files Browse the repository at this point in the history
We assume if it's incorrect, we simply need to wait.  If this proves incorrect,
we will see a stream of BROKEN log messages.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Feb 5, 2025
1 parent 536cc62 commit e9f1636
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions common/gossmap.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "config.h"
#include <assert.h>
#include <ccan/crypto/siphash24/siphash24.h>
#include <ccan/crc32c/crc32c.h>
#include <ccan/err/err.h>
#include <ccan/htable/htable_type.h>
#include <ccan/ptrint/ptrint.h>
Expand Down Expand Up @@ -658,15 +659,17 @@ static bool map_catchup(struct gossmap *map)
{
size_t reclen;
bool changed = false;
u8 msgbuf[65535];

for (; map->map_end + sizeof(struct gossip_hdr) < map->map_size;
map->map_end += reclen) {
struct gossip_hdr ghdr;
u64 off;
u16 type, flags;
u16 msglen, type, flags;

map_copy(map, map->map_end, &ghdr, sizeof(ghdr));
reclen = be16_to_cpu(ghdr.len) + sizeof(ghdr);
msglen = be16_to_cpu(ghdr.len);
reclen = msglen + sizeof(ghdr);

flags = be16_to_cpu(ghdr.flags);
if (flags & GOSSIP_STORE_DELETED_BIT)
Expand All @@ -676,13 +679,34 @@ static bool map_catchup(struct gossmap *map)
if (map->map_end + reclen > map->map_size)
break;

/* Under zfs, apparently we can see zeroes here. I'm hoping this effect
* is transient: hope to make progress next time */
if (be16_to_cpu(ghdr.len) < sizeof(be16))
/* Under zfs, apparently we can see zeroes here. I'm
* hoping this effect is transient: hope to make
* progress next time. We check size and checksum */
if (msglen < sizeof(be16)) {
map->logcb(map->cbarg,
LOG_BROKEN,
"Truncated gossmap record @%"PRIu64
"/%"PRIu64" (len %zu): waiting",
map->map_end, map->map_size, msglen);
break;
}

off = map->map_end + sizeof(ghdr);
type = map_be16(map, off);

map_copy(map, off, msgbuf, msglen);
if (be32_to_cpu(ghdr.crc)
!= crc32c(be32_to_cpu(ghdr.timestamp), msgbuf, msglen)) {
map->logcb(map->cbarg,
LOG_BROKEN,
"Bad checksum on gossmap record @%"PRIu64
"/%"PRIu64" should be %u (%s): waiting",
map->map_end, map->map_size,
be32_to_cpu(ghdr.crc),
tal_hexstr(tmpctx, msgbuf, msglen));
break;
}

if (type == WIRE_CHANNEL_ANNOUNCEMENT) {
/* Don't read yet if amount field is not there! */
if (!add_channel(map, off, be16_to_cpu(ghdr.len)))
Expand Down

0 comments on commit e9f1636

Please sign in to comment.