This patch fixes the issue reported by David in github issue 227.
Basically, when the task is woken up by the scheduler because there is some
data in the request body, then it mistakenly understand there is nothing to
do and so cleans up the resolution and tell the scheduler it's done with
its tasks.
This patch now check if the associated resolution is still in RUNNING state
and tell the scheduler to wake it up later if this is the case.

From 53461e0e39cbba85adca545c33497e944f0ee426 Mon Sep 17 00:00:00 2001
From: Baptiste Assmann <bed...@gmail.com>
Date: Tue, 1 Oct 2019 15:32:40 +0200
Subject: [PATCH] BUG/MINOR: action: do-resolve does not yield on requests with

@davidmogar reported a github issue (#227) about problems with
do-resolve action when the request contains a body.
The variable was never populated in such case, despite tcpdump shows a
valid DNS response coming back.

The do-resolve action is a task in HAProxy and so it's waken by the
scheduler each time the scheduler think such task may have some work to
When a simple HTTP request is sent, then the task is called, it sends
the DNS request, then the scheduler will wake up the task again later
once the DNS response is there.
Now, when the client send a PUT or a POST request (or any other type)
with a BODY, then the do-resolve action if first waken up once the
headers are processed. It sends the DNS request. Then, when the bytes
for the body are processed by HAProxy AND the DNS response has not yet
been received, then the action simply terminates and cleans up all the
data associated to this resolution...

This patch detect such behavior and if the action is now waken up while
a DNS resolution is in RUNNING state, then the action will tell the
scheduler to wake it up again later.

Backport status: 2.0 and above
 src/dns.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/dns.c b/src/dns.c
index ef840e50c..0ce6e8302 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -2150,6 +2150,9 @@ enum act_return dns_action_do_resolve(struct act_rule *rule, struct proxy *px,
 	/* we have a response to our DNS resolution */
 	if (s->dns_ctx.dns_requester && s->dns_ctx.dns_requester->resolution != NULL) {
 		resolution = s->dns_ctx.dns_requester->resolution;
+		if (resolution->step == RSLV_STEP_RUNNING) {
+			return ACT_RET_YIELD;
+		}
 		if (resolution->step == RSLV_STEP_NONE) {
 			/* We update the variable only if we have a valid response. */
 			if (resolution->status == RSLV_STATUS_VALID) {

Reply via email to