/*
 * Server-state management functions.
 *
 * Copyright (C) 2021 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <errno.h>

#include <import/eb64tree.h>
#include <import/xxhash.h>

#include <haproxy/api.h>
#include <haproxy/backend.h>
#include <haproxy/cfgparse.h>
#include <haproxy/check.h>
#include <haproxy/errors.h>
#include <haproxy/global.h>
#include <haproxy/log.h>
#include <haproxy/port_range.h>
#include <haproxy/proxy.h>
#include <haproxy/resolvers.h>
#include <haproxy/server.h>
#include <haproxy/ssl_sock.h>


/* Update a server state using the parameters available in the params list.
 * The caller must provide a supported version
 * Grabs the server lock during operation.
 */
static void srv_state_srv_update(struct server *srv, int version, char **params)
{
	char *p;
	struct buffer *msg;
	const char *warning;

	/* fields since version 1
	 * and common to all other upcoming versions
	 */
	enum srv_state srv_op_state;
	enum srv_admin srv_admin_state;
	unsigned srv_uweight, srv_iweight;
	unsigned long srv_last_time_change;
	short srv_check_status;
	enum chk_result srv_check_result;
	int srv_check_health;
	int srv_check_state, srv_agent_state;
	int bk_f_forced_id;
	int srv_f_forced_id;
	int fqdn_set_by_cli;
	const char *fqdn;
	const char *port_st;
	unsigned int port_svc;
	char *srvrecord;
	char *addr;
	int partial_apply = 0;
#ifdef USE_OPENSSL
	int use_ssl;
#endif

	fqdn = NULL;
	port_svc = 0;
	msg = alloc_trash_chunk();
	if (!msg)
		goto end;

	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);

	/* Only version 1 supported for now, don't check it. Fields are :
	 * srv_addr:             params[0]
	 * srv_op_state:         params[1]
	 * srv_admin_state:      params[2]
	 * srv_uweight:          params[3]
	 * srv_iweight:          params[4]
	 * srv_last_time_change: params[5]
	 * srv_check_status:     params[6]
	 * srv_check_result:     params[7]
	 * srv_check_health:     params[8]
	 * srv_check_state:      params[9]
	 * srv_agent_state:      params[10]
	 * bk_f_forced_id:       params[11]
	 * srv_f_forced_id:      params[12]
	 * srv_fqdn:             params[13]
	 * srv_port:             params[14]
	 * srvrecord:            params[15]
	 * srv_use_ssl:          params[16]
	 * srv_check_port:       params[17]
	 * srv_check_addr:       params[18]
	 * srv_agent_addr:       params[19]
	 * srv_agent_port:       params[20]
	 */

	/* validating srv_op_state */
	p = NULL;
	errno = 0;
	srv_op_state = strtol(params[1], &p, 10);
	if ((p == params[1]) || errno == EINVAL || errno == ERANGE ||
	    (srv_op_state != SRV_ST_STOPPED &&
	     srv_op_state != SRV_ST_STARTING &&
	     srv_op_state != SRV_ST_RUNNING &&
	     srv_op_state != SRV_ST_STOPPING)) {
		chunk_appendf(msg, ", invalid srv_op_state value '%s'", params[1]);
	}

	/* validating srv_admin_state */
	p = NULL;
	errno = 0;
	srv_admin_state = strtol(params[2], &p, 10);
	fqdn_set_by_cli = !!(srv_admin_state & SRV_ADMF_HMAINT);

	/* inherited statuses will be recomputed later.
	 * Also disable SRV_ADMF_HMAINT flag (set from stats socket fqdn).
	 */
	srv_admin_state &= ~SRV_ADMF_IDRAIN & ~SRV_ADMF_IMAINT & ~SRV_ADMF_HMAINT & ~SRV_ADMF_RMAINT;

	if ((p == params[2]) || errno == EINVAL || errno == ERANGE ||
	    (srv_admin_state != 0 &&
	     srv_admin_state != SRV_ADMF_FMAINT &&
	     srv_admin_state != SRV_ADMF_CMAINT &&
	     srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT) &&
	     srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FDRAIN) &&
	     srv_admin_state != SRV_ADMF_FDRAIN)) {
		chunk_appendf(msg, ", invalid srv_admin_state value '%s'", params[2]);
	}

	/* validating srv_uweight */
	p = NULL;
	errno = 0;
	srv_uweight = strtol(params[3], &p, 10);
	if ((p == params[3]) || errno == EINVAL || errno == ERANGE || (srv_uweight > SRV_UWGHT_MAX))
		chunk_appendf(msg, ", invalid srv_uweight value '%s'", params[3]);

	/* validating srv_iweight */
	p = NULL;
	errno = 0;
	srv_iweight = strtol(params[4], &p, 10);
	if ((p == params[4]) || errno == EINVAL || errno == ERANGE || (srv_iweight > SRV_UWGHT_MAX))
		chunk_appendf(msg, ", invalid srv_iweight value '%s'", params[4]);

	/* validating srv_last_time_change */
	p = NULL;
	errno = 0;
	srv_last_time_change = strtol(params[5], &p, 10);
	if ((p == params[5]) || errno == EINVAL || errno == ERANGE)
		chunk_appendf(msg, ", invalid srv_last_time_change value '%s'", params[5]);

	/* validating srv_check_status */
	p = NULL;
	errno = 0;
	srv_check_status = strtol(params[6], &p, 10);
	if (p == params[6] || errno == EINVAL || errno == ERANGE ||
	    (srv_check_status >= HCHK_STATUS_SIZE))
		chunk_appendf(msg, ", invalid srv_check_status value '%s'", params[6]);

	/* validating srv_check_result */
	p = NULL;
	errno = 0;
	srv_check_result = strtol(params[7], &p, 10);
	if ((p == params[7]) || errno == EINVAL || errno == ERANGE ||
	    (srv_check_result != CHK_RES_UNKNOWN &&
	     srv_check_result != CHK_RES_NEUTRAL &&
	     srv_check_result != CHK_RES_FAILED &&
	     srv_check_result != CHK_RES_PASSED &&
	     srv_check_result != CHK_RES_CONDPASS)) {
		chunk_appendf(msg, ", invalid srv_check_result value '%s'", params[7]);
	}

	/* validating srv_check_health */
	p = NULL;
	errno = 0;
	srv_check_health = strtol(params[8], &p, 10);
	if (p == params[8] || errno == EINVAL || errno == ERANGE)
		chunk_appendf(msg, ", invalid srv_check_health value '%s'", params[8]);

	/* validating srv_check_state */
	p = NULL;
	errno = 0;
	srv_check_state = strtol(params[9], &p, 10);
	if (p == params[9] || errno == EINVAL || errno == ERANGE ||
	    (srv_check_state & ~(CHK_ST_INPROGRESS | CHK_ST_CONFIGURED | CHK_ST_ENABLED | CHK_ST_PAUSED | CHK_ST_AGENT)))
		chunk_appendf(msg, ", invalid srv_check_state value '%s'", params[9]);

	/* validating srv_agent_state */
	p = NULL;
	errno = 0;
	srv_agent_state = strtol(params[10], &p, 10);
	if (p == params[10] || errno == EINVAL || errno == ERANGE ||
	    (srv_agent_state & ~(CHK_ST_INPROGRESS | CHK_ST_CONFIGURED | CHK_ST_ENABLED | CHK_ST_PAUSED | CHK_ST_AGENT)))
		chunk_appendf(msg, ", invalid srv_agent_state value '%s'", params[10]);

	/* validating bk_f_forced_id */
	p = NULL;
	errno = 0;
	bk_f_forced_id = strtol(params[11], &p, 10);
	if (p == params[11] || errno == EINVAL || errno == ERANGE || !((bk_f_forced_id == 0) || (bk_f_forced_id == 1)))
		chunk_appendf(msg, ", invalid bk_f_forced_id value '%s'", params[11]);

	/* validating srv_f_forced_id */
	p = NULL;
	errno = 0;
	srv_f_forced_id = strtol(params[12], &p, 10);
	if (p == params[12] || errno == EINVAL || errno == ERANGE || !((srv_f_forced_id == 0) || (srv_f_forced_id == 1)))
		chunk_appendf(msg, ", invalid srv_f_forced_id value '%s'", params[12]);

	/* validating srv_fqdn */
	fqdn = params[13];
	if (fqdn && *fqdn == '-')
		fqdn = NULL;
	if (fqdn && (strlen(fqdn) > DNS_MAX_NAME_SIZE || invalid_domainchar(fqdn))) {
		chunk_appendf(msg, ", invalid srv_fqdn value '%s'", params[13]);
		fqdn = NULL;
	}

	port_st = params[14];
	if (port_st) {
		port_svc = strl2uic(port_st, strlen(port_st));
		if (port_svc > USHRT_MAX) {
			chunk_appendf(msg, ", invalid srv_port value '%s'", port_st);
			port_st = NULL;
		}
	}

	/* SRV record
	 * NOTE: in HAProxy, SRV records must start with an underscore '_'
	 */
	srvrecord = params[15];
	if (srvrecord && *srvrecord != '_')
		srvrecord = NULL;

	/* don't apply anything if one error has been detected */
	if (msg->data)
		goto out;
	partial_apply = 1;

	/* recover operational state and apply it to this server
	 * and all servers tracking this one */
	srv->check.health = srv_check_health;
	switch (srv_op_state) {
		case SRV_ST_STOPPED:
			srv->check.health = 0;
			srv_set_stopped(srv, "changed from server-state after a reload", NULL);
			break;
		case SRV_ST_STARTING:
			/* If rise == 1 there is no STARTING state, let's switch to
			 * RUNNING
			 */
			if (srv->check.rise == 1) {
				srv->check.health = srv->check.rise + srv->check.fall - 1;
				srv_set_running(srv, "", NULL);
				break;
			}
			if (srv->check.health < 1 || srv->check.health >= srv->check.rise)
				srv->check.health = srv->check.rise - 1;
			srv->next_state = srv_op_state;
			break;
		case SRV_ST_STOPPING:
			/* If fall == 1 there is no STOPPING state, let's switch to
			 * STOPPED
			 */
			if (srv->check.fall == 1) {
				srv->check.health = 0;
				srv_set_stopped(srv, "changed from server-state after a reload", NULL);
				break;
			}
			if (srv->check.health < srv->check.rise ||
			    srv->check.health > srv->check.rise + srv->check.fall - 2)
				srv->check.health = srv->check.rise;
			srv_set_stopping(srv, "changed from server-state after a reload", NULL);
			break;
		case SRV_ST_RUNNING:
			srv->check.health = srv->check.rise + srv->check.fall - 1;
			srv_set_running(srv, "", NULL);
			break;
	}

	/* When applying server state, the following rules apply:
	 * - in case of a configuration change, we apply the setting from the new
	 *   configuration, regardless of old running state
	 * - if no configuration change, we apply old running state only if old running
	 *   state is different from new configuration state
	 */
	/* configuration has changed */
	if ((srv_admin_state & SRV_ADMF_CMAINT) != (srv->next_admin & SRV_ADMF_CMAINT)) {
		if (srv->next_admin & SRV_ADMF_CMAINT)
			srv_adm_set_maint(srv);
		else
			srv_adm_set_ready(srv);
	}
	/* configuration is the same, let's compate old running state and new conf state */
	else {
		if (srv_admin_state & SRV_ADMF_FMAINT && !(srv->next_admin & SRV_ADMF_CMAINT))
			srv_adm_set_maint(srv);
		else if (!(srv_admin_state & SRV_ADMF_FMAINT) && (srv->next_admin & SRV_ADMF_CMAINT))
			srv_adm_set_ready(srv);
	}
	/* apply drain mode if server is currently enabled */
	if (!(srv->next_admin & SRV_ADMF_FMAINT) && (srv_admin_state & SRV_ADMF_FDRAIN)) {
		/* The SRV_ADMF_FDRAIN flag is inherited when srv->iweight is 0
		 * (srv->iweight is the weight set up in configuration).
		 * There are two possible reasons for FDRAIN to have been present :
		 *   - previous config weight was zero
		 *   - "set server b/s drain" was sent to the CLI
		 *
		 * In the first case, we simply want to drop this drain state
		 * if the new weight is not zero anymore, meaning the administrator
		 * has intentionally turned the weight back to a positive value to
		 * enable the server again after an operation. In the second case,
		 * the drain state was forced on the CLI regardless of the config's
		 * weight so we don't want a change to the config weight to lose this
		 * status. What this means is :
		 *   - if previous weight was 0 and new one is >0, drop the DRAIN state.
		 *   - if the previous weight was >0, keep it.
		 */
		if (srv_iweight > 0 || srv->iweight == 0)
			srv_adm_set_drain(srv);
	}

	srv->last_change = date.tv_sec - srv_last_time_change;
	srv->check.status = srv_check_status;
	srv->check.result = srv_check_result;

	/* Only case we want to apply is removing ENABLED flag which could have been
	 * done by the "disable health" command over the stats socket
	 */
	if ((srv->check.state & CHK_ST_CONFIGURED) &&
	    (srv_check_state & CHK_ST_CONFIGURED) &&
	    !(srv_check_state & CHK_ST_ENABLED))
		srv->check.state &= ~CHK_ST_ENABLED;

	/* Only case we want to apply is removing ENABLED flag which could have been
	 * done by the "disable agent" command over the stats socket
	 */
	if ((srv->agent.state & CHK_ST_CONFIGURED) &&
	    (srv_agent_state & CHK_ST_CONFIGURED) &&
	    !(srv_agent_state & CHK_ST_ENABLED))
		srv->agent.state &= ~CHK_ST_ENABLED;

	/* We want to apply the previous 'running' weight (srv_uweight) only if there
	 * was no change in the configuration: both previous and new iweight are equals
	 *
	 * It means that a configuration file change has precedence over a unix socket change
	 * for server's weight
	 *
	 * by default, HAProxy applies the following weight when parsing the configuration
	 *    srv->uweight = srv->iweight
	 */
	if (srv_iweight == srv->iweight) {
		srv->uweight = srv_uweight;
	}
	server_recalc_eweight(srv, 1);

	/* load server IP address */
	if (strcmp(params[0], "-") != 0)
		srv->lastaddr = strdup(params[0]);

	if (fqdn && srv->hostname) {
		if (strcmp(srv->hostname, fqdn) == 0) {
			/* Here we reset the 'set from stats socket FQDN' flag
			 * to support such transitions:
			 * Let's say initial FQDN value is foo1 (in configuration file).
			 * - FQDN changed from stats socket, from foo1 to foo2 value,
			 * - FQDN changed again from file configuration (with the same previous value
			 set from stats socket, from foo1 to foo2 value),
			 * - reload for any other reason than a FQDN modification,
			 * the configuration file FQDN matches the fqdn server state file value.
			 * So we must reset the 'set from stats socket FQDN' flag to be consistent with
			 * any further FQDN modification.
			 */
			srv->next_admin &= ~SRV_ADMF_HMAINT;
		}
		else {
			/* If the FDQN has been changed from stats socket,
			 * apply fqdn state file value (which is the value set
			 * from stats socket).
			 * Also ensure the runtime resolver will process this resolution.
			 */
			if (fqdn_set_by_cli) {
				srv_set_fqdn(srv, fqdn, 0);
				srv->flags &= ~SRV_F_NO_RESOLUTION;
				srv->next_admin |= SRV_ADMF_HMAINT;
			}
		}
	}
	/* If all the conditions below are validated, this means
	 * we're evaluating a server managed by SRV resolution
	 */
	else if (fqdn && !srv->hostname && srvrecord) {
		int res;

		/* we can't apply previous state if SRV record has changed */
		if (srv->srvrq && strcmp(srv->srvrq->name, srvrecord) != 0) {
			chunk_appendf(msg, ", SRV record mismatch between configuration ('%s') and state file ('%s) for server '%s'. Previous state not applied", srv->srvrq->name, srvrecord, srv->id);
			goto out;
		}

		/* create or find a SRV resolution for this srv record */
		if (srv->srvrq == NULL && (srv->srvrq = find_srvrq_by_name(srvrecord, srv->proxy)) == NULL)
			srv->srvrq = new_resolv_srvrq(srv, srvrecord);
		if (srv->srvrq == NULL) {
			chunk_appendf(msg, ", can't create or find SRV resolution '%s' for server '%s'", srvrecord, srv->id);
			goto out;
		}

		/* prepare DNS resolution for this server */
		res = srv_prepare_for_resolution(srv, fqdn);
		if (res == -1) {
			chunk_appendf(msg, ", can't allocate memory for DNS resolution for server '%s'", srv->id);
			goto out;
		}

		/* Unset SRV_F_MAPPORTS for SRV records.
		 * SRV_F_MAPPORTS is unfortunately set by parse_server()
		 * because no ports are provided in the configuration file.
		 * This is because HAProxy will use the port found into the SRV record.
		 */
		srv->flags &= ~SRV_F_MAPPORTS;
	}

	if (port_st)
		srv->svc_port = port_svc;


	if (params[16]) {
#ifdef USE_OPENSSL
		use_ssl = strtol(params[16], &p, 10);

		/* configure ssl if connection has been initiated at startup */
		if (srv->ssl_ctx.ctx != NULL)
			ssl_sock_set_srv(srv, use_ssl);
#endif
	}

	port_st = NULL;
	if (params[17] && strcmp(params[17], "0") != 0)
		port_st = params[17];
	addr = NULL;
	if (params[18] && strcmp(params[18], "-") != 0)
		addr = params[18];
	if (addr || port_st) {
		warning = srv_update_check_addr_port(srv, addr, port_st);
		if (warning) {
			chunk_appendf(msg, ", %s", warning);
			goto out;
		}
	}

	port_st = NULL;
	if (params[20] && strcmp(params[20], "0") != 0)
		port_st = params[20];
	addr = NULL;
	if (params[19] && strcmp(params[19], "-") != 0)
		addr = params[19];
	if (addr || port_st) {
		warning = srv_update_agent_addr_port(srv, addr, port_st);
		if (warning) {
			chunk_appendf(msg, ", %s", warning);
			goto out;
		}
	}

  out:
	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
	if (msg->data) {
		if (partial_apply == 1)
			ha_warning("server-state partially applied for server '%s/%s'%s\n",
				   srv->proxy->id, srv->id, msg->area);
		else
			ha_warning("server-state application failed for server '%s/%s'%s\n",
				   srv->proxy->id, srv->id, msg->area);
	}
  end:
	free_trash_chunk(msg);
}

