commit ff7f417: [Fix] Allow real upstreams configuration

Vsevolod Stakhov vsevolod at highsecure.ru
Fri Nov 1 14:35:07 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-11-01 14:29:57 +0000
URL: https://github.com/rspamd/rspamd/commit/ff7f417bffb844100606c17162bf70a2880db223 (HEAD -> master)

[Fix] Allow real upstreams configuration

---
 src/libutil/upstream.c | 104 +++++++++++++++++++++++++------------------------
 src/libutil/upstream.h |   2 +
 2 files changed, 56 insertions(+), 50 deletions(-)

diff --git a/src/libutil/upstream.c b/src/libutil/upstream.c
index 69f1ed9e4..1f7bd1541 100644
--- a/src/libutil/upstream.c
+++ b/src/libutil/upstream.c
@@ -96,7 +96,7 @@ struct upstream_list {
 	GPtrArray *alive;
 	struct upstream_list_watcher *watchers;
 	guint64 hash_seed;
-	struct upstream_limits limits;
+	const struct upstream_limits *limits;
 	enum rspamd_upstream_flag flags;
 	guint cur_elt;
 	enum rspamd_upstream_rotation rot_alg;
@@ -131,14 +131,24 @@ struct upstream_ctx {
 INIT_LOG_MODULE(upstream)
 
 /* 4 errors in 10 seconds */
-static guint default_max_errors = 4;
-static gdouble default_revive_time = 60;
-static gdouble default_revive_jitter = 0.4;
-static gdouble default_error_time = 10;
-static gdouble default_dns_timeout = 1.0;
-static guint default_dns_retransmits = 2;
+static const guint default_max_errors = 4;
+static const gdouble default_revive_time = 60;
+static const gdouble default_revive_jitter = 0.4;
+static const gdouble default_error_time = 10;
+static const gdouble default_dns_timeout = 1.0;
+static const guint default_dns_retransmits = 2;
 /* TODO: make it configurable */
-static gdouble default_lazy_resolve_time = 3600.0;
+static const gdouble default_lazy_resolve_time = 3600.0;
+
+static const struct upstream_limits default_limits = {
+		.revive_time = default_revive_time,
+		.revive_jitter = default_revive_jitter,
+		.error_time = default_error_time,
+		.dns_timeout = default_dns_timeout,
+		.dns_retransmits = default_dns_retransmits,
+		.max_errors = default_max_errors,
+		.lazy_resolve_time = default_lazy_resolve_time,
+};
 
 static void rspamd_upstream_lazy_resolve_cb (struct ev_loop *, ev_timer *, int );
 
@@ -192,8 +202,8 @@ rspamd_upstreams_library_config (struct rspamd_config *cfg,
 					when = 0.0;
 				}
 				else {
-					when = rspamd_time_jitter (upstream->ls->limits.lazy_resolve_time,
-							upstream->ls->limits.lazy_resolve_time * .1);
+					when = rspamd_time_jitter (upstream->ls->limits->lazy_resolve_time,
+							upstream->ls->limits->lazy_resolve_time * .1);
 				}
 
 				ev_timer_init (&upstream->ev, rspamd_upstream_lazy_resolve_cb,
@@ -239,13 +249,7 @@ rspamd_upstreams_library_init (void)
 	struct upstream_ctx *ctx;
 
 	ctx = g_malloc0 (sizeof (*ctx));
-	ctx->limits.error_time = default_error_time;
-	ctx->limits.max_errors = default_max_errors;
-	ctx->limits.dns_retransmits = default_dns_retransmits;
-	ctx->limits.dns_timeout = default_dns_timeout;
-	ctx->limits.revive_jitter = default_revive_jitter;
-	ctx->limits.revive_time = default_revive_time;
-	ctx->limits.lazy_resolve_time = default_lazy_resolve_time;
+	memcpy (&ctx->limits, &default_limits, sizeof (ctx->limits));
 	ctx->pool = rspamd_mempool_new (rspamd_mempool_suggest_size (),
 			"upstreams");
 
@@ -320,8 +324,8 @@ rspamd_upstream_set_active (struct upstream_list *ls, struct upstream *upstream)
 			when = 0.0;
 		}
 		else {
-			when = rspamd_time_jitter (upstream->ls->limits.lazy_resolve_time,
-					upstream->ls->limits.lazy_resolve_time * .1);
+			when = rspamd_time_jitter (upstream->ls->limits->lazy_resolve_time,
+					upstream->ls->limits->lazy_resolve_time * .1);
 		}
 		ev_timer_init (&upstream->ev, rspamd_upstream_lazy_resolve_cb,
 				when, 0);
@@ -559,8 +563,8 @@ rspamd_upstream_dns_srv_cb (struct rdns_reply *reply, void *arg)
 
 				if (rdns_make_request_full (upstream->ctx->res,
 						rspamd_upstream_dns_srv_phase2_cb, ncbdata,
-						upstream->ls->limits.dns_timeout,
-						upstream->ls->limits.dns_retransmits,
+						upstream->ls->limits->dns_timeout,
+						upstream->ls->limits->dns_retransmits,
 						1, entry->content.srv.target, RDNS_REQUEST_A) != NULL) {
 					upstream->dns_requests++;
 					REF_RETAIN (upstream);
@@ -569,8 +573,8 @@ rspamd_upstream_dns_srv_cb (struct rdns_reply *reply, void *arg)
 
 				if (rdns_make_request_full (upstream->ctx->res,
 						rspamd_upstream_dns_srv_phase2_cb, ncbdata,
-						upstream->ls->limits.dns_timeout,
-						upstream->ls->limits.dns_retransmits,
+						upstream->ls->limits->dns_timeout,
+						upstream->ls->limits->dns_retransmits,
 						1, entry->content.srv.target, RDNS_REQUEST_AAAA) != NULL) {
 					upstream->dns_requests++;
 					REF_RETAIN (upstream);
@@ -623,7 +627,7 @@ rspamd_upstream_resolve_addrs (const struct upstream_list *ls,
 			if (up->flags & RSPAMD_UPSTREAM_FLAG_SRV_RESOLVE) {
 				if (rdns_make_request_full (up->ctx->res,
 						rspamd_upstream_dns_srv_cb, up,
-						ls->limits.dns_timeout, ls->limits.dns_retransmits,
+						ls->limits->dns_timeout, ls->limits->dns_retransmits,
 						1, up->name, RDNS_REQUEST_SRV) != NULL) {
 					up->dns_requests++;
 					REF_RETAIN (up);
@@ -632,7 +636,7 @@ rspamd_upstream_resolve_addrs (const struct upstream_list *ls,
 			else {
 				if (rdns_make_request_full (up->ctx->res,
 						rspamd_upstream_dns_cb, up,
-						ls->limits.dns_timeout, ls->limits.dns_retransmits,
+						ls->limits->dns_timeout, ls->limits->dns_retransmits,
 						1, up->name, RDNS_REQUEST_A) != NULL) {
 					up->dns_requests++;
 					REF_RETAIN (up);
@@ -640,7 +644,7 @@ rspamd_upstream_resolve_addrs (const struct upstream_list *ls,
 
 				if (rdns_make_request_full (up->ctx->res,
 						rspamd_upstream_dns_cb, up,
-						ls->limits.dns_timeout, ls->limits.dns_retransmits,
+						ls->limits->dns_timeout, ls->limits->dns_retransmits,
 						1, up->name, RDNS_REQUEST_AAAA) != NULL) {
 					up->dns_requests++;
 					REF_RETAIN (up);
@@ -661,9 +665,9 @@ rspamd_upstream_lazy_resolve_cb (struct ev_loop *loop, ev_timer *w, int revents)
 	if (up->ls) {
 		rspamd_upstream_resolve_addrs (up->ls, up);
 
-		if (up->ttl == 0 || up->ttl > up->ls->limits.lazy_resolve_time) {
-			w->repeat = rspamd_time_jitter (up->ls->limits.lazy_resolve_time,
-					up->ls->limits.lazy_resolve_time * .1);
+		if (up->ttl == 0 || up->ttl > up->ls->limits->lazy_resolve_time) {
+			w->repeat = rspamd_time_jitter (up->ls->limits->lazy_resolve_time,
+					up->ls->limits->lazy_resolve_time * .1);
 		}
 		else {
 			w->repeat = up->ttl;
@@ -697,8 +701,8 @@ rspamd_upstream_set_inactive (struct upstream_list *ls, struct upstream *upstrea
 		rspamd_upstream_resolve_addrs (ls, upstream);
 
 		REF_RETAIN (upstream);
-		ntim = rspamd_time_jitter (ls->limits.revive_time,
-				ls->limits.revive_jitter);
+		ntim = rspamd_time_jitter (ls->limits->revive_time,
+				ls->limits->revive_time * ls->limits->revive_jitter);
 
 		if (ev_can_stop (&upstream->ev)) {
 			ev_timer_stop (upstream->ctx->event_loop, &upstream->ev);
@@ -760,10 +764,10 @@ rspamd_upstream_fail (struct upstream *upstream, gboolean addr_failure)
 					}
 				}
 
-				if (sec_cur - sec_last >= upstream->ls->limits.error_time)  {
+				if (sec_cur - sec_last >= upstream->ls->limits->error_time)  {
 					error_rate = ((gdouble)upstream->errors) / (sec_cur - sec_last);
-					max_error_rate = ((gdouble)upstream->ls->limits.max_errors) /
-									 upstream->ls->limits.error_time;
+					max_error_rate = ((gdouble)upstream->ls->limits->max_errors) /
+									 upstream->ls->limits->error_time;
 				}
 
 				if (error_rate > max_error_rate) {
@@ -791,13 +795,13 @@ rspamd_upstream_fail (struct upstream *upstream, gboolean addr_failure)
 								upstream->name, error_rate, upstream->errors,
 								max_error_rate, sec_last, sec_cur);
 						/* Just re-resolve addresses */
-						if (sec_cur - sec_last > upstream->ls->limits.revive_time) {
+						if (sec_cur - sec_last > upstream->ls->limits->revive_time) {
 							upstream->errors = 0;
 							rspamd_upstream_resolve_addrs (upstream->ls, upstream);
 						}
 					}
 				}
-				else if (sec_cur - sec_last >= upstream->ls->limits.error_time) {
+				else if (sec_cur - sec_last >= upstream->ls->limits->error_time) {
 					/* Forget the whole interval */
 					upstream->last_fail = sec_cur;
 					upstream->errors = 1;
@@ -871,16 +875,10 @@ rspamd_upstreams_create (struct upstream_ctx *ctx)
 	ls->rot_alg = RSPAMD_UPSTREAM_UNDEF;
 
 	if (ctx) {
-		ls->limits = ctx->limits;
+		ls->limits = &ctx->limits;
 	}
 	else {
-		ls->limits.error_time = default_error_time;
-		ls->limits.max_errors = default_max_errors;
-		ls->limits.dns_retransmits = default_dns_retransmits;
-		ls->limits.dns_timeout = default_dns_timeout;
-		ls->limits.revive_jitter = default_revive_jitter;
-		ls->limits.revive_time = default_revive_time;
-		ls->limits.lazy_resolve_time = default_lazy_resolve_time;
+		ls->limits = &default_limits;
 	}
 
 	return ls;
@@ -1568,31 +1566,37 @@ rspamd_upstreams_set_limits (struct upstream_list *ups,
 								  guint max_errors,
 								  guint dns_retransmits)
 {
+	struct upstream_limits *nlimits;
 	g_assert (ups != NULL);
 
+	nlimits = rspamd_mempool_alloc (ups->ctx->pool, sizeof (*nlimits));
+	memcpy (nlimits, ups->limits, sizeof (*nlimits));
+
 	if (!isnan (revive_time)) {
-		ups->limits.revive_time = revive_time;
+		nlimits->revive_time = revive_time;
 	}
 
 	if (!isnan (revive_jitter)) {
-		ups->limits.revive_jitter = revive_jitter;
+		nlimits->revive_jitter = revive_jitter;
 	}
 
 	if (!isnan (error_time)) {
-		ups->limits.error_time = error_time;
+		nlimits->error_time = error_time;
 	}
 
 	if (!isnan (dns_timeout)) {
-		ups->limits.dns_timeout = dns_timeout;
+		nlimits->dns_timeout = dns_timeout;
 	}
 
 	if (max_errors > 0) {
-		ups->limits.max_errors = max_errors;
+		nlimits->max_errors = max_errors;
 	}
 
 	if (dns_retransmits > 0) {
-		ups->limits.dns_retransmits = dns_retransmits;
+		nlimits->dns_retransmits = dns_retransmits;
 	}
+
+	ups->limits = nlimits;
 }
 
 void rspamd_upstreams_add_watch_callback (struct upstream_list *ups,
diff --git a/src/libutil/upstream.h b/src/libutil/upstream.h
index d0d7374cf..4dd69e0dd 100644
--- a/src/libutil/upstream.h
+++ b/src/libutil/upstream.h
@@ -89,6 +89,8 @@ void rspamd_upstreams_set_flags (struct upstream_list *ups,
 
 /**
  * Sets custom limits for upstreams
+ * This function allocates memory from the upstreams ctx pool and should
+ * not be called in cycles/constantly as this memory is likely persistent
  * @param ups
  * @param revive_time
  * @param revive_jitter


More information about the Commits mailing list