common/gossip_store: expose routine to read one header.
This is useful when you're writing routines to scan it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
0274d88bad
commit
7e8b93daa1
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue