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