diff options
author | dormando <dormando@rydia.net> | 2022-11-28 22:57:50 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2022-11-28 23:00:55 -0800 |
commit | 6f7725c4ba39ce8c979d0feaa4e2b71f4f4d36be (patch) | |
tree | a98f87e4e3d240eac85352e833b6424ac40730ad | |
parent | 46487041a498dcea664469fe74e4f44235212461 (diff) | |
download | memcached-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.
-rw-r--r-- | proxy_network.c | 16 |
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); + } } } |