]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: kqueue: Make sure we report read events even when no data.
authorOlivier Houchard <cognet@ci0.org>
Tue, 10 Dec 2019 17:22:55 +0000 (18:22 +0100)
committerOlivier Houchard <cognet@ci0.org>
Tue, 10 Dec 2019 17:27:17 +0000 (18:27 +0100)
When we have a EVFILT_READ event, an optimization was made, and the FD was
not reported as ready to receive if there were no data available. That way,
if the socket was closed by our peer (the EV8EOF flag was set), and there were
no remaining data to read, we would just close(), and avoid doing a recv().
However, it may be fine for TCP socket, but it is not for UDP.
If we send data via UDP, and we receive an error, the only way to detect it
is to attempt a recv(). However, in this case, kevent() will report a read
event, but with no data, so we'd just ignore that read event, nothing would be
done about it, and the poller would be woken up by it over and over.
To fix this, report read events if either we have data, or the EV_EOF flag
is not set.

This should be backported to 2.1, 2.0, 1.9 and 1.8.

src/ev_kqueue.c

index 8f0b7c90725206339f76a16b7de54ef0f81b7157..98fac85202d71e7813db0d18d35cb53ca1b360df 100644 (file)
@@ -197,7 +197,7 @@ REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
                }
 
                if (kev[count].filter == EVFILT_READ) {
-                       if (kev[count].data)
+                       if (kev[count].data || !(kev[count].flags & EV_EOF))
                                n |= FD_EV_READY_R;
                        if (kev[count].flags & EV_EOF)
                                n |= FD_EV_SHUT_R;