mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
BUG/MINOR: dns: add tempo between 2 connection attempts for dns servers
As reported by Lukas Tribus on the mailing list [1], trying to connect to a nameserver with invalid network settings causes haproxy to retry a new connection attempt immediately which eventually causes unexpected CPU usage on the thread responsible for the applet (namely 100% on one CPU will be observed). This can be reproduced with the test config below: resolvers default nameserver ns1 tcp4@8.8.8.8:53 source 192.168.99.99 listen listen mode http bind :8080 server s1 www.google.com resolvers default init-addr none To fix this the issue, we add a temporisation of one second between a new connection attempt is retried. We do this in dns_session_create() when we know that the applet was created in the release callback (when previous query attempt was unsuccessful), which means initial connection is not affected. [1]: https://www.mail-archive.com/haproxy@formilux.org/msg45665.html This should fix GH #2909 and may be backported to all stable versions. This patch depends on ("MINOR: applet: add appctx_schedule() macro")
This commit is contained in:
parent
1ced5ef2fd
commit
27236f2218
14
src/dns.c
14
src/dns.c
@ -806,7 +806,7 @@ void dns_session_free(struct dns_session *ds)
|
|||||||
pool_free(dns_session_pool, ds);
|
pool_free(dns_session_pool, ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct appctx *dns_session_create(struct dns_session *ds);
|
static struct appctx *dns_session_create(struct dns_session *ds, int tempo);
|
||||||
|
|
||||||
static int dns_session_init(struct appctx *appctx)
|
static int dns_session_init(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
@ -912,7 +912,7 @@ static void dns_session_release(struct appctx *appctx)
|
|||||||
|
|
||||||
/* Create a new appctx, We hope we can
|
/* Create a new appctx, We hope we can
|
||||||
* create from the release callback! */
|
* create from the release callback! */
|
||||||
ds->appctx = dns_session_create(ds);
|
ds->appctx = dns_session_create(ds, 1);
|
||||||
if (!ds->appctx) {
|
if (!ds->appctx) {
|
||||||
dns_session_free(ds);
|
dns_session_free(ds);
|
||||||
HA_SPIN_UNLOCK(DNS_LOCK, &dss->lock);
|
HA_SPIN_UNLOCK(DNS_LOCK, &dss->lock);
|
||||||
@ -937,8 +937,10 @@ static struct applet dns_session_applet = {
|
|||||||
/*
|
/*
|
||||||
* Function used to create an appctx for a DNS session
|
* Function used to create an appctx for a DNS session
|
||||||
* It sets its context into appctx->svcctx.
|
* It sets its context into appctx->svcctx.
|
||||||
|
* if <tempo> is set, then the session startup will be delayed by 1
|
||||||
|
* second
|
||||||
*/
|
*/
|
||||||
static struct appctx *dns_session_create(struct dns_session *ds)
|
static struct appctx *dns_session_create(struct dns_session *ds, int tempo)
|
||||||
{
|
{
|
||||||
struct appctx *appctx;
|
struct appctx *appctx;
|
||||||
|
|
||||||
@ -947,10 +949,14 @@ static struct appctx *dns_session_create(struct dns_session *ds)
|
|||||||
goto out_close;
|
goto out_close;
|
||||||
appctx->svcctx = (void *)ds;
|
appctx->svcctx = (void *)ds;
|
||||||
|
|
||||||
|
if (!tempo) {
|
||||||
if (appctx_init(appctx) == -1) {
|
if (appctx_init(appctx) == -1) {
|
||||||
ha_alert("out of memory in dns_session_create().\n");
|
ha_alert("out of memory in dns_session_create().\n");
|
||||||
goto out_free_appctx;
|
goto out_free_appctx;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
appctx_schedule(appctx, tick_add(now_ms, MS_TO_TICKS(1000)));
|
||||||
|
|
||||||
return appctx;
|
return appctx;
|
||||||
|
|
||||||
@ -1072,7 +1078,7 @@ struct dns_session *dns_session_new(struct dns_stream_server *dss)
|
|||||||
ds->task_exp->process = dns_process_query_exp;
|
ds->task_exp->process = dns_process_query_exp;
|
||||||
ds->task_exp->context = ds;
|
ds->task_exp->context = ds;
|
||||||
|
|
||||||
ds->appctx = dns_session_create(ds);
|
ds->appctx = dns_session_create(ds, 0);
|
||||||
if (!ds->appctx)
|
if (!ds->appctx)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user