/*
 * 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 <import/ebistree.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>
#include <haproxy/tools.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;
		int i;
		char *tmp;

		/* we can't apply previous state if SRV record has changed */
		if (!srv->srvrq) {
			chunk_appendf(msg, ", no SRV resolution for server '%s'. Previous state not applied", srv->id);
			goto out;
		}
		if (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;
		}

		/* 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;
		}

		/* Remove from available list and insert in tree
		 * since this server has an hostname
		 */
		LIST_DEL_INIT(&srv->srv_rec_item);
		srv->host_dn.key = tmp = strdup(srv->hostname_dn);

		/* convert the key in lowercase because tree
		 * lookup is case sensitive but we don't care
		 */
		for (i = 0; tmp[i]; i++)
			tmp[i] = tolower(tmp[i]);

		/* insert in tree and set the srvrq expiration date */
		ebis_insert(&srv->srvrq->named_servers, &srv->host_dn);
		task_schedule(srv->srvrq_check, tick_add(now_ms, srv->srvrq->resolvers->hold.timeout));

		/* 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;
	int len = 0;

	/* create the globalfilepath variable */
	if (*filename == '/' || !global.server_state_base) {
		/* absolute path or no base directory provided */
		len = strlcpy2(dst_path, filename, maxpathlen);
	}
	else {
		/* concat base directory and global server-state file */
		sep = (global.server_state_base[strlen(global.server_state_base)-1] != '/' ? "/":  "");
		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;
        }
}