/*
 * Loop on the proxy's servers and try to load its state from <st_tree> using
 * srv_state_srv_update(). The proxy name and the server name are concatenated
 * to form the key. If found the entry is removed from the tree.
 */
static void srv_state_px_update(const struct proxy *px, int vsn, struct eb_root *st_tree)
{
	struct server_state_line *st_line;
	struct eb64_node *node;
	struct server *srv;
	unsigned long key;

	for (srv = px->srv; srv; srv = srv->next) {
		chunk_printf(&trash, "%s %s", px->id, srv->id);
		key = XXH3(trash.area, trash.data, 0);
		node = eb64_lookup(st_tree, key);
		if (!node)
			continue; /* next server */
		st_line = eb64_entry(node, typeof(*st_line), node);
		srv_state_srv_update(srv, vsn, st_line->params+4);

		/* the node may be released now */
		eb64_delete(node);
		free(st_line->line);
		free(st_line);
	}
}

/*
 * read next line from file <f> and return the server state version if one found.
 * If no version is found, then 0 is returned
 * Note that this should be the first read on <f>
 */
static int srv_state_get_version(FILE *f) {
	char mybuf[SRV_STATE_LINE_MAXLEN];
	char *endptr;
	long int vsn;

	/* first character of first line of the file must contain the version of the export */
	if (fgets(mybuf, SRV_STATE_LINE_MAXLEN, f) == NULL)
		return 0;

	vsn = strtol(mybuf, &endptr, 10);
	if (endptr == mybuf || *endptr != '\n') {
		/* Empty or truncated line */
		return 0;
	}

	if (vsn < SRV_STATE_FILE_VERSION_MIN || vsn > SRV_STATE_FILE_VERSION_MAX) {
		/* Wrong version number */
		return 0;
	}

	return vsn;
}


