BUG/MEDIUM: resolvers: Properly stop server resolutions on soft-stop

When HAproxy is stopping, the DNS resolutions must be stopped, except those
triggered from a "do-resolve" action. To do so, the resolutions themselves
cannot be destroyed, the current design is too complex. However, it is
possible to mute the resolvers tasks. The same is already performed with the
health-checks. On soft-stop, the tasks are still running periodically but
nothing if performed.

For the resolvers, when the process is stopping, before running a
resolution, we check all the requesters attached to this resolution. If t
least a request is a stream or if there is a requester attached to a running
proxy, a new resolution is triggered. Otherwise, we ignored the
resolution. It will be evaluated again on the next wakeup. This way,
"do-resolv" action are still working during soft-stop but other resoluation
are stopped.

Of course, it may be see as a feature and not a bug because it was never
performed. But it is in fact not expected at all to still performing
resolutions when HAProxy is stopping. In addution, a proxy option will be
added to change this behavior.

This patch partially fixes the issue #1874. It could be backported to 2.7
and maybe to 2.6. But no further.
diff --git a/src/resolvers.c b/src/resolvers.c
index 0524c63..0b78faf 100644
--- a/src/resolvers.c
+++ b/src/resolvers.c
@@ -2394,6 +2394,48 @@
 
 	/* Handle all resolutions in the wait list */
 	list_for_each_entry_safe(res, resback, &resolvers->resolutions.wait, list) {
+
+		if (unlikely(stopping)) {
+			/* If haproxy is stopping, check if the resolution to know if it must be run or not.
+			 * If at least a requester is a stream (because of a do-resolv action) or if there
+			 * is a requester attached to a running proxy, the resolution is performed.
+			 * Otherwise, it is skipped for now.
+			 */
+			struct resolv_requester *req;
+			int must_run = 0;
+
+			list_for_each_entry(req, &res->requesters, list) {
+				struct proxy *px = NULL;
+
+				switch (obj_type(req->owner)) {
+					case OBJ_TYPE_SERVER:
+						px = __objt_server(req->owner)->proxy;
+						break;
+					case OBJ_TYPE_SRVRQ:
+						px = __objt_resolv_srvrq(req->owner)->proxy;
+						break;
+					case OBJ_TYPE_STREAM:
+						/* Always perform the resolution */
+						must_run = 1;
+						break;
+					default:
+						break;
+				}
+				/* Perform the resolution if the proxy is not stopped or disabled */
+				if (px && !(px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
+					must_run = 1;
+
+				if (must_run)
+					break;
+			}
+
+			if (!must_run) {
+				/* Skip the reolsution. reset it and wait for the next wakeup */
+				resolv_reset_resolution(res);
+				continue;
+			}
+		}
+
 		if (LIST_ISEMPTY(&res->requesters)) {
 			abort_resolution(res);
 			continue;