MEDIUM: server: support {check,agent}_addr, agent_port in server state

logical followup from cli commands addition, so that the state server
file stays compatible with the changes made at runtime; use previously
added helper to load server attributes.

also alloc a specific chunk to avoid mixing with other called functions
using it

Signed-off-by: William Dauchy <wdauchy@gmail.com>
diff --git a/src/proxy.c b/src/proxy.c
index 210106d..f06b5d5 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1749,6 +1749,21 @@
 	return 0;
 }
 
+/* helper to dump server addr */
+static void dump_server_addr(const struct sockaddr_storage *addr, char *addr_str)
+{
+	addr_str[0] = '\0';
+	switch (addr->ss_family) {
+		case AF_INET:
+		case AF_INET6:
+			addr_to_str(addr, addr_str, INET6_ADDRSTRLEN + 1);
+			break;
+		default:
+			memcpy(addr_str, "-\0", 2);
+			break;
+	}
+}
+
 /* dumps server state information for all the servers found in backend cli.p0.
  * These information are all the parameters which may change during HAProxy runtime.
  * By default, we only export to the last known server state file format.
@@ -1762,6 +1777,8 @@
 	struct proxy *px = appctx->ctx.cli.p0;
 	struct server *srv;
 	char srv_addr[INET6_ADDRSTRLEN + 1];
+	char srv_agent_addr[INET6_ADDRSTRLEN + 1];
+	char srv_check_addr[INET6_ADDRSTRLEN + 1];
 	time_t srv_time_since_last_change;
 	int bk_f_forced_id, srv_f_forced_id;
 	char *srvrecord;
@@ -1775,21 +1792,11 @@
 
 	for (; appctx->ctx.cli.p1 != NULL; appctx->ctx.cli.p1 = srv->next) {
 		srv = appctx->ctx.cli.p1;
-		srv_addr[0] = '\0';
 
-		switch (srv->addr.ss_family) {
-			case AF_INET:
-				inet_ntop(srv->addr.ss_family, &((struct sockaddr_in *)&srv->addr)->sin_addr,
-					  srv_addr, INET_ADDRSTRLEN + 1);
-				break;
-			case AF_INET6:
-				inet_ntop(srv->addr.ss_family, &((struct sockaddr_in6 *)&srv->addr)->sin6_addr,
-					  srv_addr, INET6_ADDRSTRLEN + 1);
-				break;
-			default:
-				memcpy(srv_addr, "-\0", 2);
-				break;
-		}
+		dump_server_addr(&srv->addr, srv_addr);
+		dump_server_addr(&srv->check.addr, srv_check_addr);
+		dump_server_addr(&srv->agent.addr, srv_agent_addr);
+
 		srv_time_since_last_change = now.tv_sec - srv->last_change;
 		bk_f_forced_id = px->options & PR_O_FORCED_ID ? 1 : 0;
 		srv_f_forced_id = srv->flags & SRV_F_FORCED_ID ? 1 : 0;
@@ -1806,14 +1813,16 @@
 			             "%d %d %d %d %ld "
 			             "%d %d %d %d %d "
 			             "%d %d %s %u "
-				     "%s %d %d"
+				     "%s %d %d "
+				     "%s %s %d"
 			             "\n",
 			             px->uuid, px->id,
 			             srv->puid, srv->id, srv_addr,
 			             srv->cur_state, srv->cur_admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
 			             srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
 			             bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-", srv->svc_port,
-			             srvrecord ? srvrecord : "-", srv->use_ssl, srv->check.port);
+			             srvrecord ? srvrecord : "-", srv->use_ssl, srv->check.port,
+				     srv_check_addr, srv_agent_addr, srv->agent.port);
 		} else {
 			/* show servers conn */
 			int thr;
