backport from main: event thread fix for close then open of same fd

In some circumstances a file descriptor can be closed, then a new
file descriptor pointing to a different endpoint can be opened.  These
events must not be merged, a delete must always be processed since
they are not actually pointing to the same connection even though
the file descriptor itself is the same, the OS just re-used it.

Fix By: Brad House (@bradh352)
v1.26
Brad House 1 year ago
parent 32d49f38a2
commit 81a7d17ed5
  1. 12
      src/lib/ares_event_thread.c

@ -52,7 +52,13 @@ static void ares_event_destroy_cb(void *arg)
/* See if a pending update already exists. We don't want to enqueue multiple
* updates for the same event handle. Right now this is O(n) based on number
* of updates already enqueued. In the future, it might make sense to make
* this O(1) with a hashtable. */
* this O(1) with a hashtable.
* NOTE: in some cases a delete then re-add of the same fd, but really pointing
* to a different destination can happen due to a quick close of a
* connection then creation of a new one. So we need to look at the
* flags and ignore any delete events when finding a match since we
* need to process the delete always, it can't be combined with other
* updates. */
static ares_event_t *ares_event_update_find(ares_event_thread_t *e,
ares_socket_t fd, const void *data)
{
@ -62,12 +68,12 @@ static ares_event_t *ares_event_update_find(ares_event_thread_t *e,
node = ares__llist_node_next(node)) {
ares_event_t *ev = ares__llist_node_val(node);
if (fd != ARES_SOCKET_BAD && fd == ev->fd) {
if (fd != ARES_SOCKET_BAD && fd == ev->fd && ev->flags != 0) {
return ev;
}
if (fd == ARES_SOCKET_BAD && ev->fd == ARES_SOCKET_BAD &&
data == ev->data) {
data == ev->data && ev->flags != 0) {
return ev;
}
}

Loading…
Cancel
Save