summaryrefslogtreecommitdiff
path: root/sbin/unwind
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2019-11-14 08:32:31 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2019-11-14 08:32:31 +0000
commit41dff51c79fd37dda973dd31745e0ad6cbb65357 (patch)
treec6b269922b29d7303631db8af184fd2ca1171613 /sbin/unwind
parente875c869adefdeaed5e57f53bc0781fe530c4225 (diff)
Checking a resolver that we are already checking can lead to a
self-DoS under high query rate and constant failures.
Diffstat (limited to 'sbin/unwind')
-rw-r--r--sbin/unwind/resolver.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c
index cc2939c44d6..c525e72e55a 100644
--- a/sbin/unwind/resolver.c
+++ b/sbin/unwind/resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolver.c,v 1.63 2019/11/14 08:30:10 florian Exp $ */
+/* $OpenBSD: resolver.c,v 1.64 2019/11/14 08:32:30 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -88,6 +88,7 @@ struct uw_resolver {
enum uw_resolver_state state;
enum uw_resolver_type type;
int oppdot;
+ int check_running;
char *why_bogus;
int64_t histogram[nitems(histogram_limits)];
};
@@ -1258,6 +1259,12 @@ check_resolver(struct uw_resolver *resolver_to_check)
{
struct uw_resolver *res;
+ if (resolver_to_check->check_running) {
+ log_debug("%s: already checking: %s", __func__,
+ uw_resolver_type_str[resolver_to_check->type]);
+ return;
+ }
+
log_debug("%s: create_resolver", __func__);
if ((res = create_resolver(resolver_to_check->type, 0)) == NULL)
fatal("%s", __func__);
@@ -1276,7 +1283,8 @@ check_resolver(struct uw_resolver *resolver_to_check)
resolver_to_check->check_tv.tv_sec,
uw_resolver_type_str[resolver_to_check->type],
uw_resolver_state_str[resolver_to_check->state]);
- }
+ } else
+ resolver_to_check->check_running++;
if (!(resolver_to_check->type == UW_RES_DHCP ||
resolver_to_check->type == UW_RES_FORWARDER))
@@ -1302,7 +1310,8 @@ check_resolver(struct uw_resolver *resolver_to_check)
resolver_to_check->check_tv.tv_sec,
uw_resolver_type_str[resolver_to_check->type],
uw_resolver_state_str[resolver_to_check->state]);
- }
+ } else
+ resolver_to_check->check_running++;
}
void
@@ -1314,6 +1323,8 @@ check_resolver_done(struct uw_resolver *res, void *arg, int rcode,
enum uw_resolver_state prev_state;
char *str;
+ checked_resolver->check_running--;
+
log_debug("%s: %s rcode: %d", __func__,
uw_resolver_type_str[checked_resolver->type], rcode);