From 8f8b4922957548b6e32a996f51b3e58378d39f16 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 11 May 2011 20:14:03 +0200 Subject: [PATCH] [MINOR] stream_sock: always clear BF_EXPECT_MORE upon complete transfer When sending is complete, it's preferred to systematically clear the flags that were set for that transfer. What could happen is that the to_forward counter had caused the MSG_MORE flag to be set and BF_EXPECT_MORE not to be cleared, resulting in this flag being unexpectedly maintained for next round. The code has taken extreme care of not doing this till now, but it's not acceptable that the caller has to know these precise semantics. So let's unconditionnally clear the flag instead. For the sake of safety, this fix should be backported to 1.4. --- src/stream_sock.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/stream_sock.c b/src/stream_sock.c index 3e9784c28..0d55128a8 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -650,8 +650,6 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b) send_flag |= MSG_MORE; } else if (b->flags & BF_EXPECT_MORE) { - /* it was forced on the buffer, this flag is one-shoot */ - b->flags &= ~BF_EXPECT_MORE; send_flag |= MSG_MORE; } @@ -661,9 +659,9 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b) ret = send(si->fd, b->w, max, send_flag); - /* disable it only once everything has been sent */ - if (ret == max && (b->flags & BF_SEND_DONTWAIT)) - b->flags &= ~BF_SEND_DONTWAIT; + /* Always clear both flags once everything has been sent */ + if (ret == max) + b->flags &= ~(BF_EXPECT_MORE | BF_SEND_DONTWAIT); } else { int skerr; socklen_t lskerr = sizeof(skerr);