diff --git a/src/server.c b/src/server.c
index f44f238..be5c489 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2604,6 +2604,7 @@
 {
 	char *p;
 	struct buffer *msg;
+	const char *warning;
 
 	/* fields since version 1
 	 * and common to all other upcoming versions
@@ -2620,18 +2621,19 @@
 	int srv_f_forced_id;
 	int fqdn_set_by_cli;
 	const char *fqdn;
-	const char *port_svc_st;
-	const char *port_check_st;
+	const char *port_st;
 	unsigned int port_svc;
-	unsigned int port_check;
 	char *srvrecord;
+	char *addr;
 #ifdef USE_OPENSSL
 	int use_ssl;
 #endif
 
 	fqdn = NULL;
-	port_svc = port_check = 0;
-	msg = get_trash_chunk();
+	port_svc = 0;
+	msg = alloc_trash_chunk();
+	if (!msg)
+		goto end;
 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
 
 	if (version >= 1) {
@@ -2774,12 +2776,12 @@
 			fqdn = NULL;
 		}
 
-		port_svc_st = params[14];
-		if (port_svc_st) {
-			port_svc = strl2uic(port_svc_st, strlen(port_svc_st));
+		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_svc_st);
-				port_svc_st = NULL;
+				chunk_appendf(msg, ", invalid srv_port value '%s'", port_st);
+				port_st = NULL;
 			}
 		}
 
@@ -2978,33 +2980,52 @@
 			srv->flags &= ~SRV_F_MAPPORTS;
 		}
 
-		if (port_svc_st)
+		if (port_st)
 			srv->svc_port = port_svc;
 
 	}
 	if (version >= 2) {
 		/* 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]
 		 */
 
 #ifdef USE_OPENSSL
 		use_ssl = strtol(params[16], &p, 10);
-#endif
-		port_check_st = params[17];
-		if (port_check_st) {
-			port_check = strl2uic(port_check_st, strlen(port_check_st));
-			if (port_check > USHRT_MAX)
-				chunk_appendf(msg, ", invalid srv_port value '%s'", port_check_st);
-		}
 
-#ifdef USE_OPENSSL
 		/* configure ssl if connection has been initiated at startup */
 		if (srv->ssl_ctx.ctx != NULL)
 			ssl_sock_set_srv(srv, use_ssl);
 #endif
-		if (!srv->check.port)
-			srv->check.port = port_check;
+		port_st = NULL;
+		if (strcmp(params[17], "0") != 0)
+			port_st = params[17];
+		addr = NULL;
+		if (strcmp(params[18], "-") != 0)
+			addr = params[18];
+		if (addr || port_st) {
+			warning = update_server_check_addr_port(srv, addr, port_st);
+			if (warning) {
+				chunk_appendf(msg, ", %s", warning);
+				goto out;
+			}
+		}
 
+		port_st = NULL;
+		if (strcmp(params[17], "0") != 0)
+			port_st = params[20];
+		addr = NULL;
+		if (strcmp(params[19], "-") != 0)
+			addr = params[19];
+		if (addr || port_st) {
+			warning = update_server_agent_addr_port(srv, addr, port_st);
+			if (warning) {
+				chunk_appendf(msg, ", %s", warning);
+				goto out;
+			}
+		}
 	}
 
  out:
@@ -3014,6 +3035,8 @@
 		ha_warning("server-state application failed for server '%s/%s'%s",
 			   srv->proxy->id, srv->id, msg->area);
 	}
+ end:
+	free_trash_chunk(msg);
 }
 
 
@@ -3111,6 +3134,9 @@
 			 * v2
 			 * srv_use_ssl:          params[20] => srv_params[16]
 			 * srv_check_port:       params[21] => srv_params[17]
+			 * srv_check_addr:       params[22] => srv_params[18]
+			 * srv_agent_addr:       params[23] => srv_params[19]
+			 * srv_agent_port:       params[24] => srv_params[20]
 			 */
 			if ((version == 1 && arg >= 4 && arg <= 19) ||
 			     (version == 2 && arg >= 4)) {