From: Baptiste Assmann Date: Wed, 2 Nov 2016 21:58:18 +0000 (+0100) Subject: MAJOR: dns: runtime resolution can change server admin state X-Git-Tag: v1.7-dev6~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b9fe9f8f4f88ae5f753354d7266048124e1a55a;p=thirdparty%2Fhaproxy.git MAJOR: dns: runtime resolution can change server admin state WARNING: this is a MAJOR (and disruptive) change with previous HAProxy's behavior: before, HAProxy never ever used to change a server administrative status when the DNS resolution failed at run time. This patch gives HAProxy the ability to change the administrative status of a server to MAINT (RMAINT actually) when an error is encountered for a period longer than its own allowed by the corresponding 'hold' parameter. IE if the configuration sets "hold nx 10s" and a server's hostname points to a NX for more than 10s, then the server will be set to RMAINT, hence in MAINTENANCE mode. --- diff --git a/src/server.c b/src/server.c index cf58918384..f2e419daec 100644 --- a/src/server.c +++ b/src/server.c @@ -2845,6 +2845,9 @@ out: int snr_update_srv_status(struct server *s) { struct dns_resolution *resolution = s->resolution; + struct dns_resolvers *resolvers; + + resolvers = resolution->resolvers; switch (resolution->status) { case RSLV_STATUS_NONE: @@ -2852,7 +2855,59 @@ int snr_update_srv_status(struct server *s) trigger_resolution(s); break; + case RSLV_STATUS_VALID: + /* + * resume health checks + * server will be turned back on if health check is safe + */ + if (!(s->admin & SRV_ADMF_RMAINT)) + return 1; + srv_clr_admin_flag(s, SRV_ADMF_RMAINT); + chunk_printf(&trash, "Server %s/%s administratively READY thanks to valid DNS answer", + s->proxy->id, s->id); + + Warning("%s.\n", trash.str); + send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str); + return 0; + + case RSLV_STATUS_NX: + /* stop server if resolution is NX for a long enough period */ + if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.nx), now_ms)) { + if (s->admin & SRV_ADMF_RMAINT) + return 1; + srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS NX status"); + return 0; + } + break; + + case RSLV_STATUS_TIMEOUT: + /* stop server if resolution is TIMEOUT for a long enough period */ + if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.timeout), now_ms)) { + if (s->admin & SRV_ADMF_RMAINT) + return 1; + srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS timeout status"); + return 0; + } + break; + + case RSLV_STATUS_REFUSED: + /* stop server if resolution is REFUSED for a long enough period */ + if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.refused), now_ms)) { + if (s->admin & SRV_ADMF_RMAINT) + return 1; + srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS refused status"); + return 0; + } + break; + default: + /* stop server if resolution is in unmatched error for a long enough period */ + if (tick_is_expired(tick_add(resolution->last_status_change, resolvers->hold.other), now_ms)) { + if (s->admin & SRV_ADMF_RMAINT) + return 1; + srv_set_admin_flag(s, SRV_ADMF_RMAINT, "unspecified DNS error"); + return 0; + } break; }