From 4399faf57c27170190548fb857aae2052d5b389c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 4 Jun 2019 03:43:25 +0930 Subject: [PATCH] gossipd: make writes to gossip_store atomic. 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 --- gossipd/gossip_store.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index ab252c979..6723ffe7f 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -1,5 +1,6 @@ #include "gossip_store.h" +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -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); @@ -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)