Skip to content

Commit

Permalink
common/gossip_store: expose routine to read one header.
Browse files Browse the repository at this point in the history
This is useful when you're writing routines to scan it.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell authored and endothermicdev committed Jan 30, 2023
1 parent 0274d88 commit 7e8b93d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
47 changes: 35 additions & 12 deletions common/gossip_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,25 +182,48 @@ u8 *gossip_store_next(const tal_t *ctx,
return msg;
}

size_t find_gossip_store_end(int gossip_store_fd, size_t off)
/* We cheat and read first two bytes of message too. */
struct hdr_and_type {
struct gossip_hdr hdr;
be16 type;
};
/* Beware padding! */
#define HDR_AND_TYPE_SIZE (sizeof(struct gossip_hdr) + sizeof(u16))

bool gossip_store_readhdr(int gossip_store_fd, size_t off,
size_t *len,
u32 *timestamp,
u16 *flags,
u16 *type)
{
/* We cheat and read first two bytes of message too. */
struct {
struct gossip_hdr hdr;
be16 type;
} buf;
struct hdr_and_type buf;
int r;

while ((r = pread(gossip_store_fd, &buf,
sizeof(buf.hdr) + sizeof(buf.type), off))
== sizeof(buf.hdr) + sizeof(buf.type)) {
u16 msglen = be16_to_cpu(buf.hdr.len);
r = pread(gossip_store_fd, &buf, HDR_AND_TYPE_SIZE, off);
if (r != HDR_AND_TYPE_SIZE)
return false;
*len = be16_to_cpu(buf.hdr.len);
if (flags)
*flags = be16_to_cpu(buf.hdr.flags);
if (timestamp)
*timestamp = be32_to_cpu(buf.hdr.timestamp);
if (type)
*type = be16_to_cpu(buf.type);
return true;
}

size_t find_gossip_store_end(int gossip_store_fd, size_t off)
{
size_t msglen;
u16 type;

while (gossip_store_readhdr(gossip_store_fd, off,
&msglen, NULL, NULL, &type)) {
/* Don't swallow end marker! */
if (buf.type == CPU_TO_BE16(WIRE_GOSSIP_STORE_ENDED))
if (type == WIRE_GOSSIP_STORE_ENDED)
break;

off += sizeof(buf.hdr) + msglen;
off += sizeof(struct gossip_hdr) + msglen;
}
return off;
}
Expand Down
21 changes: 21 additions & 0 deletions common/gossip_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ u8 *gossip_store_next(const tal_t *ctx,
bool with_spam,
size_t *off, size_t *end);

/**
* Direct store accessor: read gossip msg hdr from store.
* @gossip_store_fd: the readable file descriptor
* @off: the offset to read
* @len (out): the length of the message (not including header)
* @timestamp (out): if non-NULL, set to the timestamp.
* @flags (out): if non-NULL, set to the flags.
* @type (out): if non-NULL, set to the msg type.
*
* Returns false if there are no more gossip msgs. If you
* want to read the message, use gossip_store_next, if you
* want to skip, simply add sizeof(gossip_hdr) + *len to *off.
* Note: it's possible that entire record isn't there yet,
* so gossip_store_next can fail.
*/
bool gossip_store_readhdr(int gossip_store_fd, size_t off,
size_t *len,
u32 *timestamp,
u16 *flags,
u16 *type);

/**
* Gossipd will be writing to this, and it's not atomic! Safest
* way to find the "end" is to walk through.
Expand Down

0 comments on commit 7e8b93d

Please sign in to comment.