/*
 * parses server state line stored in <buf> and supposedly in version <version>.
 * Set <params> accordingly on success. It returns 1 on success, 0 if the line
 * must be ignored and -1 on error.
 * The caller must provide a supported version
 */
static int srv_state_parse_line(char *buf, const int version, char **params)
{
	int buflen, arg, ret;
	char *cur;

	buflen = strlen(buf);
	cur = buf;
	ret = 1; /* be optimistic and pretend a success */

	/* we need at least one character and a non-truncated line */
	if (buflen == 0 || buf[buflen - 1] != '\n') {
		ret = -1;
		goto out;
	}

	/* skip blank characters at the beginning of the line */
	while (isblank((unsigned char)*cur))
		++cur;

	/* ignore empty or commented lines */
	if (!*cur || *cur == '\n' || *cur == '#') {
		ret = 0;
		goto out;
	}

	/* Removes trailing '\n' to ease parsing */
	buf[buflen - 1] = '\0';

	/* we're now ready to move the line into <params> */
	memset(params, 0, SRV_STATE_FILE_MAX_FIELDS * sizeof(*params));
	arg = 0;
	while (*cur) {
		/* first of all, stop if there are too many fields */
		if (arg >= SRV_STATE_FILE_MAX_FIELDS)
			break;

		/* then skip leading spaces */
		while (*cur && isblank((unsigned char)*cur)) {
			++cur;
			if (!*cur)
				break;
		}

		/*
		 * idx:
		 *   be_id:                params[0]
		 *   be_name:              params[1]
		 *   srv_id:               params[2]
		 *   srv_name:             params[3]
		 * v1
		 *   srv_addr:             params[4]
		 *   srv_op_state:         params[5]
		 *   srv_admin_state:      params[6]
		 *   srv_uweight:          params[7]
		 *   srv_iweight:          params[8]
		 *   srv_last_time_change: params[9]
		 *   srv_check_status:     params[10]
		 *   srv_check_result:     params[11]
		 *   srv_check_health:     params[12]
		 *   srv_check_state:      params[13]
		 *   srv_agent_state:      params[14]
		 *   bk_f_forced_id:       params[15]
		 *   srv_f_forced_id:      params[16]
		 *   srv_fqdn:             params[17]
		 *   srv_port:             params[18]
		 *   srvrecord:            params[19]
		 *
		 *   srv_use_ssl:          params[20]  (optional field)
		 *   srv_check_port:       params[21]  (optional field)
		 *   srv_check_addr:       params[22]  (optional field)
		 *   srv_agent_addr:       params[23]  (optional field)
		 *   srv_agent_port:       params[24]  (optional field)
		 *
		 */
		params[arg++] = cur;

		/* look for the end of the current field */
		while (*cur && !isblank((unsigned char)*cur)) {
			++cur;
			if (!*cur)
				break;
		}

		/* otherwise, cut the field and move to the next one */
		*cur++ = '\0';
	}

	/* if the number of fields does not match the version, then return an error */
	if (version == 1 &&
	    (arg < SRV_STATE_FILE_MIN_FIELDS_VERSION_1 ||
	     arg > SRV_STATE_FILE_MAX_FIELDS_VERSION_1))
		ret = -1;

  out:
	return ret;
}


