Skip to content

Commit

Permalink
gossipd: make writes to gossip_store atomic.
Browse files Browse the repository at this point in the history
There's a corner case where otherwise a reader could see the header and
not the body of a message.  It could handle that in various ways,
but simplest (and most efficient) is to avoid it happening.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Jun 4, 2019
1 parent a5f6ef3 commit 4399faf
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions gossipd/gossip_store.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "gossip_store.h"

#include <ccan/array_size/array_size.h>
#include <ccan/crc/crc.h>
#include <ccan/endian/endian.h>
#include <ccan/read_write_all/read_write_all.h>
Expand All @@ -12,6 +13,7 @@
#include <gossipd/gen_gossip_store.h>
#include <gossipd/gen_gossip_wire.h>
#include <stdio.h>
#include <sys/uio.h>
#include <unistd.h>
#include <wire/gen_peer_wire.h>
#include <wire/wire.h>
Expand Down Expand Up @@ -51,6 +53,7 @@ static bool append_msg(int fd, const u8 *msg, u64 *len)
{
beint32_t hdr[2];
u32 msglen;
struct iovec iov[2];

msglen = tal_count(msg);
hdr[0] = cpu_to_be32(msglen);
Expand All @@ -59,8 +62,12 @@ static bool append_msg(int fd, const u8 *msg, u64 *len)
if (len)
*len += sizeof(hdr) + msglen;

return (write(fd, hdr, sizeof(hdr)) == sizeof(hdr) &&
write(fd, msg, msglen) == msglen);
/* Use writev so it will appear in store atomically */
iov[0].iov_base = hdr;
iov[0].iov_len = sizeof(hdr);
iov[1].iov_base = (void *)msg;
iov[1].iov_len = msglen;
return writev(fd, iov, ARRAY_SIZE(iov)) == sizeof(hdr) + msglen;
}

struct gossip_store *gossip_store_new(struct routing_state *rstate)
Expand Down

0 comments on commit 4399faf

Please sign in to comment.