aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/librdns
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-09-26 17:08:43 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-09-26 17:15:51 +0100
commit502559ceab99ae36ae0200f98aa2ac14c99b0255 (patch)
tree1623c2942d05c2bcb85bd63aadd064742e817e31 /contrib/librdns
parentc2cbe8a3fd480360940921970de30c3f5c9f3c10 (diff)
downloadrspamd-502559ceab99ae36ae0200f98aa2ac14c99b0255.tar.gz
rspamd-502559ceab99ae36ae0200f98aa2ac14c99b0255.zip
[Fix] Do not replan retransmits if merely one server is defined
Diffstat (limited to 'contrib/librdns')
-rw-r--r--contrib/librdns/rdns.h1
-rw-r--r--contrib/librdns/resolver.c68
2 files changed, 42 insertions, 27 deletions
diff --git a/contrib/librdns/rdns.h b/contrib/librdns/rdns.h
index 7e5843183..e5fc82fe4 100644
--- a/contrib/librdns/rdns.h
+++ b/contrib/librdns/rdns.h
@@ -164,6 +164,7 @@ struct rdns_upstream_context {
size_t len, void *ups_data);
struct rdns_upstream_elt* (*select_retransmit)(const char *name,
size_t len, void *ups_data);
+ unsigned int (*count)(void *ups_data);
void (*ok)(struct rdns_upstream_elt *elt, void *ups_data);
void (*fail)(struct rdns_upstream_elt *elt, void *ups_data);
};
diff --git a/contrib/librdns/resolver.c b/contrib/librdns/resolver.c
index 329caa620..8c5df913f 100644
--- a/contrib/librdns/resolver.c
+++ b/contrib/librdns/resolver.c
@@ -295,6 +295,7 @@ rdns_process_timer (void *arg)
bool renew = false;
struct rdns_resolver *resolver;
struct rdns_server *serv = NULL;
+ unsigned cnt;
req->retransmits --;
resolver = req->resolver;
@@ -318,44 +319,57 @@ rdns_process_timer (void *arg)
}
if (!req->io->active || req->retransmits == 1) {
- /* Do not reschedule IO requests on inactive sockets */
- rdns_debug ("reschedule request with id: %d", (int)req->id);
- rdns_request_unschedule (req);
- REF_RELEASE (req->io);
if (resolver->ups) {
- struct rdns_upstream_elt *elt;
+ cnt = resolver->ups->count (resolver->ups->data);
+ }
+ else {
+ cnt = 0;
+ UPSTREAM_FOREACH (resolver->servers, serv) {
+ cnt ++;
+ }
+ }
- elt = resolver->ups->select_retransmit (req->requested_names[0].name,
- req->requested_names[0].len, resolver->ups->data);
+ if (!req->io->active || cnt > 1) {
+ /* Do not reschedule IO requests on inactive sockets */
+ rdns_debug ("reschedule request with id: %d", (int)req->id);
+ rdns_request_unschedule (req);
+ REF_RELEASE (req->io);
- if (elt) {
- serv = elt->server;
- serv->ups_elt = elt;
+ if (resolver->ups) {
+ struct rdns_upstream_elt *elt;
+
+ elt = resolver->ups->select_retransmit (req->requested_names[0].name,
+ req->requested_names[0].len, resolver->ups->data);
+
+ if (elt) {
+ serv = elt->server;
+ serv->ups_elt = elt;
+ }
+ else {
+ UPSTREAM_SELECT_ROUND_ROBIN (resolver->servers, serv);
+ }
}
else {
UPSTREAM_SELECT_ROUND_ROBIN (resolver->servers, serv);
}
- }
- else {
- UPSTREAM_SELECT_ROUND_ROBIN (resolver->servers, serv);
- }
- if (serv == NULL) {
- rdns_warn ("cannot find suitable server for request");
- rep = rdns_make_reply (req, RDNS_RC_SERVFAIL);
- req->state = RDNS_REQUEST_REPLIED;
- req->func (rep, req->arg);
- REF_RELEASE (req);
+ if (serv == NULL) {
+ rdns_warn ("cannot find suitable server for request");
+ rep = rdns_make_reply (req, RDNS_RC_SERVFAIL);
+ req->state = RDNS_REQUEST_REPLIED;
+ req->func (rep, req->arg);
+ REF_RELEASE (req);
- return;
- }
+ return;
+ }
- /* Select random IO channel */
- req->io = serv->io_channels[ottery_rand_uint32 () % serv->io_cnt];
- req->io->uses ++;
- REF_RETAIN (req->io);
- renew = true;
+ /* Select random IO channel */
+ req->io = serv->io_channels[ottery_rand_uint32 () % serv->io_cnt];
+ req->io->uses ++;
+ REF_RETAIN (req->io);
+ renew = true;
+ }
}
/*