summaryrefslogtreecommitdiff
path: root/proxy_network.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2022-11-28 22:57:50 -0800
committerdormando <dormando@rydia.net>2022-11-28 23:00:55 -0800
commit6f7725c4ba39ce8c979d0feaa4e2b71f4f4d36be (patch)
treea98f87e4e3d240eac85352e833b6424ac40730ad /proxy_network.c
parent46487041a498dcea664469fe74e4f44235212461 (diff)
downloadmemcached-6f7725c4ba39ce8c979d0feaa4e2b71f4f4d36be.tar.gz
proxy: more be validation fixes + old race
the prior fix to backend validation was incomplete: there was always a race during connection because the logic checking the result of flags was in the wrong place. Thus, if flooding with traffic during a reconnect it was still possible to write requests down the pipe or to overwrite the event handler. So this now skips both flushing and event handling for sure while connecting or validating (which I will likely merge into a single "valid" flag for a small speedup later) I was expecting a bug on the validating code but not on the existing code, but that race window is very short in my test rig so I was unable to reproduce it. Using a lot more traffic worked however.
Diffstat (limited to 'proxy_network.c')
-rw-r--r--proxy_network.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/proxy_network.c b/proxy_network.c
index 074b172..29d3aff 100644
--- a/proxy_network.c
+++ b/proxy_network.c
@@ -519,18 +519,18 @@ static void proxy_event_handler(evutil_socket_t fd, short which, void *arg) {
be->stacked = false;
int flags = 0;
- if (be->connecting) {
+ if (be->connecting || be->validating) {
P_DEBUG("%s: deferring IO pending connecting (%s:%s)\n", __func__, be->name, be->port);
} else {
flags = _flush_pending_write(be);
- }
- if (flags == -1) {
- _reset_bad_backend(be, P_BE_FAIL_WRITING);
- _backend_failed(be);
- } else if (!be->validating) {
- flags = be->can_write ? EV_READ|EV_TIMEOUT : EV_READ|EV_WRITE|EV_TIMEOUT;
- _set_event(be, t->base, flags, tmp_time, proxy_backend_handler);
+ if (flags == -1) {
+ _reset_bad_backend(be, P_BE_FAIL_WRITING);
+ _backend_failed(be);
+ } else {
+ flags = be->can_write ? EV_READ|EV_TIMEOUT : EV_READ|EV_WRITE|EV_TIMEOUT;
+ _set_event(be, t->base, flags, tmp_time, proxy_backend_handler);
+ }
}
}