/*
 * parses a server state line using srv_state_parse_line() and store the result
 * in <st_tree>. If an error occurred during the parsing, the line is
 * ignored. if <px> is defined, it is used to check the backend id/name against
 * the parsed params and to compute the key of the line.
 */
static int srv_state_parse_and_store_line(char *line, int vsn, struct eb_root *st_tree,
					  struct proxy *px)
{
	struct server_state_line *st_line;
	int ret = 0;

	/* store line in tree and duplicate the line */
	st_line = calloc(1, sizeof(*st_line));
	if (st_line == NULL)
		goto skip_line;
	st_line->line = strdup(line);
	if (st_line->line == NULL)
		goto skip_line;

	ret = srv_state_parse_line(st_line->line, vsn, st_line->params);
	if (ret <= 0)
		goto skip_line;

	/* Check backend name against params if <px> is defined */
	if (px) {
		int check_id = (atoi(st_line->params[0]) == px->uuid);
		int check_name = (strcmp(px->id, st_line->params[1]) == 0);
		int bk_f_forced_id = (atoi(st_line->params[15]) & PR_O_FORCED_ID);


		if (!check_id && !check_name) {
			/* backend does not match at all: skip the line */
			goto skip_line;
		}
		else if (!check_id) {
			/* Id mismatch: warn but continue */
			ha_warning("Proxy '%s': backend ID mismatch: from server state file: '%s', from running config '%d'\n",
				   px->id, st_line->params[0], px->uuid);
			send_log(px, LOG_NOTICE, "backend ID mismatch: from server state file: '%s', from running config '%d'\n",
				 st_line->params[0], px->uuid);
		}
		else if (!check_name) {
			/* Name mismatch: warn and skip the line, except if the backend id was forced
			 * in the previous configuration */
			ha_warning("Proxy '%s': backend name mismatch: from server state file: '%s', from running config '%s'\n",
				   px->id, st_line->params[1], px->id);
			send_log(px, LOG_NOTICE, "backend name mismatch: from server state file: '%s', from running config '%s'\n",
				 st_line->params[1], px->id);
			if (!bk_f_forced_id)
				goto skip_line;
		}
	}

