summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2019-07-15 06:47:54 +0200
committerWilly Tarreau <w@1wt.eu>2019-07-15 06:47:54 +0200
commit9cca8dfc0b96a2cbe35e789e2ff0b65aec78dbe6 (patch)
treebff06f2c8618bc813a1575ea5d3f1441f693a2f3
parent4bd58676275d557a654979948f587aaae8e15c0d (diff)
downloadhaproxy-9cca8dfc0b96a2cbe35e789e2ff0b65aec78dbe6.tar.gz
BUG/MINOR: mux-pt: do not pretend there's more data after a read0
Commit 8706c8131 ("BUG/MEDIUM: mux_pt: Always set CS_FL_RCV_MORE.") was a bit excessive in setting this flag, it refrained from removing it after read0 unless it was on an empty call. The problem it causes is that read0 is thus ignored on the first call : $ strace -tts200 -e trace=recvfrom,epoll_wait,sendto ./haproxy -db -f tcp.cfg 06:34:23.956897 recvfrom(9, "blah\n", 15360, 0, NULL, NULL) = 5 06:34:23.956938 recvfrom(9, "", 15355, 0, NULL, NULL) = 0 06:34:23.956958 recvfrom(9, "", 15355, 0, NULL, NULL) = 0 06:34:23.957033 sendto(8, "blah\n", 5, MSG_DONTWAIT|MSG_NOSIGNAL, NULL, 0) = 5 06:34:23.957229 epoll_wait(3, [{EPOLLIN|EPOLLHUP|EPOLLRDHUP, {u32=8, u64=8}}], 200, 0) = 1 06:34:23.957297 recvfrom(8, "", 15360, 0, NULL, NULL) = 0 If CO_FL_SOCK_RD_SH is reported by the transport layer, it indicates the read0 was already seen thus we must not try again and we must immedaitely report it. The simple fix consists in removing the test on ret==0 : $ strace -tts200 -e trace=recvfrom,epoll_wait,sendto ./haproxy -db -f tcp.cfg 06:44:21.634835 recvfrom(9, "blah\n", 15360, 0, NULL, NULL) = 5 06:44:21.635020 recvfrom(9, "", 15355, 0, NULL, NULL) = 0 06:44:21.635056 sendto(8, "blah\n", 5, MSG_DONTWAIT|MSG_NOSIGNAL, NULL, 0) = 5 06:44:21.635269 epoll_wait(3, [{EPOLLIN|EPOLLHUP|EPOLLRDHUP, {u32=8, u64=8}}], 200, 0) = 1 06:44:21.635330 recvfrom(8, "", 15360, 0, NULL, NULL) = 0 The issue is minor, it only results in extra syscalls and CPU usage. This fix should be backported to 2.0 and 1.9.
-rw-r--r--src/mux_pt.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/src/mux_pt.c b/src/mux_pt.c
index 47d0634bd..323594f32 100644
--- a/src/mux_pt.c
+++ b/src/mux_pt.c
@@ -260,13 +260,11 @@ static size_t mux_pt_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t
b_realign_if_empty(buf);
ret = cs->conn->xprt->rcv_buf(cs->conn, cs->conn->xprt_ctx, buf, count, flags);
if (conn_xprt_read0_pending(cs->conn)) {
- if (ret == 0)
- cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM);
+ cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM);
cs->flags |= CS_FL_EOS;
}
if (cs->conn->flags & CO_FL_ERROR) {
- if (ret == 0)
- cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM);
+ cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM);
cs->flags |= CS_FL_ERROR;
}
return ret;