From a67496f2d1f467f473cb39d56525e2d73b0d1b1d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 29 Sep 2025 11:07:01 +0930 Subject: [PATCH] ccan/io: fix occasional immediate close after io_shutdown() If we're doing a duplex connection, we could be still trying to write: that will fail (since we called shutdown on the write side), and we'll respond by closing the socket. The reason we're doing shutdown() is to ensure the final bytes are written: doing a close() breaks this, and so the result is lost final bytes. Signed-off-by: Rusty Russell --- ccan/io/io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ccan/io/io.c b/ccan/io/io.c index 58ae19bd..178ab01b 100644 --- a/ccan/io/io.c +++ b/ccan/io/io.c @@ -583,8 +583,13 @@ struct io_plan *io_sock_shutdown(struct io_conn *conn) if (shutdown(io_conn_fd(conn), SHUT_WR) != 0) return io_close(conn); - /* And leave unset .*/ - return &conn->plan[IO_IN]; + /* We need to make sure we don't try to write again, so + * "wait" on something which will never be woken. + * + * In the duplex case, we can call io_sock_shutdown on the + * input side, while io_write is going on on the output side. + * Then we will try to write, fail, and immediately close. */ + return io_wait_dir(conn, io_sock_shutdown, IO_OUT, io_never, NULL); } bool io_flush_sync(struct io_conn *conn) -- 2.47.3