mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
BUG/MINOR: resolvers: answser item list was randomly purged or errors
In case of SRV records, The answer item list was purged by the error callback of the first requester which considers the error could not be safely ignored. It makes this item list unavailable for subsequent requesters even if they consider the error could be ignored. On A resolution or do_resolve action error, the answer items were never trashed. This patch re-work the error callbacks and the code to check the return code If a callback return 1, we consider the error was ignored and the answer item list must be kept. At the opposite, If all error callbacks of all requesters of the same resolution returns 0 the list will be purged This patch should be backported as far as 2.0.
This commit is contained in:
parent
0fe1864f7d
commit
12ca658dbe
@ -157,6 +157,12 @@ int act_resolution_cb(struct resolv_requester *requester, struct dns_counters *c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do resolve error management callback
|
||||||
|
* returns:
|
||||||
|
* 0 if we can trash answser items.
|
||||||
|
* 1 when safely ignored and we must kept answer items
|
||||||
|
*/
|
||||||
int act_resolution_error_cb(struct resolv_requester *requester, int error_code)
|
int act_resolution_error_cb(struct resolv_requester *requester, int error_code)
|
||||||
{
|
{
|
||||||
struct stream *stream;
|
struct stream *stream;
|
||||||
|
@ -1900,6 +1900,7 @@ static int resolv_process_responses(struct dns_nameserver *ns)
|
|||||||
unsigned short query_id;
|
unsigned short query_id;
|
||||||
struct eb32_node *eb;
|
struct eb32_node *eb;
|
||||||
struct resolv_requester *req;
|
struct resolv_requester *req;
|
||||||
|
int keep_answer_items;
|
||||||
|
|
||||||
resolvers = ns->parent;
|
resolvers = ns->parent;
|
||||||
HA_SPIN_LOCK(DNS_LOCK, &resolvers->lock);
|
HA_SPIN_LOCK(DNS_LOCK, &resolvers->lock);
|
||||||
@ -2034,8 +2035,11 @@ static int resolv_process_responses(struct dns_nameserver *ns)
|
|||||||
goto report_res_success;
|
goto report_res_success;
|
||||||
|
|
||||||
report_res_error:
|
report_res_error:
|
||||||
|
keep_answer_items = 0;
|
||||||
list_for_each_entry(req, &res->requesters, list)
|
list_for_each_entry(req, &res->requesters, list)
|
||||||
req->requester_error_cb(req, dns_resp);
|
keep_answer_items |= req->requester_error_cb(req, dns_resp);
|
||||||
|
if (!keep_answer_items)
|
||||||
|
resolv_purge_resolution_answer_records(res);
|
||||||
resolv_reset_resolution(res);
|
resolv_reset_resolution(res);
|
||||||
LIST_DELETE(&res->list);
|
LIST_DELETE(&res->list);
|
||||||
LIST_APPEND(&resolvers->resolutions.wait, &res->list);
|
LIST_APPEND(&resolvers->resolutions.wait, &res->list);
|
||||||
@ -2097,12 +2101,15 @@ static struct task *process_resolvers(struct task *t, void *context, unsigned in
|
|||||||
* the list */
|
* the list */
|
||||||
if (!res->try) {
|
if (!res->try) {
|
||||||
struct resolv_requester *req;
|
struct resolv_requester *req;
|
||||||
|
int keep_answer_items = 0;
|
||||||
|
|
||||||
/* Notify the result to the requesters */
|
/* Notify the result to the requesters */
|
||||||
if (!res->nb_responses)
|
if (!res->nb_responses)
|
||||||
res->status = RSLV_STATUS_TIMEOUT;
|
res->status = RSLV_STATUS_TIMEOUT;
|
||||||
list_for_each_entry(req, &res->requesters, list)
|
list_for_each_entry(req, &res->requesters, list)
|
||||||
req->requester_error_cb(req, res->status);
|
keep_answer_items |= req->requester_error_cb(req, res->status);
|
||||||
|
if (!keep_answer_items)
|
||||||
|
resolv_purge_resolution_answer_records(res);
|
||||||
|
|
||||||
/* Clean up resolution info and remove it from the
|
/* Clean up resolution info and remove it from the
|
||||||
* current list */
|
* current list */
|
||||||
|
23
src/server.c
23
src/server.c
@ -3436,8 +3436,8 @@ int snr_resolution_cb(struct resolv_requester *requester, struct dns_counters *c
|
|||||||
/*
|
/*
|
||||||
* SRV record error management callback
|
* SRV record error management callback
|
||||||
* returns:
|
* returns:
|
||||||
* 0 on error
|
* 0 if we can trash answser items.
|
||||||
* 1 when no error or safe ignore
|
* 1 when safely ignored and we must kept answer items
|
||||||
*
|
*
|
||||||
* Grabs the server's lock.
|
* Grabs the server's lock.
|
||||||
*/
|
*/
|
||||||
@ -3452,7 +3452,7 @@ int srvrq_resolution_error_cb(struct resolv_requester *requester, int error_code
|
|||||||
/* SRV records */
|
/* SRV records */
|
||||||
srvrq = objt_resolv_srvrq(requester->owner);
|
srvrq = objt_resolv_srvrq(requester->owner);
|
||||||
if (!srvrq)
|
if (!srvrq)
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
resolvers = srvrq->resolvers;
|
resolvers = srvrq->resolvers;
|
||||||
res = requester->resolution;
|
res = requester->resolution;
|
||||||
@ -3502,16 +3502,14 @@ int srvrq_resolution_error_cb(struct resolv_requester *requester, int error_code
|
|||||||
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
|
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolv_purge_resolution_answer_records(res);
|
return 0;
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Server Name Resolution error management callback
|
* Server Name Resolution error management callback
|
||||||
* returns:
|
* returns:
|
||||||
* 0 on error
|
* 0 if we can trash answser items.
|
||||||
* 1 when no error or safe ignore
|
* 1 when safely ignored and we must kept answer items
|
||||||
*
|
*
|
||||||
* Grabs the server's lock.
|
* Grabs the server's lock.
|
||||||
*/
|
*/
|
||||||
@ -3521,11 +3519,16 @@ int snr_resolution_error_cb(struct resolv_requester *requester, int error_code)
|
|||||||
|
|
||||||
s = objt_server(requester->owner);
|
s = objt_server(requester->owner);
|
||||||
if (!s)
|
if (!s)
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
|
HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
|
||||||
if (!snr_update_srv_status(s, 1))
|
if (!snr_update_srv_status(s, 1)) {
|
||||||
memset(&s->addr, 0, sizeof(s->addr));
|
memset(&s->addr, 0, sizeof(s->addr));
|
||||||
|
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
|
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user