	/*
	 * The key: "be_name srv_name"
	 *   if <px> is defined:  be_name == px->id
	 *   otherwise: be_name == params[1]
	 */
	chunk_printf(&trash, "%s %s", (px ? px->id : st_line->params[1]), st_line->params[3]);
	st_line->node.key = XXH3(trash.area, trash.data, 0);
	if (eb64_insert(st_tree, &st_line->node) != &st_line->node) {
		/* this is a duplicate key, probably a hand-crafted file, drop it! */
		goto skip_line;
	}

	return ret;

  skip_line:
	/* free up memory in case of error during the processing of the line */
	if (st_line) {
		free(st_line->line);
		free(st_line);
	}
	return ret;
}

/* Helper function to get the server-state file path.
 * If <filename> starts with a '/', it is considered as an absolute path. In
 * this case or if <global.server_state_base> is not set, <filename> only is
 * considered. Otherwise, the <global.server_state_base> is concatenated to
 * <filename> to produce the file path and copied to <dst_path>. in both cases,
 * the result must not exceeds <maxpathlen>.
 *
 * The len is returned on success or -1 if the path is too long. On error, the
 * caller must not rely on <dst_path>.
 */
static inline int srv_state_get_filepath(char *dst_path, int maxpathlen, const char *filename)
{
	char *sep = (global.server_state_base[strlen(global.server_state_base)-1] != '/' ? "/":  "");
	int len = 0;

	/* create the globalfilepath variable */
	if (*filename == '/' || !global.server_state_base) {
		/* absolute path or no base directory provided */
		len = strlen(filename);
		if (len < maxpathlen)
			strcpy(dst_path, global.server_state_file);
	}
	else {
		/* concat base directory and global server-state file */
		len = snprintf(dst_path, maxpathlen, "%s%s%s", global.server_state_base, sep, filename);
	}
	return (len < maxpathlen ? len: -1);
}


