From f5c26fc39608aca98900da83bb3844f71d9d2ce1 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 21 Sep 2016 12:38:05 +0100 Subject: [PATCH] [Fix] Another try to fix RDNS events processing logic Issue: #971 MFH: true --- contrib/librdns/dns_private.h | 3 ++- contrib/librdns/resolver.c | 25 ++++++------------- contrib/librdns/util.c | 47 ++++++++++++++++++++++++++--------- contrib/librdns/util.h | 2 ++ src/libserver/dns.c | 1 + 5 files changed, 48 insertions(+), 30 deletions(-) diff --git a/contrib/librdns/dns_private.h b/contrib/librdns/dns_private.h index a198dc46d..d2d1c08a3 100644 --- a/contrib/librdns/dns_private.h +++ b/contrib/librdns/dns_private.h @@ -72,7 +72,8 @@ struct rdns_request { enum { RDNS_REQUEST_NEW = 0, RDNS_REQUEST_REGISTERED = 1, - RDNS_REQUEST_SENT, + RDNS_REQUEST_WAIT_SEND, + RDNS_REQUEST_WAIT_REPLY, RDNS_REQUEST_REPLIED } state; diff --git a/contrib/librdns/resolver.c b/contrib/librdns/resolver.c index 5b68b4c1b..664d42026 100644 --- a/contrib/librdns/resolver.c +++ b/contrib/librdns/resolver.c @@ -81,6 +81,7 @@ rdns_send_request (struct rdns_request *req, int fd, bool new_req) HASH_ADD_INT (req->io->requests, id, req); req->async_event = resolver->async->add_write (resolver->async->data, fd, req); + req->state = RDNS_REQUEST_WAIT_SEND; } /* * If request is already processed then the calling function @@ -100,7 +101,7 @@ rdns_send_request (struct rdns_request *req, int fd, bool new_req) /* Fill timeout */ req->async_event = resolver->async->add_timer (resolver->async->data, req->timeout, req); - req->state = RDNS_REQUEST_SENT; + req->state = RDNS_REQUEST_WAIT_REPLY; } return 1; @@ -236,17 +237,6 @@ rdns_parse_reply (uint8_t *in, int r, struct rdns_request *req, return true; } -static void -rdns_request_unschedule (struct rdns_request *req) -{ - if (req->async_event) { - req->async->del_timer (req->async->data, - req->async_event); - } - /* Remove from id hashes */ - HASH_DEL (req->io->requests, req); -} - void rdns_process_read (int fd, void *arg) { @@ -284,8 +274,8 @@ rdns_process_read (int fd, void *arg) req->resolver->ups->data); } - req->state = RDNS_REQUEST_REPLIED; rdns_request_unschedule (req); + req->state = RDNS_REQUEST_REPLIED; req->func (rep, req->arg); REF_RELEASE (req); } @@ -319,8 +309,8 @@ rdns_process_timer (void *arg) } rep = rdns_make_reply (req, RDNS_RC_TIMEOUT); - req->state = RDNS_REQUEST_REPLIED; rdns_request_unschedule (req); + req->state = RDNS_REQUEST_REPLIED; req->func (rep, req->arg); REF_RELEASE (req); @@ -373,7 +363,7 @@ rdns_process_timer (void *arg) req->async_event); req->async_event = req->async->add_write (req->async->data, req->io->sock, req); - req->state = RDNS_REQUEST_REGISTERED; + req->state = RDNS_REQUEST_WAIT_SEND; } else if (r == -1) { if (req->resolver->ups && req->io->srv->ups_elt) { @@ -392,6 +382,7 @@ rdns_process_timer (void *arg) } else { req->async->repeat_timer (req->async->data, req->async_event); + req->state = RDNS_REQUEST_WAIT_REPLY; } } @@ -466,7 +457,7 @@ rdns_process_retransmit (int fd, void *arg) /* Retransmit one more time */ req->async_event = req->async->add_write (req->async->data, fd, req); - req->state = RDNS_REQUEST_REGISTERED; + req->state = RDNS_REQUEST_WAIT_SEND; } else if (r == -1) { if (req->resolver->ups && req->io->srv->ups_elt) { @@ -485,7 +476,7 @@ rdns_process_retransmit (int fd, void *arg) else { req->async_event = req->async->add_timer (req->async->data, req->timeout, req); - req->state = RDNS_REQUEST_SENT; + req->state = RDNS_REQUEST_WAIT_REPLY; } } diff --git a/contrib/librdns/util.c b/contrib/librdns/util.c index 4a44fe0d7..32ba4a5d9 100644 --- a/contrib/librdns/util.c +++ b/contrib/librdns/util.c @@ -402,18 +402,19 @@ rdns_request_free (struct rdns_request *req) if (req->reply != NULL) { rdns_reply_free (req->reply); } - if (req->state >= RDNS_REQUEST_SENT && - req->state < RDNS_REQUEST_REPLIED) { - /* Remove timer */ - req->async->del_timer (req->async->data, - req->async_event); - /* Remove from id hashes */ - HASH_DEL (req->io->requests, req); - } - else if (req->state == RDNS_REQUEST_REGISTERED) { - /* Remove retransmit event */ - req->async->del_write (req->async->data, - req->async_event); + if (req->async_event) { + if (req->state == RDNS_REQUEST_WAIT_REPLY) { + /* Remove timer */ + req->async->del_timer (req->async->data, + req->async_event); + /* Remove from id hashes */ + HASH_DEL (req->io->requests, req); + } + else if (req->state == RDNS_REQUEST_WAIT_SEND) { + /* Remove retransmit event */ + req->async->del_write (req->async->data, + req->async_event); + } } #ifdef TWEETNACL if (req->curve_plugin_data != NULL) { @@ -457,9 +458,31 @@ rdns_request_retain (struct rdns_request *req) return req; } +void +rdns_request_unschedule (struct rdns_request *req) +{ + if (req->async_event) { + if (req->state == RDNS_REQUEST_WAIT_REPLY) { + req->async->del_timer (req->async->data, + req->async_event); + /* Remove from id hashes */ + HASH_DEL (req->io->requests, req); + req->async_event = NULL; + } + else if (req->state == RDNS_REQUEST_WAIT_SEND) { + req->async->del_write (req->async->data, + req->async_event); + /* Remove from id hashes */ + HASH_DEL (req->io->requests, req); + req->async_event = NULL; + } + } +} + void rdns_request_release (struct rdns_request *req) { + rdns_request_unschedule (req); REF_RELEASE (req); } diff --git a/contrib/librdns/util.h b/contrib/librdns/util.h index 035f49a19..4da927c3a 100644 --- a/contrib/librdns/util.h +++ b/contrib/librdns/util.h @@ -59,4 +59,6 @@ void rdns_request_free (struct rdns_request *req); */ void rdns_reply_free (struct rdns_reply *rep); +void rdns_request_unschedule (struct rdns_request *req); + #endif /* UTIL_H_ */ diff --git a/src/libserver/dns.c b/src/libserver/dns.c index c0fdceebd..13d1b8309 100644 --- a/src/libserver/dns.c +++ b/src/libserver/dns.c @@ -53,6 +53,7 @@ rspamd_dns_fin_cb (gpointer arg) struct rspamd_dns_request_ud *reqdata = (struct rspamd_dns_request_ud *)arg; rdns_request_release (reqdata->req); + if (reqdata->pool == NULL) { g_slice_free1 (sizeof (struct rspamd_dns_request_ud), reqdata); } -- 2.39.5