From: Willy Tarreau Date: Fri, 9 Mar 2012 17:10:44 +0000 (+0100) Subject: BUG/MINOR: stream_sock: don't remove BF_EXPECT_MORE and BF_SEND_DONTWAIT on partial... X-Git-Tag: v1.5-dev8~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f17810e4fadcda9e556c1950d49a1617e87486b8;p=thirdparty%2Fhaproxy.git BUG/MINOR: stream_sock: don't remove BF_EXPECT_MORE and BF_SEND_DONTWAIT on partial writes The flags are one-shot but should be maintained over all send() operations as long as send_max is not flushed. The flags were incidentely cleared once a complete send() was performed, regardless of the fact that the send() might have been on the first half of a buffer before a wrapping. The result is that on wrapping data (eg: which happens often with chunked encoding), many incomplete segments are transmitted instead of being aggregated. The fix consists in only flushing the flags only once send_max is empty, which was the expected behaviour. This fix should be backported to 1.4 though it is not critical, just sub-optimal. --- diff --git a/src/stream_sock.c b/src/stream_sock.c index 29b7fcb2dd..8c9f765e53 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -633,10 +633,6 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b) send_flag &= ~MSG_MORE; ret = send(si->fd, b->w, max, send_flag); - - /* 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); @@ -668,6 +664,8 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b) b->send_max -= ret; if (!b->send_max) { + /* Always clear both flags once everything has been sent, they're one-shot */ + b->flags &= ~(BF_EXPECT_MORE | BF_SEND_DONTWAIT); if (likely(!b->pipe)) b->flags |= BF_OUT_EMPTY; break;