/* This function parses all the proxies and only take care of the backends (since we're looking for server)
 * For each proxy, it does the following:
 *  - opens its server state file (either one or local one)
 *  - read whole file, line by line
 *  - analyse each line to check if it matches our current backend:
 *    - backend name matches
 *    - backend id matches if id is forced and name doesn't match
 *  - if the server pointed by the line is found, then state is applied
 *
 * If the running backend uuid or id differs from the state file, then HAProxy reports
 * a warning.
 *
 * Grabs the server's lock via srv_state_srv_update().
 */
void apply_server_state(void)
{
	/* tree where global state_file is loaded */
	struct eb_root global_state_tree = EB_ROOT_UNIQUE;
	struct proxy *curproxy;
	struct server_state_line *st_line;
	struct eb64_node *node, *next_node;
	FILE *f;
	char mybuf[SRV_STATE_LINE_MAXLEN];
	char file[MAXPATHLEN];
	int local_vsn, global_vsn, len, linenum;

	global_vsn = 0; /* no global file */
	if (!global.server_state_file)
		goto no_globalfile;
	len = srv_state_get_filepath(file, MAXPATHLEN, global.server_state_file);
	if (len == -1) {
		ha_warning("config: Can't load global server state file: file too long.\n");
		goto no_globalfile;
	}

	/* Load global server state in a tree */
	errno = 0;
	f = fopen(file, "r");
	if (!f) {
		ha_warning("config: Can't open global server state file '%s': %s\n", file, strerror(errno));
		goto no_globalfile;
	}

	global_vsn = srv_state_get_version(f);
	if (global_vsn == 0) {
		ha_warning("config: Can't get version of the global server state file '%s'.\n",
			   file);
		goto close_globalfile;
	}

	for (linenum = 1; fgets(mybuf, SRV_STATE_LINE_MAXLEN, f); linenum++) {
		int ret;

		ret = srv_state_parse_and_store_line(mybuf, global_vsn, &global_state_tree, NULL);
		if (ret == -1) {
			ha_warning("config: corrupted global server state file '%s' at line %d.\n",
				   file, linenum);
			global_vsn = 0;
			break;
		}
	}

  close_globalfile:
	fclose(f);

  no_globalfile:
	/* parse all proxies and load states form tree (global file) or from local file */
	for (curproxy = proxies_list; curproxy != NULL; curproxy = curproxy->next) {
		struct eb_root local_state_tree = EB_ROOT_UNIQUE;

		/* Must be an enabled backend with at least a server */
		if (!(curproxy->cap & PR_CAP_BE) || curproxy->disabled || !curproxy->srv)
			continue; /* next proxy */

		/* Mode must be specified */
		BUG_ON(curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_UNSPEC);

		/* No server-state file for this proxy */
		if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_NONE)
			continue;  /* next proxy */

		if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_GLOBAL) {
			/* when global file is used, we get data from the tree
			 * Note that in such case we don't check backend name neither uuid.
			 * Backend name can't be wrong since it's used as a key to retrieve the server state
			 * line from the tree.
			 */
			if (global_vsn)
				srv_state_px_update(curproxy, global_vsn, &global_state_tree);
			continue; /* next proxy */
		}

		/*
		 * Here we load a local server state-file
		 */

		/* create file variable */
		len = srv_state_get_filepath(file, MAXPATHLEN, curproxy->server_state_file_name);
		if (len == -1) {
			ha_warning("Proxy '%s': Can't load local server state file: file too long.\n", curproxy->id);
			continue; /* next proxy */
		}

		/* Load local server state in a tree */
		errno = 0;
		f = fopen(file, "r");
		if (!f) {
			ha_warning("Proxy '%s': Can't open server state file '%s': %s.\n",
				   curproxy->id, file, strerror(errno));
			continue; /* next proxy */
		}

		/* first character of first line of the file must contain the version of the export */
		local_vsn = srv_state_get_version(f);
		if (local_vsn == 0) {
			ha_warning("Proxy '%s': Can't get version of the server state file '%s'.\n",
				   curproxy->id, file);
			goto close_localfile;
		}

		/* First, parse lines of the local server-state file and store them in a eb-tree */
		for (linenum = 1; fgets(mybuf, SRV_STATE_LINE_MAXLEN, f); linenum++) {
			int ret;

			ret = srv_state_parse_and_store_line(mybuf, local_vsn, &local_state_tree, curproxy);
			if (ret == -1) {
				ha_warning("Proxy '%s': corrupted server state file '%s' at line %d.\n",
					   curproxy->id, file, linenum);
				local_vsn = 0;
				break;
			}
		}

		if (local_vsn)
			srv_state_px_update(curproxy, local_vsn, &local_state_tree);

		/* Remove unused server-state lines */
		node = eb64_first(&local_state_tree);
		while (node) {
			st_line = eb64_entry(node, typeof(*st_line), node);
			next_node = eb64_next(node);
			eb64_delete(node);

			if (local_vsn) {
				/* if no server found, then warn */
				ha_warning("Proxy '%s': can't find server '%s' in backend '%s'\n",
					   curproxy->id, st_line->params[3], curproxy->id);
				send_log(curproxy, LOG_NOTICE, "can't find server '%s' in backend '%s'\n",
					 st_line->params[3], curproxy->id);
			}

			free(st_line->line);
			free(st_line);
			node = next_node;
		}

	close_localfile:
		fclose(f);
	}

	node = eb64_first(&global_state_tree);
        while (node) {
                st_line = eb64_entry(node, typeof(*st_line), node);
                next_node = eb64_next(node);
                eb64_delete(node);
		free(st_line->line);
		free(st_line);
                node = next_node;
        }
}
