1 /*
2  * Server management functions.
3  *
4  * Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
5  * Copyright 2007-2008 Krzysztof Piotr Oledzki <ole@ans.pl>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  *
12  */
13 
14 #include <sys/types.h>
15 #include <netinet/tcp.h>
16 #include <ctype.h>
17 #include <errno.h>
18 
19 #include <import/xxhash.h>
20 
21 #include <haproxy/api.h>
22 #include <haproxy/applet-t.h>
23 #include <haproxy/backend.h>
24 #include <haproxy/cfgparse.h>
25 #include <haproxy/check.h>
26 #include <haproxy/cli.h>
27 #include <haproxy/connection.h>
28 #include <haproxy/dict-t.h>
29 #include <haproxy/errors.h>
30 #include <haproxy/global.h>
31 #include <haproxy/log.h>
32 #include <haproxy/mailers.h>
33 #include <haproxy/namespace.h>
34 #include <haproxy/port_range.h>
35 #include <haproxy/protocol.h>
36 #include <haproxy/proxy.h>
37 #include <haproxy/queue.h>
38 #include <haproxy/resolvers.h>
39 #include <haproxy/sample.h>
40 #include <haproxy/server.h>
41 #include <haproxy/ssl_sock.h>
42 #include <haproxy/stats.h>
43 #include <haproxy/stream.h>
44 #include <haproxy/stream_interface.h>
45 #include <haproxy/task.h>
46 #include <haproxy/tcpcheck.h>
47 #include <haproxy/time.h>
48 #include <haproxy/tools.h>
49 
50 
51 static void srv_update_status(struct server *s);
52 static int srv_apply_lastaddr(struct server *srv, int *err_code);
53 static void srv_cleanup_connections(struct server *srv);
54 
55 /* extra keywords used as value for other arguments. They are used as
56  * suggestions for mistyped words.
57  */
58 static const char *extra_kw_list[] = {
59 	"ipv4", "ipv6", "legacy", "octet-count",
60 	"fail-check", "sudden-death", "mark-down",
61 	NULL /* must be last */
62 };
63 
64 /* List head of all known server keywords */
65 static struct srv_kw_list srv_keywords = {
66 	.list = LIST_HEAD_INIT(srv_keywords.list)
67 };
68 
69 __decl_thread(HA_SPINLOCK_T idle_conn_srv_lock);
70 struct eb_root idle_conn_srv = EB_ROOT;
71 struct task *idle_conn_task __read_mostly = NULL;
72 struct list servers_list = LIST_HEAD_INIT(servers_list);
73 
74 /* The server names dictionary */
75 struct dict server_key_dict = {
76 	.name = "server keys",
77 	.values = EB_ROOT_UNIQUE,
78 };
79 
srv_downtime(const struct server * s)80 int srv_downtime(const struct server *s)
81 {
82 	if ((s->cur_state != SRV_ST_STOPPED) || s->last_change >= now.tv_sec)		// ignore negative time
83 		return s->down_time;
84 
85 	return now.tv_sec - s->last_change + s->down_time;
86 }
87 
srv_lastsession(const struct server * s)88 int srv_lastsession(const struct server *s)
89 {
90 	if (s->counters.last_sess)
91 		return now.tv_sec - s->counters.last_sess;
92 
93 	return -1;
94 }
95 
srv_getinter(const struct check * check)96 int srv_getinter(const struct check *check)
97 {
98 	const struct server *s = check->server;
99 
100 	if ((check->state & CHK_ST_CONFIGURED) && (check->health == check->rise + check->fall - 1))
101 		return check->inter;
102 
103 	if ((s->next_state == SRV_ST_STOPPED) && check->health == 0)
104 		return (check->downinter)?(check->downinter):(check->inter);
105 
106 	return (check->fastinter)?(check->fastinter):(check->inter);
107 }
108 
109 /*
110  * Check that we did not get a hash collision.
111  * Unlikely, but it can happen. The server's proxy must be at least
112  * read-locked.
113  */
srv_check_for_dup_dyncookie(struct server * s)114 static inline void srv_check_for_dup_dyncookie(struct server *s)
115 {
116 	struct proxy *p = s->proxy;
117 	struct server *tmpserv;
118 
119 	for (tmpserv = p->srv; tmpserv != NULL;
120 	    tmpserv = tmpserv->next) {
121 		if (tmpserv == s)
122 			continue;
123 		if (tmpserv->next_admin & SRV_ADMF_FMAINT)
124 			continue;
125 		if (tmpserv->cookie &&
126 		    strcmp(tmpserv->cookie, s->cookie) == 0) {
127 			ha_warning("We generated two equal cookies for two different servers.\n"
128 				   "Please change the secret key for '%s'.\n",
129 				   s->proxy->id);
130 		}
131 	}
132 
133 }
134 
135 /*
136  * Must be called with the server lock held, and will read-lock the proxy.
137  */
srv_set_dyncookie(struct server * s)138 void srv_set_dyncookie(struct server *s)
139 {
140 	struct proxy *p = s->proxy;
141 	char *tmpbuf;
142 	unsigned long long hash_value;
143 	size_t key_len;
144 	size_t buffer_len;
145 	int addr_len;
146 	int port;
147 
148 	HA_RWLOCK_RDLOCK(PROXY_LOCK, &p->lock);
149 
150 	if ((s->flags & SRV_F_COOKIESET) ||
151 	    !(s->proxy->ck_opts & PR_CK_DYNAMIC) ||
152 	    s->proxy->dyncookie_key == NULL)
153 		goto out;
154 	key_len = strlen(p->dyncookie_key);
155 
156 	if (s->addr.ss_family != AF_INET &&
157 	    s->addr.ss_family != AF_INET6)
158 		goto out;
159 	/*
160 	 * Buffer to calculate the cookie value.
161 	 * The buffer contains the secret key + the server IP address
162 	 * + the TCP port.
163 	 */
164 	addr_len = (s->addr.ss_family == AF_INET) ? 4 : 16;
165 	/*
166 	 * The TCP port should use only 2 bytes, but is stored in
167 	 * an unsigned int in struct server, so let's use 4, to be
168 	 * on the safe side.
169 	 */
170 	buffer_len = key_len + addr_len + 4;
171 	tmpbuf = trash.area;
172 	memcpy(tmpbuf, p->dyncookie_key, key_len);
173 	memcpy(&(tmpbuf[key_len]),
174 	    s->addr.ss_family == AF_INET ?
175 	    (void *)&((struct sockaddr_in *)&s->addr)->sin_addr.s_addr :
176 	    (void *)&(((struct sockaddr_in6 *)&s->addr)->sin6_addr.s6_addr),
177 	    addr_len);
178 	/*
179 	 * Make sure it's the same across all the load balancers,
180 	 * no matter their endianness.
181 	 */
182 	port = htonl(s->svc_port);
183 	memcpy(&tmpbuf[key_len + addr_len], &port, 4);
184 	hash_value = XXH64(tmpbuf, buffer_len, 0);
185 	memprintf(&s->cookie, "%016llx", hash_value);
186 	if (!s->cookie)
187 		goto out;
188 	s->cklen = 16;
189 
190 	/* Don't bother checking if the dyncookie is duplicated if
191 	 * the server is marked as "disabled", maybe it doesn't have
192 	 * its real IP yet, but just a place holder.
193 	 */
194 	if (!(s->next_admin & SRV_ADMF_FMAINT))
195 		srv_check_for_dup_dyncookie(s);
196  out:
197 	HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &p->lock);
198 }
199 
200 /* Returns true if it's possible to reuse an idle connection from server <srv>
201  * for a websocket stream. This is the case if server is configured to use the
202  * same protocol for both HTTP and websocket streams. This depends on the value
203  * of "proto", "alpn" and "ws" keywords.
204  */
srv_check_reuse_ws(struct server * srv)205 int srv_check_reuse_ws(struct server *srv)
206 {
207 #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
208 	if (!srv->mux_proto && srv->use_ssl && srv->ssl_ctx.alpn_str) {
209 		/* ALPN selection.
210 		 * Based on the assumption that only "h2" and "http/1.1" token
211 		 * are used on server ALPN.
212 		 */
213 		const struct ist alpn = ist2(srv->ssl_ctx.alpn_str,
214 		                             srv->ssl_ctx.alpn_len);
215 
216 		switch (srv->ws) {
217 		case SRV_WS_AUTO:
218 			/* for auto mode, consider reuse as possible if the
219 			 * server uses a single protocol ALPN
220 			 */
221 			if (!istchr(alpn, ','))
222 				return 1;
223 			break;
224 
225 		case SRV_WS_H2:
226 			return isteq(alpn, ist("\x02h2"));
227 
228 		case SRV_WS_H1:
229 			return isteq(alpn, ist("\x08http/1.1"));
230 		}
231 	}
232 	else {
233 #endif /* defined(OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation) */
234 		/* explicit srv.mux_proto or no ALPN : srv.mux_proto is used
235 		 * for mux selection.
236 		 */
237 		const struct ist srv_mux = srv->mux_proto ?
238 		                           srv->mux_proto->token : IST_NULL;
239 
240 		switch (srv->ws) {
241 		/* "auto" means use the same protocol : reuse is possible. */
242 		case SRV_WS_AUTO:
243 			return 1;
244 
245 		/* "h2" means use h2 for websocket : reuse is possible if
246 		 * server mux is h2.
247 		 */
248 		case SRV_WS_H2:
249 			if (srv->mux_proto && isteq(srv_mux, ist("h2")))
250 				return 1;
251 			break;
252 
253 		/* "h1" means use h1 for websocket : reuse is possible if
254 		 * server mux is h1.
255 		 */
256 		case SRV_WS_H1:
257 			if (!srv->mux_proto || isteq(srv_mux, ist("h1")))
258 				return 1;
259 			break;
260 		}
261 #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
262 	}
263 #endif /* defined(OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation) */
264 
265 	return 0;
266 }
267 
268 /* Return the proto to used for a websocket stream on <srv> without ALPN. NULL
269  * is a valid value indicating to use the fallback mux.
270  */
srv_get_ws_proto(struct server * srv)271 const struct mux_ops *srv_get_ws_proto(struct server *srv)
272 {
273 	const struct mux_proto_list *mux = NULL;
274 
275 	switch (srv->ws) {
276 	case SRV_WS_AUTO:
277 		mux = srv->mux_proto;
278 		break;
279 
280 	case SRV_WS_H1:
281 		mux = get_mux_proto(ist("h1"));
282 		break;
283 
284 	case SRV_WS_H2:
285 		mux = get_mux_proto(ist("h2"));
286 		break;
287 	}
288 
289 	return mux ? mux->mux : NULL;
290 }
291 
292 /*
293  * Must be called with the server lock held. The server is first removed from
294  * the proxy tree if it was already attached. If <reattach> is true, the server
295  * will then be attached in the proxy tree. The proxy lock is held to
296  * manipulate the tree.
297  */
srv_set_addr_desc(struct server * s,int reattach)298 static void srv_set_addr_desc(struct server *s, int reattach)
299 {
300 	struct proxy *p = s->proxy;
301 	char *key;
302 
303 	key = sa2str(&s->addr, s->svc_port, s->flags & SRV_F_MAPPORTS);
304 
305 	if (s->addr_node.key) {
306 		if (key && strcmp(key, s->addr_node.key) == 0) {
307 			free(key);
308 			return;
309 		}
310 
311 		HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock);
312 		ebpt_delete(&s->addr_node);
313 		HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock);
314 
315 		free(s->addr_node.key);
316 	}
317 
318 	s->addr_node.key = key;
319 
320 	if (reattach) {
321 		if (s->addr_node.key) {
322 			HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock);
323 			ebis_insert(&p->used_server_addr, &s->addr_node);
324 			HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock);
325 		}
326 	}
327 }
328 
329 /*
330  * Registers the server keyword list <kwl> as a list of valid keywords for next
331  * parsing sessions.
332  */
srv_register_keywords(struct srv_kw_list * kwl)333 void srv_register_keywords(struct srv_kw_list *kwl)
334 {
335 	LIST_APPEND(&srv_keywords.list, &kwl->list);
336 }
337 
338 /* Return a pointer to the server keyword <kw>, or NULL if not found. If the
339  * keyword is found with a NULL ->parse() function, then an attempt is made to
340  * find one with a valid ->parse() function. This way it is possible to declare
341  * platform-dependant, known keywords as NULL, then only declare them as valid
342  * if some options are met. Note that if the requested keyword contains an
343  * opening parenthesis, everything from this point is ignored.
344  */
srv_find_kw(const char * kw)345 struct srv_kw *srv_find_kw(const char *kw)
346 {
347 	int index;
348 	const char *kwend;
349 	struct srv_kw_list *kwl;
350 	struct srv_kw *ret = NULL;
351 
352 	kwend = strchr(kw, '(');
353 	if (!kwend)
354 		kwend = kw + strlen(kw);
355 
356 	list_for_each_entry(kwl, &srv_keywords.list, list) {
357 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
358 			if ((strncmp(kwl->kw[index].kw, kw, kwend - kw) == 0) &&
359 			    kwl->kw[index].kw[kwend-kw] == 0) {
360 				if (kwl->kw[index].parse)
361 					return &kwl->kw[index]; /* found it !*/
362 				else
363 					ret = &kwl->kw[index];  /* may be OK */
364 			}
365 		}
366 	}
367 	return ret;
368 }
369 
370 /* Dumps all registered "server" keywords to the <out> string pointer. The
371  * unsupported keywords are only dumped if their supported form was not
372  * found.
373  */
srv_dump_kws(char ** out)374 void srv_dump_kws(char **out)
375 {
376 	struct srv_kw_list *kwl;
377 	int index;
378 
379 	if (!out)
380 		return;
381 
382 	*out = NULL;
383 	list_for_each_entry(kwl, &srv_keywords.list, list) {
384 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
385 			if (kwl->kw[index].parse ||
386 			    srv_find_kw(kwl->kw[index].kw) == &kwl->kw[index]) {
387 				memprintf(out, "%s[%4s] %s%s%s%s\n", *out ? *out : "",
388 				          kwl->scope,
389 				          kwl->kw[index].kw,
390 				          kwl->kw[index].skip ? " <arg>" : "",
391 				          kwl->kw[index].default_ok ? " [dflt_ok]" : "",
392 				          kwl->kw[index].parse ? "" : " (not supported)");
393 			}
394 		}
395 	}
396 }
397 
398 /* Try to find in srv_keyword the word that looks closest to <word> by counting
399  * transitions between letters, digits and other characters. Will return the
400  * best matching word if found, otherwise NULL. An optional array of extra
401  * words to compare may be passed in <extra>, but it must then be terminated
402  * by a NULL entry. If unused it may be NULL.
403  */
srv_find_best_kw(const char * word)404 static const char *srv_find_best_kw(const char *word)
405 {
406 	uint8_t word_sig[1024];
407 	uint8_t list_sig[1024];
408 	const struct srv_kw_list *kwl;
409 	const char *best_ptr = NULL;
410 	int dist, best_dist = INT_MAX;
411 	const char **extra;
412 	int index;
413 
414 	make_word_fingerprint(word_sig, word);
415 	list_for_each_entry(kwl, &srv_keywords.list, list) {
416 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
417 			make_word_fingerprint(list_sig, kwl->kw[index].kw);
418 			dist = word_fingerprint_distance(word_sig, list_sig);
419 			if (dist < best_dist) {
420 				best_dist = dist;
421 				best_ptr = kwl->kw[index].kw;
422 			}
423 		}
424 	}
425 
426 	for (extra = extra_kw_list; *extra; extra++) {
427 		make_word_fingerprint(list_sig, *extra);
428 		dist = word_fingerprint_distance(word_sig, list_sig);
429 		if (dist < best_dist) {
430 			best_dist = dist;
431 			best_ptr = *extra;
432 		}
433 	}
434 
435 	if (best_dist > 2 * strlen(word) || (best_ptr && best_dist > 2 * strlen(best_ptr)))
436 		best_ptr = NULL;
437 
438 	return best_ptr;
439 }
440 
441 /* Parse the "backup" server keyword */
srv_parse_backup(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)442 static int srv_parse_backup(char **args, int *cur_arg,
443                             struct proxy *curproxy, struct server *newsrv, char **err)
444 {
445 	newsrv->flags |= SRV_F_BACKUP;
446 	return 0;
447 }
448 
449 
450 /* Parse the "cookie" server keyword */
srv_parse_cookie(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)451 static int srv_parse_cookie(char **args, int *cur_arg,
452                             struct proxy *curproxy, struct server *newsrv, char **err)
453 {
454 	char *arg;
455 
456 	arg = args[*cur_arg + 1];
457 	if (!*arg) {
458 		memprintf(err, "'%s' expects <value> as argument.\n", args[*cur_arg]);
459 		return ERR_ALERT | ERR_FATAL;
460 	}
461 
462 	free(newsrv->cookie);
463 	newsrv->cookie = strdup(arg);
464 	newsrv->cklen = strlen(arg);
465 	newsrv->flags |= SRV_F_COOKIESET;
466 	return 0;
467 }
468 
469 /* Parse the "disabled" server keyword */
srv_parse_disabled(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)470 static int srv_parse_disabled(char **args, int *cur_arg,
471                               struct proxy *curproxy, struct server *newsrv, char **err)
472 {
473 	newsrv->next_admin |= SRV_ADMF_CMAINT | SRV_ADMF_FMAINT;
474 	newsrv->next_state = SRV_ST_STOPPED;
475 	newsrv->check.state |= CHK_ST_PAUSED;
476 	newsrv->check.health = 0;
477 	return 0;
478 }
479 
480 /* Parse the "enabled" server keyword */
srv_parse_enabled(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)481 static int srv_parse_enabled(char **args, int *cur_arg,
482                              struct proxy *curproxy, struct server *newsrv, char **err)
483 {
484 	newsrv->next_admin &= ~SRV_ADMF_CMAINT & ~SRV_ADMF_FMAINT;
485 	newsrv->next_state = SRV_ST_RUNNING;
486 	newsrv->check.state &= ~CHK_ST_PAUSED;
487 	newsrv->check.health = newsrv->check.rise;
488 	return 0;
489 }
490 
491 /* Parse the "error-limit" server keyword */
srv_parse_error_limit(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)492 static int srv_parse_error_limit(char **args, int *cur_arg,
493                                  struct proxy *curproxy, struct server *newsrv, char **err)
494 {
495 	if (!*args[*cur_arg + 1]) {
496 		memprintf(err, "'%s' expects an integer argument.",
497 		          args[*cur_arg]);
498 		return ERR_ALERT | ERR_FATAL;
499 	}
500 
501 	newsrv->consecutive_errors_limit = atoi(args[*cur_arg + 1]);
502 
503 	if (newsrv->consecutive_errors_limit <= 0) {
504 		memprintf(err, "%s has to be > 0.",
505 		          args[*cur_arg]);
506 		return ERR_ALERT | ERR_FATAL;
507 	}
508 
509 	return 0;
510 }
511 
512 /* Parse the "ws" keyword */
srv_parse_ws(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)513 static int srv_parse_ws(char **args, int *cur_arg,
514                         struct proxy *curproxy, struct server *newsrv, char **err)
515 {
516 	if (!args[*cur_arg + 1]) {
517 		memprintf(err, "'%s' expects 'auto', 'h1' or 'h2' value", args[*cur_arg]);
518 		return ERR_ALERT | ERR_FATAL;
519 	}
520 
521 	if (strcmp(args[*cur_arg + 1], "h1") == 0) {
522 		newsrv->ws = SRV_WS_H1;
523 	}
524 	else if (strcmp(args[*cur_arg + 1], "h2") == 0) {
525 		newsrv->ws = SRV_WS_H2;
526 	}
527 	else if (strcmp(args[*cur_arg + 1], "auto") == 0) {
528 		newsrv->ws = SRV_WS_AUTO;
529 	}
530 	else {
531 		memprintf(err, "'%s' has to be 'auto', 'h1' or 'h2'", args[*cur_arg]);
532 		return ERR_ALERT | ERR_FATAL;
533 	}
534 
535 
536 	return 0;
537 }
538 
539 /* Parse the "init-addr" server keyword */
srv_parse_init_addr(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)540 static int srv_parse_init_addr(char **args, int *cur_arg,
541                                struct proxy *curproxy, struct server *newsrv, char **err)
542 {
543 	char *p, *end;
544 	int done;
545 	struct sockaddr_storage sa;
546 
547 	newsrv->init_addr_methods = 0;
548 	memset(&newsrv->init_addr, 0, sizeof(newsrv->init_addr));
549 
550 	for (p = args[*cur_arg + 1]; *p; p = end) {
551 		/* cut on next comma */
552 		for (end = p; *end && *end != ','; end++);
553 		if (*end)
554 			*(end++) = 0;
555 
556 		memset(&sa, 0, sizeof(sa));
557 		if (strcmp(p, "libc") == 0) {
558 			done = srv_append_initaddr(&newsrv->init_addr_methods, SRV_IADDR_LIBC);
559 		}
560 		else if (strcmp(p, "last") == 0) {
561 			done = srv_append_initaddr(&newsrv->init_addr_methods, SRV_IADDR_LAST);
562 		}
563 		else if (strcmp(p, "none") == 0) {
564 			done = srv_append_initaddr(&newsrv->init_addr_methods, SRV_IADDR_NONE);
565 		}
566 		else if (str2ip2(p, &sa, 0)) {
567 			if (is_addr(&newsrv->init_addr)) {
568 				memprintf(err, "'%s' : initial address already specified, cannot add '%s'.",
569 				          args[*cur_arg], p);
570 				return ERR_ALERT | ERR_FATAL;
571 			}
572 			newsrv->init_addr = sa;
573 			done = srv_append_initaddr(&newsrv->init_addr_methods, SRV_IADDR_IP);
574 		}
575 		else {
576 			memprintf(err, "'%s' : unknown init-addr method '%s', supported methods are 'libc', 'last', 'none'.",
577 			          args[*cur_arg], p);
578 			return ERR_ALERT | ERR_FATAL;
579 		}
580 		if (!done) {
581 			memprintf(err, "'%s' : too many init-addr methods when trying to add '%s'",
582 			          args[*cur_arg], p);
583 			return ERR_ALERT | ERR_FATAL;
584 		}
585 	}
586 
587 	return 0;
588 }
589 
590 /* Parse the "log-proto" server keyword */
srv_parse_log_proto(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)591 static int srv_parse_log_proto(char **args, int *cur_arg,
592                                struct proxy *curproxy, struct server *newsrv, char **err)
593 {
594 	if (strcmp(args[*cur_arg + 1], "legacy") == 0)
595 		newsrv->log_proto = SRV_LOG_PROTO_LEGACY;
596 	else if (strcmp(args[*cur_arg + 1], "octet-count") == 0)
597 		newsrv->log_proto = SRV_LOG_PROTO_OCTET_COUNTING;
598 	else {
599 		memprintf(err, "'%s' expects one of 'legacy' or 'octet-count' but got '%s'",
600 		          args[*cur_arg], args[*cur_arg + 1]);
601 		return ERR_ALERT | ERR_FATAL;
602 	}
603 
604 	return 0;
605 }
606 
607 /* Parse the "maxconn" server keyword */
srv_parse_maxconn(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)608 static int srv_parse_maxconn(char **args, int *cur_arg,
609                              struct proxy *curproxy, struct server *newsrv, char **err)
610 {
611 	newsrv->maxconn = atol(args[*cur_arg + 1]);
612 	return 0;
613 }
614 
615 /* Parse the "maxqueue" server keyword */
srv_parse_maxqueue(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)616 static int srv_parse_maxqueue(char **args, int *cur_arg,
617                               struct proxy *curproxy, struct server *newsrv, char **err)
618 {
619 	newsrv->maxqueue = atol(args[*cur_arg + 1]);
620 	return 0;
621 }
622 
623 /* Parse the "minconn" server keyword */
srv_parse_minconn(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)624 static int srv_parse_minconn(char **args, int *cur_arg,
625                              struct proxy *curproxy, struct server *newsrv, char **err)
626 {
627 	newsrv->minconn = atol(args[*cur_arg + 1]);
628 	return 0;
629 }
630 
srv_parse_max_reuse(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)631 static int srv_parse_max_reuse(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
632 {
633 	char *arg;
634 
635 	arg = args[*cur_arg + 1];
636 	if (!*arg) {
637 		memprintf(err, "'%s' expects <value> as argument.\n", args[*cur_arg]);
638 		return ERR_ALERT | ERR_FATAL;
639 	}
640 	newsrv->max_reuse = atoi(arg);
641 
642 	return 0;
643 }
644 
srv_parse_pool_purge_delay(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)645 static int srv_parse_pool_purge_delay(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
646 {
647 	const char *res;
648 	char *arg;
649 	unsigned int time;
650 
651 	arg = args[*cur_arg + 1];
652 	if (!*arg) {
653 		memprintf(err, "'%s' expects <value> as argument.\n", args[*cur_arg]);
654 		return ERR_ALERT | ERR_FATAL;
655 	}
656 	res = parse_time_err(arg, &time, TIME_UNIT_MS);
657 	if (res == PARSE_TIME_OVER) {
658 		memprintf(err, "timer overflow in argument '%s' to '%s' (maximum value is 2147483647 ms or ~24.8 days)",
659 			  args[*cur_arg+1], args[*cur_arg]);
660 		return ERR_ALERT | ERR_FATAL;
661 	}
662 	else if (res == PARSE_TIME_UNDER) {
663 		memprintf(err, "timer underflow in argument '%s' to '%s' (minimum non-null value is 1 ms)",
664 			  args[*cur_arg+1], args[*cur_arg]);
665 		return ERR_ALERT | ERR_FATAL;
666 	}
667 	else if (res) {
668 		memprintf(err, "unexpected character '%c' in argument to <%s>.\n",
669 		    *res, args[*cur_arg]);
670 		return ERR_ALERT | ERR_FATAL;
671 	}
672 	newsrv->pool_purge_delay = time;
673 
674 	return 0;
675 }
676 
srv_parse_pool_low_conn(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)677 static int srv_parse_pool_low_conn(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
678 {
679 	char *arg;
680 
681 	arg = args[*cur_arg + 1];
682 	if (!*arg) {
683 		memprintf(err, "'%s' expects <value> as argument.\n", args[*cur_arg]);
684 		return ERR_ALERT | ERR_FATAL;
685 	}
686 
687 	newsrv->low_idle_conns = atoi(arg);
688 	return 0;
689 }
690 
srv_parse_pool_max_conn(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)691 static int srv_parse_pool_max_conn(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
692 {
693 	char *arg;
694 
695 	arg = args[*cur_arg + 1];
696 	if (!*arg) {
697 		memprintf(err, "'%s' expects <value> as argument.\n", args[*cur_arg]);
698 		return ERR_ALERT | ERR_FATAL;
699 	}
700 
701 	newsrv->max_idle_conns = atoi(arg);
702 	if ((int)newsrv->max_idle_conns < -1) {
703 		memprintf(err, "'%s' must be >= -1", args[*cur_arg]);
704 		return ERR_ALERT | ERR_FATAL;
705 	}
706 
707 	return 0;
708 }
709 
710 /* parse the "id" server keyword */
srv_parse_id(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)711 static int srv_parse_id(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
712 {
713 	struct eb32_node *node;
714 
715 	if (!*args[*cur_arg + 1]) {
716 		memprintf(err, "'%s' : expects an integer argument", args[*cur_arg]);
717 		return ERR_ALERT | ERR_FATAL;
718 	}
719 
720 	newsrv->puid = atol(args[*cur_arg + 1]);
721 	newsrv->conf.id.key = newsrv->puid;
722 
723 	if (newsrv->puid <= 0) {
724 		memprintf(err, "'%s' : custom id has to be > 0", args[*cur_arg]);
725 		return ERR_ALERT | ERR_FATAL;
726 	}
727 
728 	node = eb32_lookup(&curproxy->conf.used_server_id, newsrv->puid);
729 	if (node) {
730 		struct server *target = container_of(node, struct server, conf.id);
731 		memprintf(err, "'%s' : custom id %d already used at %s:%d ('server %s')",
732 		          args[*cur_arg], newsrv->puid, target->conf.file, target->conf.line,
733 		          target->id);
734 		return ERR_ALERT | ERR_FATAL;
735 	}
736 
737 	newsrv->flags |= SRV_F_FORCED_ID;
738 	return 0;
739 }
740 
741 /* Parse the "namespace" server keyword */
srv_parse_namespace(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)742 static int srv_parse_namespace(char **args, int *cur_arg,
743                                struct proxy *curproxy, struct server *newsrv, char **err)
744 {
745 #ifdef USE_NS
746 	char *arg;
747 
748 	arg = args[*cur_arg + 1];
749 	if (!*arg) {
750 		memprintf(err, "'%s' : expects <name> as argument", args[*cur_arg]);
751 		return ERR_ALERT | ERR_FATAL;
752 	}
753 
754 	if (strcmp(arg, "*") == 0) {
755 		/* Use the namespace associated with the connection (if present). */
756 		newsrv->flags |= SRV_F_USE_NS_FROM_PP;
757 		return 0;
758 	}
759 
760 	/*
761 	 * As this parser may be called several times for the same 'default-server'
762 	 * object, or for a new 'server' instance deriving from a 'default-server'
763 	 * one with SRV_F_USE_NS_FROM_PP flag enabled, let's reset it.
764 	 */
765 	newsrv->flags &= ~SRV_F_USE_NS_FROM_PP;
766 
767 	newsrv->netns = netns_store_lookup(arg, strlen(arg));
768 	if (!newsrv->netns)
769 		newsrv->netns = netns_store_insert(arg);
770 
771 	if (!newsrv->netns) {
772 		memprintf(err, "Cannot open namespace '%s'", arg);
773 		return ERR_ALERT | ERR_FATAL;
774 	}
775 
776 	return 0;
777 #else
778 	memprintf(err, "'%s': '%s' option not implemented", args[0], args[*cur_arg]);
779 	return ERR_ALERT | ERR_FATAL;
780 #endif
781 }
782 
783 /* Parse the "no-backup" server keyword */
srv_parse_no_backup(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)784 static int srv_parse_no_backup(char **args, int *cur_arg,
785                                struct proxy *curproxy, struct server *newsrv, char **err)
786 {
787 	newsrv->flags &= ~SRV_F_BACKUP;
788 	return 0;
789 }
790 
791 
792 /* Disable server PROXY protocol flags. */
srv_disable_pp_flags(struct server * srv,unsigned int flags)793 static inline int srv_disable_pp_flags(struct server *srv, unsigned int flags)
794 {
795 	srv->pp_opts &= ~flags;
796 	return 0;
797 }
798 
799 /* Parse the "no-send-proxy" server keyword */
srv_parse_no_send_proxy(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)800 static int srv_parse_no_send_proxy(char **args, int *cur_arg,
801                                    struct proxy *curproxy, struct server *newsrv, char **err)
802 {
803 	return srv_disable_pp_flags(newsrv, SRV_PP_V1);
804 }
805 
806 /* Parse the "no-send-proxy-v2" server keyword */
srv_parse_no_send_proxy_v2(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)807 static int srv_parse_no_send_proxy_v2(char **args, int *cur_arg,
808                                       struct proxy *curproxy, struct server *newsrv, char **err)
809 {
810 	return srv_disable_pp_flags(newsrv, SRV_PP_V2);
811 }
812 
813 /* Parse the "no-tfo" server keyword */
srv_parse_no_tfo(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)814 static int srv_parse_no_tfo(char **args, int *cur_arg,
815                             struct proxy *curproxy, struct server *newsrv, char **err)
816 {
817 	newsrv->flags &= ~SRV_F_FASTOPEN;
818 	return 0;
819 }
820 
821 /* Parse the "non-stick" server keyword */
srv_parse_non_stick(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)822 static int srv_parse_non_stick(char **args, int *cur_arg,
823                                struct proxy *curproxy, struct server *newsrv, char **err)
824 {
825 	newsrv->flags |= SRV_F_NON_STICK;
826 	return 0;
827 }
828 
829 /* Enable server PROXY protocol flags. */
srv_enable_pp_flags(struct server * srv,unsigned int flags)830 static inline int srv_enable_pp_flags(struct server *srv, unsigned int flags)
831 {
832 	srv->pp_opts |= flags;
833 	return 0;
834 }
835 /* parse the "proto" server keyword */
srv_parse_proto(char ** args,int * cur_arg,struct proxy * px,struct server * newsrv,char ** err)836 static int srv_parse_proto(char **args, int *cur_arg,
837 			   struct proxy *px, struct server *newsrv, char **err)
838 {
839 	struct ist proto;
840 
841 	if (!*args[*cur_arg + 1]) {
842 		memprintf(err, "'%s' : missing value", args[*cur_arg]);
843 		return ERR_ALERT | ERR_FATAL;
844 	}
845 	proto = ist(args[*cur_arg + 1]);
846 	newsrv->mux_proto = get_mux_proto(proto);
847 	if (!newsrv->mux_proto) {
848 		memprintf(err, "'%s' :  unknown MUX protocol '%s'", args[*cur_arg], args[*cur_arg+1]);
849 		return ERR_ALERT | ERR_FATAL;
850 	}
851 	return 0;
852 }
853 
854 /* parse the "proxy-v2-options" */
srv_parse_proxy_v2_options(char ** args,int * cur_arg,struct proxy * px,struct server * newsrv,char ** err)855 static int srv_parse_proxy_v2_options(char **args, int *cur_arg,
856 				      struct proxy *px, struct server *newsrv, char **err)
857 {
858 	char *p, *n;
859 	for (p = args[*cur_arg+1]; p; p = n) {
860 		n = strchr(p, ',');
861 		if (n)
862 			*n++ = '\0';
863 		if (strcmp(p, "ssl") == 0) {
864 			newsrv->pp_opts |= SRV_PP_V2_SSL;
865 		} else if (strcmp(p, "cert-cn") == 0) {
866 			newsrv->pp_opts |= SRV_PP_V2_SSL;
867 			newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
868 		} else if (strcmp(p, "cert-key") == 0) {
869 			newsrv->pp_opts |= SRV_PP_V2_SSL;
870 			newsrv->pp_opts |= SRV_PP_V2_SSL_KEY_ALG;
871 		} else if (strcmp(p, "cert-sig") == 0) {
872 			newsrv->pp_opts |= SRV_PP_V2_SSL;
873 			newsrv->pp_opts |= SRV_PP_V2_SSL_SIG_ALG;
874 		} else if (strcmp(p, "ssl-cipher") == 0) {
875 			newsrv->pp_opts |= SRV_PP_V2_SSL;
876 			newsrv->pp_opts |= SRV_PP_V2_SSL_CIPHER;
877 		} else if (strcmp(p, "authority") == 0) {
878 			newsrv->pp_opts |= SRV_PP_V2_AUTHORITY;
879 		} else if (strcmp(p, "crc32c") == 0) {
880 			newsrv->pp_opts |= SRV_PP_V2_CRC32C;
881 		} else if (strcmp(p, "unique-id") == 0) {
882 			newsrv->pp_opts |= SRV_PP_V2_UNIQUE_ID;
883 		} else
884 			goto fail;
885 	}
886 	return 0;
887  fail:
888 	if (err)
889 		memprintf(err, "'%s' : proxy v2 option not implemented", p);
890 	return ERR_ALERT | ERR_FATAL;
891 }
892 
893 /* Parse the "observe" server keyword */
srv_parse_observe(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)894 static int srv_parse_observe(char **args, int *cur_arg,
895                              struct proxy *curproxy, struct server *newsrv, char **err)
896 {
897 	char *arg;
898 
899 	arg = args[*cur_arg + 1];
900 	if (!*arg) {
901 		memprintf(err, "'%s' expects <mode> as argument.\n", args[*cur_arg]);
902 		return ERR_ALERT | ERR_FATAL;
903 	}
904 
905 	if (strcmp(arg, "none") == 0) {
906 		newsrv->observe = HANA_OBS_NONE;
907 	}
908 	else if (strcmp(arg, "layer4") == 0) {
909 		newsrv->observe = HANA_OBS_LAYER4;
910 	}
911 	else if (strcmp(arg, "layer7") == 0) {
912 		if (curproxy->mode != PR_MODE_HTTP) {
913 			memprintf(err, "'%s' can only be used in http proxies.\n", arg);
914 			return ERR_ALERT;
915 		}
916 		newsrv->observe = HANA_OBS_LAYER7;
917 	}
918 	else {
919 		memprintf(err, "'%s' expects one of 'none', 'layer4', 'layer7' "
920 		               "but got '%s'\n", args[*cur_arg], arg);
921 		return ERR_ALERT | ERR_FATAL;
922 	}
923 
924 	return 0;
925 }
926 
927 /* Parse the "on-error" server keyword */
srv_parse_on_error(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)928 static int srv_parse_on_error(char **args, int *cur_arg,
929                               struct proxy *curproxy, struct server *newsrv, char **err)
930 {
931 	if (strcmp(args[*cur_arg + 1], "fastinter") == 0)
932 		newsrv->onerror = HANA_ONERR_FASTINTER;
933 	else if (strcmp(args[*cur_arg + 1], "fail-check") == 0)
934 		newsrv->onerror = HANA_ONERR_FAILCHK;
935 	else if (strcmp(args[*cur_arg + 1], "sudden-death") == 0)
936 		newsrv->onerror = HANA_ONERR_SUDDTH;
937 	else if (strcmp(args[*cur_arg + 1], "mark-down") == 0)
938 		newsrv->onerror = HANA_ONERR_MARKDWN;
939 	else {
940 		memprintf(err, "'%s' expects one of 'fastinter', "
941 		          "'fail-check', 'sudden-death' or 'mark-down' but got '%s'",
942 		          args[*cur_arg], args[*cur_arg + 1]);
943 		return ERR_ALERT | ERR_FATAL;
944 	}
945 
946 	return 0;
947 }
948 
949 /* Parse the "on-marked-down" server keyword */
srv_parse_on_marked_down(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)950 static int srv_parse_on_marked_down(char **args, int *cur_arg,
951                                     struct proxy *curproxy, struct server *newsrv, char **err)
952 {
953 	if (strcmp(args[*cur_arg + 1], "shutdown-sessions") == 0)
954 		newsrv->onmarkeddown = HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS;
955 	else {
956 		memprintf(err, "'%s' expects 'shutdown-sessions' but got '%s'",
957 		          args[*cur_arg], args[*cur_arg + 1]);
958 		return ERR_ALERT | ERR_FATAL;
959 	}
960 
961 	return 0;
962 }
963 
964 /* Parse the "on-marked-up" server keyword */
srv_parse_on_marked_up(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)965 static int srv_parse_on_marked_up(char **args, int *cur_arg,
966                                   struct proxy *curproxy, struct server *newsrv, char **err)
967 {
968 	if (strcmp(args[*cur_arg + 1], "shutdown-backup-sessions") == 0)
969 		newsrv->onmarkedup = HANA_ONMARKEDUP_SHUTDOWNBACKUPSESSIONS;
970 	else {
971 		memprintf(err, "'%s' expects 'shutdown-backup-sessions' but got '%s'",
972 		          args[*cur_arg], args[*cur_arg + 1]);
973 		return ERR_ALERT | ERR_FATAL;
974 	}
975 
976 	return 0;
977 }
978 
979 /* Parse the "redir" server keyword */
srv_parse_redir(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)980 static int srv_parse_redir(char **args, int *cur_arg,
981                            struct proxy *curproxy, struct server *newsrv, char **err)
982 {
983 	char *arg;
984 
985 	arg = args[*cur_arg + 1];
986 	if (!*arg) {
987 		memprintf(err, "'%s' expects <prefix> as argument.\n", args[*cur_arg]);
988 		return ERR_ALERT | ERR_FATAL;
989 	}
990 
991 	free(newsrv->rdr_pfx);
992 	newsrv->rdr_pfx = strdup(arg);
993 	newsrv->rdr_len = strlen(arg);
994 
995 	return 0;
996 }
997 
998 /* Parse the "resolvers" server keyword */
srv_parse_resolvers(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)999 static int srv_parse_resolvers(char **args, int *cur_arg,
1000                            struct proxy *curproxy, struct server *newsrv, char **err)
1001 {
1002 	free(newsrv->resolvers_id);
1003 	newsrv->resolvers_id = strdup(args[*cur_arg + 1]);
1004 	return 0;
1005 }
1006 
1007 /* Parse the "resolve-net" server keyword */
srv_parse_resolve_net(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1008 static int srv_parse_resolve_net(char **args, int *cur_arg,
1009                                  struct proxy *curproxy, struct server *newsrv, char **err)
1010 {
1011 	char *p, *e;
1012 	unsigned char mask;
1013 	struct resolv_options *opt;
1014 
1015 	if (!args[*cur_arg + 1] || args[*cur_arg + 1][0] == '\0') {
1016 		memprintf(err, "'%s' expects a list of networks.",
1017 		          args[*cur_arg]);
1018 		return ERR_ALERT | ERR_FATAL;
1019 	}
1020 
1021 	opt = &newsrv->resolv_opts;
1022 
1023 	/* Split arguments by comma, and convert it from ipv4 or ipv6
1024 	 * string network in in_addr or in6_addr.
1025 	 */
1026 	p = args[*cur_arg + 1];
1027 	e = p;
1028 	while (*p != '\0') {
1029 		/* If no room available, return error. */
1030 		if (opt->pref_net_nb >= SRV_MAX_PREF_NET) {
1031 			memprintf(err, "'%s' exceed %d networks.",
1032 			          args[*cur_arg], SRV_MAX_PREF_NET);
1033 			return ERR_ALERT | ERR_FATAL;
1034 		}
1035 		/* look for end or comma. */
1036 		while (*e != ',' && *e != '\0')
1037 			e++;
1038 		if (*e == ',') {
1039 			*e = '\0';
1040 			e++;
1041 		}
1042 		if (str2net(p, 0, &opt->pref_net[opt->pref_net_nb].addr.in4,
1043 		                  &opt->pref_net[opt->pref_net_nb].mask.in4)) {
1044 			/* Try to convert input string from ipv4 or ipv6 network. */
1045 			opt->pref_net[opt->pref_net_nb].family = AF_INET;
1046 		} else if (str62net(p, &opt->pref_net[opt->pref_net_nb].addr.in6,
1047 		                     &mask)) {
1048 			/* Try to convert input string from ipv6 network. */
1049 			len2mask6(mask, &opt->pref_net[opt->pref_net_nb].mask.in6);
1050 			opt->pref_net[opt->pref_net_nb].family = AF_INET6;
1051 		} else {
1052 			/* All network conversions fail, return error. */
1053 			memprintf(err, "'%s' invalid network '%s'.",
1054 			          args[*cur_arg], p);
1055 			return ERR_ALERT | ERR_FATAL;
1056 		}
1057 		opt->pref_net_nb++;
1058 		p = e;
1059 	}
1060 
1061 	return 0;
1062 }
1063 
1064 /* Parse the "resolve-opts" server keyword */
srv_parse_resolve_opts(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1065 static int srv_parse_resolve_opts(char **args, int *cur_arg,
1066                                   struct proxy *curproxy, struct server *newsrv, char **err)
1067 {
1068 	char *p, *end;
1069 
1070 	for (p = args[*cur_arg + 1]; *p; p = end) {
1071 		/* cut on next comma */
1072 		for (end = p; *end && *end != ','; end++);
1073 		if (*end)
1074 			*(end++) = 0;
1075 
1076 		if (strcmp(p, "allow-dup-ip") == 0) {
1077 			newsrv->resolv_opts.accept_duplicate_ip = 1;
1078 		}
1079 		else if (strcmp(p, "ignore-weight") == 0) {
1080 			newsrv->resolv_opts.ignore_weight = 1;
1081 		}
1082 		else if (strcmp(p, "prevent-dup-ip") == 0) {
1083 			newsrv->resolv_opts.accept_duplicate_ip = 0;
1084 		}
1085 		else {
1086 			memprintf(err, "'%s' : unknown resolve-opts option '%s', supported methods are 'allow-dup-ip', 'ignore-weight', and 'prevent-dup-ip'.",
1087 			          args[*cur_arg], p);
1088 			return ERR_ALERT | ERR_FATAL;
1089 		}
1090 	}
1091 
1092 	return 0;
1093 }
1094 
1095 /* Parse the "resolve-prefer" server keyword */
srv_parse_resolve_prefer(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1096 static int srv_parse_resolve_prefer(char **args, int *cur_arg,
1097                                     struct proxy *curproxy, struct server *newsrv, char **err)
1098 {
1099 	if (strcmp(args[*cur_arg + 1], "ipv4") == 0)
1100 		newsrv->resolv_opts.family_prio = AF_INET;
1101 	else if (strcmp(args[*cur_arg + 1], "ipv6") == 0)
1102 		newsrv->resolv_opts.family_prio = AF_INET6;
1103 	else {
1104 		memprintf(err, "'%s' expects either ipv4 or ipv6 as argument.",
1105 		          args[*cur_arg]);
1106 		return ERR_ALERT | ERR_FATAL;
1107 	}
1108 
1109 	return 0;
1110 }
1111 
1112 /* Parse the "send-proxy" server keyword */
srv_parse_send_proxy(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1113 static int srv_parse_send_proxy(char **args, int *cur_arg,
1114                                 struct proxy *curproxy, struct server *newsrv, char **err)
1115 {
1116 	return srv_enable_pp_flags(newsrv, SRV_PP_V1);
1117 }
1118 
1119 /* Parse the "send-proxy-v2" server keyword */
srv_parse_send_proxy_v2(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1120 static int srv_parse_send_proxy_v2(char **args, int *cur_arg,
1121                                    struct proxy *curproxy, struct server *newsrv, char **err)
1122 {
1123 	return srv_enable_pp_flags(newsrv, SRV_PP_V2);
1124 }
1125 
1126 /* Parse the "slowstart" server keyword */
srv_parse_slowstart(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1127 static int srv_parse_slowstart(char **args, int *cur_arg,
1128                                struct proxy *curproxy, struct server *newsrv, char **err)
1129 {
1130 	/* slowstart is stored in seconds */
1131 	unsigned int val;
1132 	const char *time_err = parse_time_err(args[*cur_arg + 1], &val, TIME_UNIT_MS);
1133 
1134 	if (time_err == PARSE_TIME_OVER) {
1135 		memprintf(err, "overflow in argument <%s> to <%s> of server %s, maximum value is 2147483647 ms (~24.8 days).",
1136 		          args[*cur_arg+1], args[*cur_arg], newsrv->id);
1137 		return ERR_ALERT | ERR_FATAL;
1138 	}
1139 	else if (time_err == PARSE_TIME_UNDER) {
1140 		memprintf(err, "underflow in argument <%s> to <%s> of server %s, minimum non-null value is 1 ms.",
1141 		          args[*cur_arg+1], args[*cur_arg], newsrv->id);
1142 		return ERR_ALERT | ERR_FATAL;
1143 	}
1144 	else if (time_err) {
1145 		memprintf(err, "unexpected character '%c' in 'slowstart' argument of server %s.",
1146 		          *time_err, newsrv->id);
1147 		return ERR_ALERT | ERR_FATAL;
1148 	}
1149 	newsrv->slowstart = (val + 999) / 1000;
1150 
1151 	return 0;
1152 }
1153 
1154 /* Parse the "source" server keyword */
srv_parse_source(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1155 static int srv_parse_source(char **args, int *cur_arg,
1156                             struct proxy *curproxy, struct server *newsrv, char **err)
1157 {
1158 	char *errmsg;
1159 	int port_low, port_high;
1160 	struct sockaddr_storage *sk;
1161 
1162 	errmsg = NULL;
1163 
1164 	if (!*args[*cur_arg + 1]) {
1165 		memprintf(err, "'%s' expects <addr>[:<port>[-<port>]], and optionally '%s' <addr>, "
1166 		               "and '%s' <name> as argument.\n", args[*cur_arg], "usesrc", "interface");
1167 		goto err;
1168 	}
1169 
1170 	/* 'sk' is statically allocated (no need to be freed). */
1171 	sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL, NULL,
1172 	                  &errmsg, NULL, NULL,
1173 		          PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_RANGE | PA_O_STREAM | PA_O_CONNECT);
1174 	if (!sk) {
1175 		memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg);
1176 		goto err;
1177 	}
1178 
1179 	newsrv->conn_src.opts |= CO_SRC_BIND;
1180 	newsrv->conn_src.source_addr = *sk;
1181 
1182 	if (port_low != port_high) {
1183 		int i;
1184 
1185 		newsrv->conn_src.sport_range = port_range_alloc_range(port_high - port_low + 1);
1186 		if (!newsrv->conn_src.sport_range) {
1187 			ha_alert("Server '%s': Out of memory (sport_range)\n", args[0]);
1188 			goto err;
1189 		}
1190 		for (i = 0; i < newsrv->conn_src.sport_range->size; i++)
1191 			newsrv->conn_src.sport_range->ports[i] = port_low + i;
1192 	}
1193 
1194 	*cur_arg += 2;
1195 	while (*(args[*cur_arg])) {
1196 		if (strcmp(args[*cur_arg], "usesrc") == 0) {  /* address to use outside */
1197 #if defined(CONFIG_HAP_TRANSPARENT)
1198 			if (!*args[*cur_arg + 1]) {
1199 				ha_alert("'usesrc' expects <addr>[:<port>], 'client', 'clientip', "
1200 					 "or 'hdr_ip(name,#)' as argument.\n");
1201 				goto err;
1202 			}
1203 			if (strcmp(args[*cur_arg + 1], "client") == 0) {
1204 				newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
1205 				newsrv->conn_src.opts |= CO_SRC_TPROXY_CLI;
1206 			}
1207 			else if (strcmp(args[*cur_arg + 1], "clientip") == 0) {
1208 				newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
1209 				newsrv->conn_src.opts |= CO_SRC_TPROXY_CIP;
1210 			}
1211 			else if (!strncmp(args[*cur_arg + 1], "hdr_ip(", 7)) {
1212 				char *name, *end;
1213 
1214 				name = args[*cur_arg + 1] + 7;
1215 				while (isspace((unsigned char)*name))
1216 					name++;
1217 
1218 				end = name;
1219 				while (*end && !isspace((unsigned char)*end) && *end != ',' && *end != ')')
1220 					end++;
1221 
1222 				newsrv->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
1223 				newsrv->conn_src.opts |= CO_SRC_TPROXY_DYN;
1224 				free(newsrv->conn_src.bind_hdr_name);
1225 				newsrv->conn_src.bind_hdr_name = calloc(1, end - name + 1);
1226 				if (!newsrv->conn_src.bind_hdr_name) {
1227 					ha_alert("Server '%s': Out of memory (bind_hdr_name)\n", args[0]);
1228 					goto err;
1229 				}
1230 				newsrv->conn_src.bind_hdr_len = end - name;
1231 				memcpy(newsrv->conn_src.bind_hdr_name, name, end - name);
1232 				newsrv->conn_src.bind_hdr_name[end - name] = '\0';
1233 				newsrv->conn_src.bind_hdr_occ = -1;
1234 
1235 				/* now look for an occurrence number */
1236 				while (isspace((unsigned char)*end))
1237 					end++;
1238 				if (*end == ',') {
1239 					end++;
1240 					name = end;
1241 					if (*end == '-')
1242 						end++;
1243 					while (isdigit((unsigned char)*end))
1244 						end++;
1245 					newsrv->conn_src.bind_hdr_occ = strl2ic(name, end - name);
1246 				}
1247 
1248 				if (newsrv->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
1249 					ha_alert("usesrc hdr_ip(name,num) does not support negative"
1250 						 " occurrences values smaller than %d.\n", MAX_HDR_HISTORY);
1251 					goto err;
1252 				}
1253 			}
1254 			else {
1255 				struct sockaddr_storage *sk;
1256 				int port1, port2;
1257 
1258 				/* 'sk' is statically allocated (no need to be freed). */
1259 				sk = str2sa_range(args[*cur_arg + 1], NULL, &port1, &port2, NULL, NULL,
1260 				                  &errmsg, NULL, NULL,
1261 				                  PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
1262 				if (!sk) {
1263 					ha_alert("'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg);
1264 					goto err;
1265 				}
1266 
1267 				newsrv->conn_src.tproxy_addr = *sk;
1268 				newsrv->conn_src.opts |= CO_SRC_TPROXY_ADDR;
1269 			}
1270 			global.last_checks |= LSTCHK_NETADM;
1271 			*cur_arg += 2;
1272 			continue;
1273 #else	/* no TPROXY support */
1274 			ha_alert("'usesrc' not allowed here because support for TPROXY was not compiled in.\n");
1275 			goto err;
1276 #endif /* defined(CONFIG_HAP_TRANSPARENT) */
1277 		} /* "usesrc" */
1278 
1279 		if (strcmp(args[*cur_arg], "interface") == 0) { /* specifically bind to this interface */
1280 #ifdef SO_BINDTODEVICE
1281 			if (!*args[*cur_arg + 1]) {
1282 				ha_alert("'%s' : missing interface name.\n", args[0]);
1283 				goto err;
1284 			}
1285 			free(newsrv->conn_src.iface_name);
1286 			newsrv->conn_src.iface_name = strdup(args[*cur_arg + 1]);
1287 			newsrv->conn_src.iface_len  = strlen(newsrv->conn_src.iface_name);
1288 			global.last_checks |= LSTCHK_NETADM;
1289 #else
1290 			ha_alert("'%s' : '%s' option not implemented.\n", args[0], args[*cur_arg]);
1291 			goto err;
1292 #endif
1293 			*cur_arg += 2;
1294 			continue;
1295 		}
1296 		/* this keyword in not an option of "source" */
1297 		break;
1298 	} /* while */
1299 
1300 	return 0;
1301 
1302  err:
1303 	free(errmsg);
1304 	return ERR_ALERT | ERR_FATAL;
1305 }
1306 
1307 /* Parse the "stick" server keyword */
srv_parse_stick(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1308 static int srv_parse_stick(char **args, int *cur_arg,
1309                            struct proxy *curproxy, struct server *newsrv, char **err)
1310 {
1311 	newsrv->flags &= ~SRV_F_NON_STICK;
1312 	return 0;
1313 }
1314 
1315 /* Parse the "track" server keyword */
srv_parse_track(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1316 static int srv_parse_track(char **args, int *cur_arg,
1317                            struct proxy *curproxy, struct server *newsrv, char **err)
1318 {
1319 	char *arg;
1320 
1321 	arg = args[*cur_arg + 1];
1322 	if (!*arg) {
1323 		memprintf(err, "'track' expects [<proxy>/]<server> as argument.\n");
1324 		return ERR_ALERT | ERR_FATAL;
1325 	}
1326 
1327 	free(newsrv->trackit);
1328 	newsrv->trackit = strdup(arg);
1329 
1330 	return 0;
1331 }
1332 
1333 /* Parse the "socks4" server keyword */
srv_parse_socks4(char ** args,int * cur_arg,struct proxy * curproxy,struct server * newsrv,char ** err)1334 static int srv_parse_socks4(char **args, int *cur_arg,
1335                             struct proxy *curproxy, struct server *newsrv, char **err)
1336 {
1337 	char *errmsg;
1338 	int port_low, port_high;
1339 	struct sockaddr_storage *sk;
1340 
1341 	errmsg = NULL;
1342 
1343 	if (!*args[*cur_arg + 1]) {
1344 		memprintf(err, "'%s' expects <addr>:<port> as argument.\n", args[*cur_arg]);
1345 		goto err;
1346 	}
1347 
1348 	/* 'sk' is statically allocated (no need to be freed). */
1349 	sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, NULL, NULL,
1350 	                  &errmsg, NULL, NULL,
1351 	                  PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_STREAM | PA_O_CONNECT);
1352 	if (!sk) {
1353 		memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg + 1], errmsg);
1354 		goto err;
1355 	}
1356 
1357 	newsrv->flags |= SRV_F_SOCKS4_PROXY;
1358 	newsrv->socks4_addr = *sk;
1359 
1360 	return 0;
1361 
1362  err:
1363 	free(errmsg);
1364 	return ERR_ALERT | ERR_FATAL;
1365 }
1366 
1367 
1368 /* parse the "tfo" server keyword */
srv_parse_tfo(char ** args,int * cur_arg,struct proxy * px,struct server * newsrv,char ** err)1369 static int srv_parse_tfo(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1370 {
1371 	newsrv->flags |= SRV_F_FASTOPEN;
1372 	return 0;
1373 }
1374 
1375 /* parse the "usesrc" server keyword */
srv_parse_usesrc(char ** args,int * cur_arg,struct proxy * px,struct server * newsrv,char ** err)1376 static int srv_parse_usesrc(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1377 {
1378 	memprintf(err, "'%s' only allowed after a '%s' statement.",
1379 	          "usesrc", "source");
1380 	return ERR_ALERT | ERR_FATAL;
1381 }
1382 
1383 /* parse the "weight" server keyword */
srv_parse_weight(char ** args,int * cur_arg,struct proxy * px,struct server * newsrv,char ** err)1384 static int srv_parse_weight(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1385 {
1386 	int w;
1387 
1388 	w = atol(args[*cur_arg + 1]);
1389 	if (w < 0 || w > SRV_UWGHT_MAX) {
1390 		memprintf(err, "weight of server %s is not within 0 and %d (%d).",
1391 		          newsrv->id, SRV_UWGHT_MAX, w);
1392 		return ERR_ALERT | ERR_FATAL;
1393 	}
1394 	newsrv->uweight = newsrv->iweight = w;
1395 
1396 	return 0;
1397 }
1398 
1399 /* Shutdown all connections of a server. The caller must pass a termination
1400  * code in <why>, which must be one of SF_ERR_* indicating the reason for the
1401  * shutdown.
1402  *
1403  * Must be called with the server lock held.
1404  */
srv_shutdown_streams(struct server * srv,int why)1405 void srv_shutdown_streams(struct server *srv, int why)
1406 {
1407 	struct stream *stream;
1408 	struct mt_list *elt1, elt2;
1409 	int thr;
1410 
1411 	for (thr = 0; thr < global.nbthread; thr++)
1412 		mt_list_for_each_entry_safe(stream, &srv->per_thr[thr].streams, by_srv, elt1, elt2)
1413 			if (stream->srv_conn == srv)
1414 				stream_shutdown(stream, why);
1415 }
1416 
1417 /* Shutdown all connections of all backup servers of a proxy. The caller must
1418  * pass a termination code in <why>, which must be one of SF_ERR_* indicating
1419  * the reason for the shutdown.
1420  *
1421  * Must be called with the server lock held.
1422  */
srv_shutdown_backup_streams(struct proxy * px,int why)1423 void srv_shutdown_backup_streams(struct proxy *px, int why)
1424 {
1425 	struct server *srv;
1426 
1427 	for (srv = px->srv; srv != NULL; srv = srv->next)
1428 		if (srv->flags & SRV_F_BACKUP)
1429 			srv_shutdown_streams(srv, why);
1430 }
1431 
1432 /* Appends some information to a message string related to a server going UP or
1433  * DOWN.  If both <forced> and <reason> are null and the server tracks another
1434  * one, a "via" information will be provided to know where the status came from.
1435  * If <check> is non-null, an entire string describing the check result will be
1436  * appended after a comma and a space (eg: to report some information from the
1437  * check that changed the state). In the other case, the string will be built
1438  * using the check results stored into the struct server if present.
1439  * If <xferred> is non-negative, some information about requeued sessions are
1440  * provided.
1441  *
1442  * Must be called with the server lock held.
1443  */
srv_append_status(struct buffer * msg,struct server * s,struct check * check,int xferred,int forced)1444 void srv_append_status(struct buffer *msg, struct server *s,
1445 		       struct check *check, int xferred, int forced)
1446 {
1447 	short status = s->op_st_chg.status;
1448 	short code = s->op_st_chg.code;
1449 	long duration = s->op_st_chg.duration;
1450 	char *desc = s->op_st_chg.reason;
1451 
1452 	if (check) {
1453 		status = check->status;
1454 		code = check->code;
1455 		duration = check->duration;
1456 		desc = check->desc;
1457 	}
1458 
1459 	if (status != -1) {
1460 		chunk_appendf(msg, ", reason: %s", get_check_status_description(status));
1461 
1462 		if (status >= HCHK_STATUS_L57DATA)
1463 			chunk_appendf(msg, ", code: %d", code);
1464 
1465 		if (desc && *desc) {
1466 			struct buffer src;
1467 
1468 			chunk_appendf(msg, ", info: \"");
1469 
1470 			chunk_initlen(&src, desc, 0, strlen(desc));
1471 			chunk_asciiencode(msg, &src, '"');
1472 
1473 			chunk_appendf(msg, "\"");
1474 		}
1475 
1476 		if (duration >= 0)
1477 			chunk_appendf(msg, ", check duration: %ldms", duration);
1478 	}
1479         else if (desc && *desc) {
1480                 chunk_appendf(msg, ", %s", desc);
1481         }
1482 	else if (!forced && s->track) {
1483 		chunk_appendf(msg, " via %s/%s", s->track->proxy->id, s->track->id);
1484 	}
1485 
1486 	if (xferred >= 0) {
1487 		if (s->next_state == SRV_ST_STOPPED)
1488 			chunk_appendf(msg, ". %d active and %d backup servers left.%s"
1489 				" %d sessions active, %d requeued, %d remaining in queue",
1490 				s->proxy->srv_act, s->proxy->srv_bck,
1491 				(s->proxy->srv_bck && !s->proxy->srv_act) ? " Running on backup." : "",
1492 				s->cur_sess, xferred, s->nbpend);
1493 		else
1494 			chunk_appendf(msg, ". %d active and %d backup servers online.%s"
1495 				" %d sessions requeued, %d total in queue",
1496 				s->proxy->srv_act, s->proxy->srv_bck,
1497 				(s->proxy->srv_bck && !s->proxy->srv_act) ? " Running on backup." : "",
1498 				xferred, s->nbpend);
1499 	}
1500 }
1501 
1502 /* Marks server <s> down, regardless of its checks' statuses. The server is
1503  * registered in a list to postpone the counting of the remaining servers on
1504  * the proxy and transfers queued streams whenever possible to other servers at
1505  * a sync point. Maintenance servers are ignored. It stores the <reason> if
1506  * non-null as the reason for going down or the available data from the check
1507  * struct to recompute this reason later.
1508  *
1509  * Must be called with the server lock held.
1510  */
srv_set_stopped(struct server * s,const char * reason,struct check * check)1511 void srv_set_stopped(struct server *s, const char *reason, struct check *check)
1512 {
1513 	struct server *srv;
1514 
1515 	if ((s->cur_admin & SRV_ADMF_MAINT) || s->next_state == SRV_ST_STOPPED)
1516 		return;
1517 
1518 	s->next_state = SRV_ST_STOPPED;
1519 	*s->op_st_chg.reason = 0;
1520 	s->op_st_chg.status = -1;
1521 	if (reason) {
1522 		strlcpy2(s->op_st_chg.reason, reason, sizeof(s->op_st_chg.reason));
1523 	}
1524 	else if (check) {
1525 		strlcpy2(s->op_st_chg.reason, check->desc, sizeof(s->op_st_chg.reason));
1526 		s->op_st_chg.code = check->code;
1527 		s->op_st_chg.status = check->status;
1528 		s->op_st_chg.duration = check->duration;
1529 	}
1530 
1531 	/* propagate changes */
1532 	srv_update_status(s);
1533 
1534 	for (srv = s->trackers; srv; srv = srv->tracknext) {
1535 		HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1536 		srv_set_stopped(srv, NULL, NULL);
1537 		HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1538 	}
1539 }
1540 
1541 /* Marks server <s> up regardless of its checks' statuses and provided it isn't
1542  * in maintenance. The server is registered in a list to postpone the counting
1543  * of the remaining servers on the proxy and tries to grab requests from the
1544  * proxy at a sync point. Maintenance servers are ignored. It stores the
1545  * <reason> if non-null as the reason for going down or the available data
1546  * from the check struct to recompute this reason later.
1547  *
1548  * Must be called with the server lock held.
1549  */
srv_set_running(struct server * s,const char * reason,struct check * check)1550 void srv_set_running(struct server *s, const char *reason, struct check *check)
1551 {
1552 	struct server *srv;
1553 
1554 	if (s->cur_admin & SRV_ADMF_MAINT)
1555 		return;
1556 
1557 	if (s->next_state == SRV_ST_STARTING || s->next_state == SRV_ST_RUNNING)
1558 		return;
1559 
1560 	s->next_state = SRV_ST_STARTING;
1561 	*s->op_st_chg.reason = 0;
1562 	s->op_st_chg.status = -1;
1563 	if (reason) {
1564 		strlcpy2(s->op_st_chg.reason, reason, sizeof(s->op_st_chg.reason));
1565 	}
1566 	else if (check) {
1567 		strlcpy2(s->op_st_chg.reason, check->desc, sizeof(s->op_st_chg.reason));
1568 		s->op_st_chg.code = check->code;
1569 		s->op_st_chg.status = check->status;
1570 		s->op_st_chg.duration = check->duration;
1571 	}
1572 
1573 	if (s->slowstart <= 0)
1574 		s->next_state = SRV_ST_RUNNING;
1575 
1576 	/* propagate changes */
1577 	srv_update_status(s);
1578 
1579 	for (srv = s->trackers; srv; srv = srv->tracknext) {
1580 		HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1581 		srv_set_running(srv, NULL, NULL);
1582 		HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1583 	}
1584 }
1585 
1586 /* Marks server <s> stopping regardless of its checks' statuses and provided it
1587  * isn't in maintenance. The server is registered in a list to postpone the
1588  * counting of the remaining servers on the proxy and tries to grab requests
1589  * from the proxy. Maintenance servers are ignored. It stores the
1590  * <reason> if non-null as the reason for going down or the available data
1591  * from the check struct to recompute this reason later.
1592  * up. Note that it makes use of the trash to build the log strings, so <reason>
1593  * must not be placed there.
1594  *
1595  * Must be called with the server lock held.
1596  */
srv_set_stopping(struct server * s,const char * reason,struct check * check)1597 void srv_set_stopping(struct server *s, const char *reason, struct check *check)
1598 {
1599 	struct server *srv;
1600 
1601 	if (s->cur_admin & SRV_ADMF_MAINT)
1602 		return;
1603 
1604 	if (s->next_state == SRV_ST_STOPPING)
1605 		return;
1606 
1607 	s->next_state = SRV_ST_STOPPING;
1608 	*s->op_st_chg.reason = 0;
1609 	s->op_st_chg.status = -1;
1610 	if (reason) {
1611 		strlcpy2(s->op_st_chg.reason, reason, sizeof(s->op_st_chg.reason));
1612 	}
1613 	else if (check) {
1614 		strlcpy2(s->op_st_chg.reason, check->desc, sizeof(s->op_st_chg.reason));
1615 		s->op_st_chg.code = check->code;
1616 		s->op_st_chg.status = check->status;
1617 		s->op_st_chg.duration = check->duration;
1618 	}
1619 
1620 	/* propagate changes */
1621 	srv_update_status(s);
1622 
1623 	for (srv = s->trackers; srv; srv = srv->tracknext) {
1624 		HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1625 		srv_set_stopping(srv, NULL, NULL);
1626 		HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1627 	}
1628 }
1629 
1630 /* Enables admin flag <mode> (among SRV_ADMF_*) on server <s>. This is used to
1631  * enforce either maint mode or drain mode. It is not allowed to set more than
1632  * one flag at once. The equivalent "inherited" flag is propagated to all
1633  * tracking servers. Maintenance mode disables health checks (but not agent
1634  * checks). When either the flag is already set or no flag is passed, nothing
1635  * is done. If <cause> is non-null, it will be displayed at the end of the log
1636  * lines to justify the state change.
1637  *
1638  * Must be called with the server lock held.
1639  */
srv_set_admin_flag(struct server * s,enum srv_admin mode,const char * cause)1640 void srv_set_admin_flag(struct server *s, enum srv_admin mode, const char *cause)
1641 {
1642 	struct server *srv;
1643 
1644 	if (!mode)
1645 		return;
1646 
1647 	/* stop going down as soon as we meet a server already in the same state */
1648 	if (s->next_admin & mode)
1649 		return;
1650 
1651 	s->next_admin |= mode;
1652 	if (cause)
1653 		strlcpy2(s->adm_st_chg_cause, cause, sizeof(s->adm_st_chg_cause));
1654 
1655 	/* propagate changes */
1656 	srv_update_status(s);
1657 
1658 	/* stop going down if the equivalent flag was already present (forced or inherited) */
1659 	if (((mode & SRV_ADMF_MAINT) && (s->next_admin & ~mode & SRV_ADMF_MAINT)) ||
1660 	    ((mode & SRV_ADMF_DRAIN) && (s->next_admin & ~mode & SRV_ADMF_DRAIN)))
1661 		return;
1662 
1663 	/* compute the inherited flag to propagate */
1664 	if (mode & SRV_ADMF_MAINT)
1665 		mode = SRV_ADMF_IMAINT;
1666 	else if (mode & SRV_ADMF_DRAIN)
1667 		mode = SRV_ADMF_IDRAIN;
1668 
1669 	for (srv = s->trackers; srv; srv = srv->tracknext) {
1670 		HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1671 		srv_set_admin_flag(srv, mode, cause);
1672 		HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1673 	}
1674 }
1675 
1676 /* Disables admin flag <mode> (among SRV_ADMF_*) on server <s>. This is used to
1677  * stop enforcing either maint mode or drain mode. It is not allowed to set more
1678  * than one flag at once. The equivalent "inherited" flag is propagated to all
1679  * tracking servers. Leaving maintenance mode re-enables health checks. When
1680  * either the flag is already cleared or no flag is passed, nothing is done.
1681  *
1682  * Must be called with the server lock held.
1683  */
srv_clr_admin_flag(struct server * s,enum srv_admin mode)1684 void srv_clr_admin_flag(struct server *s, enum srv_admin mode)
1685 {
1686 	struct server *srv;
1687 
1688 	if (!mode)
1689 		return;
1690 
1691 	/* stop going down as soon as we see the flag is not there anymore */
1692 	if (!(s->next_admin & mode))
1693 		return;
1694 
1695 	s->next_admin &= ~mode;
1696 
1697 	/* propagate changes */
1698 	srv_update_status(s);
1699 
1700 	/* stop going down if the equivalent flag is still present (forced or inherited) */
1701 	if (((mode & SRV_ADMF_MAINT) && (s->next_admin & SRV_ADMF_MAINT)) ||
1702 	    ((mode & SRV_ADMF_DRAIN) && (s->next_admin & SRV_ADMF_DRAIN)))
1703 		return;
1704 
1705 	if (mode & SRV_ADMF_MAINT)
1706 		mode = SRV_ADMF_IMAINT;
1707 	else if (mode & SRV_ADMF_DRAIN)
1708 		mode = SRV_ADMF_IDRAIN;
1709 
1710 	for (srv = s->trackers; srv; srv = srv->tracknext) {
1711 		HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1712 		srv_clr_admin_flag(srv, mode);
1713 		HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1714 	}
1715 }
1716 
1717 /* principle: propagate maint and drain to tracking servers. This is useful
1718  * upon startup so that inherited states are correct.
1719  */
srv_propagate_admin_state(struct server * srv)1720 static void srv_propagate_admin_state(struct server *srv)
1721 {
1722 	struct server *srv2;
1723 
1724 	if (!srv->trackers)
1725 		return;
1726 
1727 	for (srv2 = srv->trackers; srv2; srv2 = srv2->tracknext) {
1728 		HA_SPIN_LOCK(SERVER_LOCK, &srv2->lock);
1729 		if (srv->next_admin & (SRV_ADMF_MAINT | SRV_ADMF_CMAINT))
1730 			srv_set_admin_flag(srv2, SRV_ADMF_IMAINT, NULL);
1731 
1732 		if (srv->next_admin & SRV_ADMF_DRAIN)
1733 			srv_set_admin_flag(srv2, SRV_ADMF_IDRAIN, NULL);
1734 		HA_SPIN_UNLOCK(SERVER_LOCK, &srv2->lock);
1735 	}
1736 }
1737 
1738 /* Compute and propagate the admin states for all servers in proxy <px>.
1739  * Only servers *not* tracking another one are considered, because other
1740  * ones will be handled when the server they track is visited.
1741  */
srv_compute_all_admin_states(struct proxy * px)1742 void srv_compute_all_admin_states(struct proxy *px)
1743 {
1744 	struct server *srv;
1745 
1746 	for (srv = px->srv; srv; srv = srv->next) {
1747 		if (srv->track)
1748 			continue;
1749 		srv_propagate_admin_state(srv);
1750 	}
1751 }
1752 
1753 /* Note: must not be declared <const> as its list will be overwritten.
1754  * Please take care of keeping this list alphabetically sorted, doing so helps
1755  * all code contributors.
1756  * Optional keywords are also declared with a NULL ->parse() function so that
1757  * the config parser can report an appropriate error when a known keyword was
1758  * not enabled.
1759  * Note: -1 as ->skip value means that the number of arguments are variable.
1760  */
1761 static struct srv_kw_list srv_kws = { "ALL", { }, {
1762 	{ "backup",              srv_parse_backup,              0,  1,  1 }, /* Flag as backup server */
1763 	{ "cookie",              srv_parse_cookie,              1,  1,  0 }, /* Assign a cookie to the server */
1764 	{ "disabled",            srv_parse_disabled,            0,  1,  1 }, /* Start the server in 'disabled' state */
1765 	{ "enabled",             srv_parse_enabled,             0,  1,  1 }, /* Start the server in 'enabled' state */
1766 	{ "error-limit",         srv_parse_error_limit,         1,  1,  0 }, /* Configure the consecutive count of check failures to consider a server on error */
1767 	{ "ws",                  srv_parse_ws,                  1,  1,  1 }, /* websocket protocol */
1768 	{ "id",                  srv_parse_id,                  1,  0,  1 }, /* set id# of server */
1769 	{ "init-addr",           srv_parse_init_addr,           1,  1,  0 }, /* */
1770 	{ "log-proto",           srv_parse_log_proto,           1,  1,  0 }, /* Set the protocol for event messages, only relevant in a ring section */
1771 	{ "maxconn",             srv_parse_maxconn,             1,  1,  1 }, /* Set the max number of concurrent connection */
1772 	{ "maxqueue",            srv_parse_maxqueue,            1,  1,  1 }, /* Set the max number of connection to put in queue */
1773 	{ "max-reuse",           srv_parse_max_reuse,           1,  1,  0 }, /* Set the max number of requests on a connection, -1 means unlimited */
1774 	{ "minconn",             srv_parse_minconn,             1,  1,  1 }, /* Enable a dynamic maxconn limit */
1775 	{ "namespace",           srv_parse_namespace,           1,  1,  0 }, /* Namespace the server socket belongs to (if supported) */
1776 	{ "no-backup",           srv_parse_no_backup,           0,  1,  1 }, /* Flag as non-backup server */
1777 	{ "no-send-proxy",       srv_parse_no_send_proxy,       0,  1,  1 }, /* Disable use of PROXY V1 protocol */
1778 	{ "no-send-proxy-v2",    srv_parse_no_send_proxy_v2,    0,  1,  1 }, /* Disable use of PROXY V2 protocol */
1779 	{ "no-tfo",              srv_parse_no_tfo,              0,  1,  1 }, /* Disable use of TCP Fast Open */
1780 	{ "non-stick",           srv_parse_non_stick,           0,  1,  0 }, /* Disable stick-table persistence */
1781 	{ "observe",             srv_parse_observe,             1,  1,  0 }, /* Enables health adjusting based on observing communication with the server */
1782 	{ "on-error",            srv_parse_on_error,            1,  1,  0 }, /* Configure the action on check failure */
1783 	{ "on-marked-down",      srv_parse_on_marked_down,      1,  1,  0 }, /* Configure the action when a server is marked down */
1784 	{ "on-marked-up",        srv_parse_on_marked_up,        1,  1,  0 }, /* Configure the action when a server is marked up */
1785 	{ "pool-low-conn",       srv_parse_pool_low_conn,       1,  1,  1 }, /* Set the min number of orphan idle connecbefore being allowed to pick from other threads */
1786 	{ "pool-max-conn",       srv_parse_pool_max_conn,       1,  1,  1 }, /* Set the max number of orphan idle connections, -1 means unlimited */
1787 	{ "pool-purge-delay",    srv_parse_pool_purge_delay,    1,  1,  1 }, /* Set the time before we destroy orphan idle connections, defaults to 1s */
1788 	{ "proto",               srv_parse_proto,               1,  1,  1 }, /* Set the proto to use for all outgoing connections */
1789 	{ "proxy-v2-options",    srv_parse_proxy_v2_options,    1,  1,  1 }, /* options for send-proxy-v2 */
1790 	{ "redir",               srv_parse_redir,               1,  1,  0 }, /* Enable redirection mode */
1791 	{ "resolve-net",         srv_parse_resolve_net,         1,  1,  0 }, /* Set the preferred network range for name resolution */
1792 	{ "resolve-opts",        srv_parse_resolve_opts,        1,  1,  0 }, /* Set options for name resolution */
1793 	{ "resolve-prefer",      srv_parse_resolve_prefer,      1,  1,  0 }, /* Set the preferred family for name resolution */
1794 	{ "resolvers",           srv_parse_resolvers,           1,  1,  0 }, /* Configure the resolver to use for name resolution */
1795 	{ "send-proxy",          srv_parse_send_proxy,          0,  1,  1 }, /* Enforce use of PROXY V1 protocol */
1796 	{ "send-proxy-v2",       srv_parse_send_proxy_v2,       0,  1,  1 }, /* Enforce use of PROXY V2 protocol */
1797 	{ "slowstart",           srv_parse_slowstart,           1,  1,  0 }, /* Set the warm-up timer for a previously failed server */
1798 	{ "source",              srv_parse_source,             -1,  1,  1 }, /* Set the source address to be used to connect to the server */
1799 	{ "stick",               srv_parse_stick,               0,  1,  0 }, /* Enable stick-table persistence */
1800 	{ "tfo",                 srv_parse_tfo,                 0,  1,  1 }, /* enable TCP Fast Open of server */
1801 	{ "track",               srv_parse_track,               1,  1,  0 }, /* Set the current state of the server, tracking another one */
1802 	{ "socks4",              srv_parse_socks4,              1,  1,  0 }, /* Set the socks4 proxy of the server*/
1803 	{ "usesrc",              srv_parse_usesrc,              0,  1,  1 }, /* safe-guard against usesrc without preceding <source> keyword */
1804 	{ "weight",              srv_parse_weight,              1,  1,  1 }, /* Set the load-balancing weight */
1805 	{ NULL, NULL, 0 },
1806 }};
1807 
1808 INITCALL1(STG_REGISTER, srv_register_keywords, &srv_kws);
1809 
1810 /* Recomputes the server's eweight based on its state, uweight, the current time,
1811  * and the proxy's algorithm. To be used after updating sv->uweight. The warmup
1812  * state is automatically disabled if the time is elapsed. If <must_update> is
1813  * not zero, the update will be propagated immediately.
1814  *
1815  * Must be called with the server lock held.
1816  */
server_recalc_eweight(struct server * sv,int must_update)1817 void server_recalc_eweight(struct server *sv, int must_update)
1818 {
1819 	struct proxy *px = sv->proxy;
1820 	unsigned w;
1821 
1822 	if (now.tv_sec < sv->last_change || now.tv_sec >= sv->last_change + sv->slowstart) {
1823 		/* go to full throttle if the slowstart interval is reached */
1824 		if (sv->next_state == SRV_ST_STARTING)
1825 			sv->next_state = SRV_ST_RUNNING;
1826 	}
1827 
1828 	/* We must take care of not pushing the server to full throttle during slow starts.
1829 	 * It must also start immediately, at least at the minimal step when leaving maintenance.
1830 	 */
1831 	if ((sv->next_state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN))
1832 		w = (px->lbprm.wdiv * (now.tv_sec - sv->last_change) + sv->slowstart) / sv->slowstart;
1833 	else
1834 		w = px->lbprm.wdiv;
1835 
1836 	sv->next_eweight = (sv->uweight * w + px->lbprm.wmult - 1) / px->lbprm.wmult;
1837 
1838 	/* propagate changes only if needed (i.e. not recursively) */
1839 	if (must_update)
1840 		srv_update_status(sv);
1841 }
1842 
1843 /*
1844  * Parses weight_str and configures sv accordingly.
1845  * Returns NULL on success, error message string otherwise.
1846  *
1847  * Must be called with the server lock held.
1848  */
server_parse_weight_change_request(struct server * sv,const char * weight_str)1849 const char *server_parse_weight_change_request(struct server *sv,
1850 					       const char *weight_str)
1851 {
1852 	struct proxy *px;
1853 	long int w;
1854 	char *end;
1855 
1856 	px = sv->proxy;
1857 
1858 	/* if the weight is terminated with '%', it is set relative to
1859 	 * the initial weight, otherwise it is absolute.
1860 	 */
1861 	if (!*weight_str)
1862 		return "Require <weight> or <weight%>.\n";
1863 
1864 	w = strtol(weight_str, &end, 10);
1865 	if (end == weight_str)
1866 		return "Empty weight string empty or preceded by garbage";
1867 	else if (end[0] == '%' && end[1] == '\0') {
1868 		if (w < 0)
1869 			return "Relative weight must be positive.\n";
1870 		/* Avoid integer overflow */
1871 		if (w > 25600)
1872 			w = 25600;
1873 		w = sv->iweight * w / 100;
1874 		if (w > 256)
1875 			w = 256;
1876 	}
1877 	else if (w < 0 || w > 256)
1878 		return "Absolute weight can only be between 0 and 256 inclusive.\n";
1879 	else if (end[0] != '\0')
1880 		return "Trailing garbage in weight string";
1881 
1882 	if (w && w != sv->iweight && !(px->lbprm.algo & BE_LB_PROP_DYN))
1883 		return "Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.\n";
1884 
1885 	sv->uweight = w;
1886 	server_recalc_eweight(sv, 1);
1887 
1888 	return NULL;
1889 }
1890 
1891 /*
1892  * Parses <addr_str> and configures <sv> accordingly. <from> precise
1893  * the source of the change in the associated message log.
1894  * Returns:
1895  *  - error string on error
1896  *  - NULL on success
1897  *
1898  * Must be called with the server lock held.
1899  */
server_parse_addr_change_request(struct server * sv,const char * addr_str,const char * updater)1900 const char *server_parse_addr_change_request(struct server *sv,
1901                                              const char *addr_str, const char *updater)
1902 {
1903 	unsigned char ip[INET6_ADDRSTRLEN];
1904 
1905 	if (inet_pton(AF_INET6, addr_str, ip)) {
1906 		srv_update_addr(sv, ip, AF_INET6, updater);
1907 		return NULL;
1908 	}
1909 	if (inet_pton(AF_INET, addr_str, ip)) {
1910 		srv_update_addr(sv, ip, AF_INET, updater);
1911 		return NULL;
1912 	}
1913 
1914 	return "Could not understand IP address format.\n";
1915 }
1916 
1917 /*
1918  * Must be called with the server lock held.
1919  */
server_parse_maxconn_change_request(struct server * sv,const char * maxconn_str)1920 const char *server_parse_maxconn_change_request(struct server *sv,
1921                                                 const char *maxconn_str)
1922 {
1923 	long int v;
1924 	char *end;
1925 
1926 	if (!*maxconn_str)
1927 		return "Require <maxconn>.\n";
1928 
1929 	v = strtol(maxconn_str, &end, 10);
1930 	if (end == maxconn_str)
1931 		return "maxconn string empty or preceded by garbage";
1932 	else if (end[0] != '\0')
1933 		return "Trailing garbage in maxconn string";
1934 
1935 	if (sv->maxconn == sv->minconn) { // static maxconn
1936 		sv->maxconn = sv->minconn = v;
1937 	} else { // dynamic maxconn
1938 		sv->maxconn = v;
1939 	}
1940 
1941 	/* server_parse_maxconn_change_request requires the server lock held.
1942 	 * Specify it to process_srv_queue to prevent a deadlock.
1943 	 */
1944 	if (may_dequeue_tasks(sv, sv->proxy))
1945 		process_srv_queue(sv, 1);
1946 
1947 	return NULL;
1948 }
1949 
srv_sni_sample_parse_expr(struct server * srv,struct proxy * px,const char * file,int linenum,char ** err)1950 static struct sample_expr *srv_sni_sample_parse_expr(struct server *srv, struct proxy *px,
1951                                                      const char *file, int linenum, char **err)
1952 {
1953 	int idx;
1954 	const char *args[] = {
1955 		srv->sni_expr,
1956 		NULL,
1957 	};
1958 
1959 	idx = 0;
1960 	px->conf.args.ctx = ARGC_SRV;
1961 
1962 	return sample_parse_expr((char **)args, &idx, file, linenum, err, &px->conf.args, NULL);
1963 }
1964 
server_parse_sni_expr(struct server * newsrv,struct proxy * px,char ** err)1965 static int server_parse_sni_expr(struct server *newsrv, struct proxy *px, char **err)
1966 {
1967 	struct sample_expr *expr;
1968 
1969 	expr = srv_sni_sample_parse_expr(newsrv, px, px->conf.file, px->conf.line, err);
1970 	if (!expr) {
1971 		memprintf(err, "error detected while parsing sni expression : %s", *err);
1972 		return ERR_ALERT | ERR_FATAL;
1973 	}
1974 
1975 	if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
1976 		memprintf(err, "error detected while parsing sni expression : "
1977 		          " fetch method '%s' extracts information from '%s', "
1978 		          "none of which is available here.\n",
1979 		          newsrv->sni_expr, sample_src_names(expr->fetch->use));
1980 		return ERR_ALERT | ERR_FATAL;
1981 	}
1982 
1983 	px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
1984 	release_sample_expr(newsrv->ssl_ctx.sni);
1985 	newsrv->ssl_ctx.sni = expr;
1986 
1987 	return 0;
1988 }
1989 
display_parser_err(const char * file,int linenum,char ** args,int cur_arg,int err_code,char ** err)1990 static void display_parser_err(const char *file, int linenum, char **args, int cur_arg, int err_code, char **err)
1991 {
1992 	char *msg = "error encountered while processing ";
1993 	char *quote = "'";
1994 	char *token = args[cur_arg];
1995 
1996 	if (err && *err) {
1997 		indent_msg(err, 2);
1998 		msg = *err;
1999 		quote = "";
2000 		token = "";
2001 	}
2002 
2003 	if (err_code & ERR_WARN && !(err_code & ERR_ALERT))
2004 		ha_warning("parsing [%s:%d] : '%s %s' : %s%s%s%s.\n",
2005 		           file, linenum, args[0], args[1],
2006 		           msg, quote, token, quote);
2007 	else
2008 		ha_alert("parsing [%s:%d] : '%s %s' : %s%s%s%s.\n",
2009 		         file, linenum, args[0], args[1],
2010 		         msg, quote, token, quote);
2011 }
2012 
srv_conn_src_sport_range_cpy(struct server * srv,struct server * src)2013 static void srv_conn_src_sport_range_cpy(struct server *srv,
2014                                             struct server *src)
2015 {
2016 	int range_sz;
2017 
2018 	range_sz = src->conn_src.sport_range->size;
2019 	if (range_sz > 0) {
2020 		srv->conn_src.sport_range = port_range_alloc_range(range_sz);
2021 		if (srv->conn_src.sport_range != NULL) {
2022 			int i;
2023 
2024 			for (i = 0; i < range_sz; i++) {
2025 				srv->conn_src.sport_range->ports[i] =
2026 					src->conn_src.sport_range->ports[i];
2027 			}
2028 		}
2029 	}
2030 }
2031 
2032 /*
2033  * Copy <src> server connection source settings to <srv> server everything needed.
2034  */
srv_conn_src_cpy(struct server * srv,struct server * src)2035 static void srv_conn_src_cpy(struct server *srv, struct server *src)
2036 {
2037 	srv->conn_src.opts = src->conn_src.opts;
2038 	srv->conn_src.source_addr = src->conn_src.source_addr;
2039 
2040 	/* Source port range copy. */
2041 	if (src->conn_src.sport_range != NULL)
2042 		srv_conn_src_sport_range_cpy(srv, src);
2043 
2044 #ifdef CONFIG_HAP_TRANSPARENT
2045 	if (src->conn_src.bind_hdr_name != NULL) {
2046 		srv->conn_src.bind_hdr_name = strdup(src->conn_src.bind_hdr_name);
2047 		srv->conn_src.bind_hdr_len = strlen(src->conn_src.bind_hdr_name);
2048 	}
2049 	srv->conn_src.bind_hdr_occ = src->conn_src.bind_hdr_occ;
2050 	srv->conn_src.tproxy_addr  = src->conn_src.tproxy_addr;
2051 #endif
2052 	if (src->conn_src.iface_name != NULL)
2053 		srv->conn_src.iface_name = strdup(src->conn_src.iface_name);
2054 }
2055 
2056 /*
2057  * Copy <src> server SSL settings to <srv> server allocating
2058  * everything needed.
2059  */
2060 #if defined(USE_OPENSSL)
srv_ssl_settings_cpy(struct server * srv,struct server * src)2061 static void srv_ssl_settings_cpy(struct server *srv, struct server *src)
2062 {
2063 	/* <src> is the current proxy's default server and SSL is enabled */
2064 	if (src == &srv->proxy->defsrv && src->use_ssl == 1)
2065 		srv->flags |= SRV_F_DEFSRV_USE_SSL;
2066 
2067 	if (src->ssl_ctx.ca_file != NULL)
2068 		srv->ssl_ctx.ca_file = strdup(src->ssl_ctx.ca_file);
2069 	if (src->ssl_ctx.crl_file != NULL)
2070 		srv->ssl_ctx.crl_file = strdup(src->ssl_ctx.crl_file);
2071 
2072 	srv->ssl_ctx.verify = src->ssl_ctx.verify;
2073 
2074 	srv->ssl_ctx.ctx = src->ssl_ctx.ctx;
2075 
2076 	if (src->ssl_ctx.verify_host != NULL)
2077 		srv->ssl_ctx.verify_host = strdup(src->ssl_ctx.verify_host);
2078 	if (src->ssl_ctx.ciphers != NULL)
2079 		srv->ssl_ctx.ciphers = strdup(src->ssl_ctx.ciphers);
2080 	if (src->ssl_ctx.options)
2081 		srv->ssl_ctx.options = src->ssl_ctx.options;
2082 	if (src->ssl_ctx.methods.flags)
2083 		srv->ssl_ctx.methods.flags = src->ssl_ctx.methods.flags;
2084 	if (src->ssl_ctx.methods.min)
2085 		srv->ssl_ctx.methods.min = src->ssl_ctx.methods.min;
2086 	if (src->ssl_ctx.methods.max)
2087 		srv->ssl_ctx.methods.max = src->ssl_ctx.methods.max;
2088 
2089 	if (src->ssl_ctx.ciphersuites != NULL)
2090 		srv->ssl_ctx.ciphersuites = strdup(src->ssl_ctx.ciphersuites);
2091 	if (src->sni_expr != NULL)
2092 		srv->sni_expr = strdup(src->sni_expr);
2093 
2094 	if (src->ssl_ctx.alpn_str) {
2095 		srv->ssl_ctx.alpn_str = malloc(src->ssl_ctx.alpn_len);
2096 		if (srv->ssl_ctx.alpn_str) {
2097 			memcpy(srv->ssl_ctx.alpn_str, src->ssl_ctx.alpn_str,
2098 			    src->ssl_ctx.alpn_len);
2099 			srv->ssl_ctx.alpn_len = src->ssl_ctx.alpn_len;
2100 		}
2101 	}
2102 
2103 	if (src->ssl_ctx.npn_str) {
2104 		srv->ssl_ctx.npn_str = malloc(src->ssl_ctx.npn_len);
2105 		if (srv->ssl_ctx.npn_str) {
2106 			memcpy(srv->ssl_ctx.npn_str, src->ssl_ctx.npn_str,
2107 			    src->ssl_ctx.npn_len);
2108 			srv->ssl_ctx.npn_len = src->ssl_ctx.npn_len;
2109 		}
2110 	}
2111 }
2112 #endif
2113 
2114 /*
2115  * Prepare <srv> for hostname resolution.
2116  * May be safely called with a default server as <src> argument (without hostname).
2117  * Returns -1 in case of any allocation failure, 0 if not.
2118  */
srv_prepare_for_resolution(struct server * srv,const char * hostname)2119 int srv_prepare_for_resolution(struct server *srv, const char *hostname)
2120 {
2121 	char *hostname_dn;
2122 	int   hostname_len, hostname_dn_len;
2123 
2124 	if (!hostname)
2125 		return 0;
2126 
2127 	hostname_len    = strlen(hostname);
2128 	hostname_dn     = trash.area;
2129 	hostname_dn_len = resolv_str_to_dn_label(hostname, hostname_len,
2130 	                                         hostname_dn, trash.size);
2131 	if (hostname_dn_len == -1)
2132 		goto err;
2133 
2134 
2135 	free(srv->hostname);
2136 	free(srv->hostname_dn);
2137 	srv->hostname        = strdup(hostname);
2138 	srv->hostname_dn     = strdup(hostname_dn);
2139 	srv->hostname_dn_len = hostname_dn_len;
2140 	if (!srv->hostname || !srv->hostname_dn)
2141 		goto err;
2142 
2143 	return 0;
2144 
2145  err:
2146 	ha_free(&srv->hostname);
2147 	ha_free(&srv->hostname_dn);
2148 	return -1;
2149 }
2150 
2151 /*
2152  * Copy <src> server settings to <srv> server allocating
2153  * everything needed.
2154  * This function is not supposed to be called at any time, but only
2155  * during server settings parsing or during server allocations from
2156  * a server template, and just after having calloc()'ed a new server.
2157  * So, <src> may only be a default server (when parsing server settings)
2158  * or a server template (during server allocations from a server template).
2159  * <srv_tmpl> distinguishes these two cases (must be 1 if <srv> is a template,
2160  * 0 if not).
2161  */
srv_settings_cpy(struct server * srv,struct server * src,int srv_tmpl)2162 static void srv_settings_cpy(struct server *srv, struct server *src, int srv_tmpl)
2163 {
2164 	/* Connection source settings copy */
2165 	srv_conn_src_cpy(srv, src);
2166 
2167 	if (srv_tmpl) {
2168 		srv->addr = src->addr;
2169 		srv->svc_port = src->svc_port;
2170 	}
2171 
2172 	srv->pp_opts = src->pp_opts;
2173 	if (src->rdr_pfx != NULL) {
2174 		srv->rdr_pfx = strdup(src->rdr_pfx);
2175 		srv->rdr_len = src->rdr_len;
2176 	}
2177 	if (src->cookie != NULL) {
2178 		srv->cookie = strdup(src->cookie);
2179 		srv->cklen  = src->cklen;
2180 	}
2181 	srv->use_ssl                  = src->use_ssl;
2182 	srv->check.addr               = src->check.addr;
2183 	srv->agent.addr               = src->agent.addr;
2184 	srv->check.use_ssl            = src->check.use_ssl;
2185 	srv->check.port               = src->check.port;
2186 	srv->check.sni                = src->check.sni;
2187 	srv->check.alpn_str           = src->check.alpn_str;
2188 	srv->check.alpn_len           = src->check.alpn_len;
2189 	/* Note: 'flags' field has potentially been already initialized. */
2190 	srv->flags                   |= src->flags;
2191 	srv->do_check                 = src->do_check;
2192 	srv->do_agent                 = src->do_agent;
2193 	srv->check.inter              = src->check.inter;
2194 	srv->check.fastinter          = src->check.fastinter;
2195 	srv->check.downinter          = src->check.downinter;
2196 	srv->agent.use_ssl            = src->agent.use_ssl;
2197 	srv->agent.port               = src->agent.port;
2198 
2199 	if (src->agent.tcpcheck_rules) {
2200 		srv->agent.tcpcheck_rules = calloc(1, sizeof(*srv->agent.tcpcheck_rules));
2201 		if (srv->agent.tcpcheck_rules) {
2202 			srv->agent.tcpcheck_rules->flags = src->agent.tcpcheck_rules->flags;
2203 			srv->agent.tcpcheck_rules->list  = src->agent.tcpcheck_rules->list;
2204 			LIST_INIT(&srv->agent.tcpcheck_rules->preset_vars);
2205 			dup_tcpcheck_vars(&srv->agent.tcpcheck_rules->preset_vars,
2206 					  &src->agent.tcpcheck_rules->preset_vars);
2207 		}
2208 	}
2209 
2210 	srv->agent.inter              = src->agent.inter;
2211 	srv->agent.fastinter          = src->agent.fastinter;
2212 	srv->agent.downinter          = src->agent.downinter;
2213 	srv->maxqueue                 = src->maxqueue;
2214 	srv->ws                       = src->ws;
2215 	srv->minconn                  = src->minconn;
2216 	srv->maxconn                  = src->maxconn;
2217 	srv->slowstart                = src->slowstart;
2218 	srv->observe                  = src->observe;
2219 	srv->onerror                  = src->onerror;
2220 	srv->onmarkeddown             = src->onmarkeddown;
2221 	srv->onmarkedup               = src->onmarkedup;
2222 	if (src->trackit != NULL)
2223 		srv->trackit = strdup(src->trackit);
2224 	srv->consecutive_errors_limit = src->consecutive_errors_limit;
2225 	srv->uweight = srv->iweight   = src->iweight;
2226 
2227 	srv->check.send_proxy         = src->check.send_proxy;
2228 	/* health: up, but will fall down at first failure */
2229 	srv->check.rise = srv->check.health = src->check.rise;
2230 	srv->check.fall               = src->check.fall;
2231 
2232 	/* Here we check if 'disabled' is the default server state */
2233 	if (src->next_admin & (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT)) {
2234 		srv->next_admin |= SRV_ADMF_CMAINT | SRV_ADMF_FMAINT;
2235 		srv->next_state        = SRV_ST_STOPPED;
2236 		srv->check.state |= CHK_ST_PAUSED;
2237 		srv->check.health = 0;
2238 	}
2239 
2240 	/* health: up but will fall down at first failure */
2241 	srv->agent.rise	= srv->agent.health = src->agent.rise;
2242 	srv->agent.fall	              = src->agent.fall;
2243 
2244 	if (src->resolvers_id != NULL)
2245 		srv->resolvers_id = strdup(src->resolvers_id);
2246 	srv->resolv_opts.family_prio = src->resolv_opts.family_prio;
2247 	srv->resolv_opts.accept_duplicate_ip = src->resolv_opts.accept_duplicate_ip;
2248 	srv->resolv_opts.ignore_weight = src->resolv_opts.ignore_weight;
2249 	if (srv->resolv_opts.family_prio == AF_UNSPEC)
2250 		srv->resolv_opts.family_prio = AF_INET6;
2251 	memcpy(srv->resolv_opts.pref_net,
2252 	       src->resolv_opts.pref_net,
2253 	       sizeof srv->resolv_opts.pref_net);
2254 	srv->resolv_opts.pref_net_nb  = src->resolv_opts.pref_net_nb;
2255 
2256 	srv->init_addr_methods        = src->init_addr_methods;
2257 	srv->init_addr                = src->init_addr;
2258 #if defined(USE_OPENSSL)
2259 	srv_ssl_settings_cpy(srv, src);
2260 #endif
2261 #ifdef TCP_USER_TIMEOUT
2262 	srv->tcp_ut = src->tcp_ut;
2263 #endif
2264 	srv->mux_proto = src->mux_proto;
2265 	srv->pool_purge_delay = src->pool_purge_delay;
2266 	srv->low_idle_conns = src->low_idle_conns;
2267 	srv->max_idle_conns = src->max_idle_conns;
2268 	srv->max_reuse = src->max_reuse;
2269 
2270 	if (srv_tmpl)
2271 		srv->srvrq = src->srvrq;
2272 
2273 	srv->check.via_socks4         = src->check.via_socks4;
2274 	srv->socks4_addr              = src->socks4_addr;
2275 }
2276 
2277 /* allocate a server and attach it to the global servers_list. Returns
2278  * the server on success, otherwise NULL.
2279  */
new_server(struct proxy * proxy)2280 struct server *new_server(struct proxy *proxy)
2281 {
2282 	struct server *srv;
2283 
2284 	srv = calloc(1, sizeof *srv);
2285 	if (!srv)
2286 		return NULL;
2287 
2288 	srv->obj_type = OBJ_TYPE_SERVER;
2289 	srv->proxy = proxy;
2290 	srv->pendconns = EB_ROOT;
2291 	LIST_APPEND(&servers_list, &srv->global_list);
2292 	LIST_INIT(&srv->srv_rec_item);
2293 	LIST_INIT(&srv->ip_rec_item);
2294 
2295 	srv->next_state = SRV_ST_RUNNING; /* early server setup */
2296 	srv->last_change = now.tv_sec;
2297 
2298 	srv->check.obj_type = OBJ_TYPE_CHECK;
2299 	srv->check.status = HCHK_STATUS_INI;
2300 	srv->check.server = srv;
2301 	srv->check.proxy = proxy;
2302 	srv->check.tcpcheck_rules = &proxy->tcpcheck_rules;
2303 
2304 	srv->agent.obj_type = OBJ_TYPE_CHECK;
2305 	srv->agent.status = HCHK_STATUS_INI;
2306 	srv->agent.server = srv;
2307 	srv->agent.proxy = proxy;
2308 	srv->xprt  = srv->check.xprt = srv->agent.xprt = xprt_get(XPRT_RAW);
2309 #if defined(USE_QUIC)
2310 	srv->cids = EB_ROOT_UNIQUE;
2311 #endif
2312 
2313 	srv->extra_counters = NULL;
2314 #ifdef USE_OPENSSL
2315 	HA_RWLOCK_INIT(&srv->ssl_ctx.lock);
2316 #endif
2317 
2318 	/* please don't put default server settings here, they are set in
2319 	 * proxy_preset_defaults().
2320 	 */
2321 	return srv;
2322 }
2323 
2324 /* Increment the dynamic server refcount. */
srv_use_dynsrv(struct server * srv)2325 void srv_use_dynsrv(struct server *srv)
2326 {
2327 	BUG_ON(!(srv->flags & SRV_F_DYNAMIC));
2328 	HA_ATOMIC_INC(&srv->refcount_dynsrv);
2329 }
2330 
2331 /* Decrement the dynamic server refcount. */
srv_release_dynsrv(struct server * srv)2332 static uint srv_release_dynsrv(struct server *srv)
2333 {
2334 	BUG_ON(!(srv->flags & SRV_F_DYNAMIC));
2335 	return HA_ATOMIC_SUB_FETCH(&srv->refcount_dynsrv, 1);
2336 }
2337 
2338 /* Deallocate a server <srv> and its member. <srv> must be allocated. For
2339  * dynamic servers, its refcount is decremented first. The free operations are
2340  * conducted only if the refcount is nul, unless the process is stopping.
2341  *
2342  * As a convenience, <srv.next> is returned if srv is not NULL. It may be useful
2343  * when calling free_server on the list of servers.
2344  */
free_server(struct server * srv)2345 struct server *free_server(struct server *srv)
2346 {
2347 	struct server *next = NULL;
2348 
2349 	next = srv->next;
2350 
2351 	/* For dynamic servers, decrement the reference counter. Only free the
2352 	 * server when reaching zero.
2353 	 */
2354 	if (likely(!(global.mode & MODE_STOPPING))) {
2355 		if (srv->flags & SRV_F_DYNAMIC) {
2356 			if (srv_release_dynsrv(srv))
2357 				goto end;
2358 		}
2359 	}
2360 
2361 	task_destroy(srv->warmup);
2362 	task_destroy(srv->srvrq_check);
2363 
2364 	free(srv->id);
2365 	free(srv->cookie);
2366 	free(srv->hostname);
2367 	free(srv->hostname_dn);
2368 	free((char*)srv->conf.file);
2369 	free(srv->per_thr);
2370 	free(srv->curr_idle_thr);
2371 	free(srv->resolvers_id);
2372 	free(srv->addr_node.key);
2373 	free(srv->lb_nodes);
2374 
2375 	if (srv->use_ssl == 1 || srv->check.use_ssl == 1 || (srv->proxy->options & PR_O_TCPCHK_SSL)) {
2376 		if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->destroy_srv)
2377 			xprt_get(XPRT_SSL)->destroy_srv(srv);
2378 	}
2379 	HA_SPIN_DESTROY(&srv->lock);
2380 
2381 	LIST_DELETE(&srv->global_list);
2382 
2383 	EXTRA_COUNTERS_FREE(srv->extra_counters);
2384 
2385 	free(srv);
2386 	srv = NULL;
2387 
2388  end:
2389 	return next;
2390 }
2391 
2392 /*
2393  * Parse as much as possible such a range string argument: low[-high]
2394  * Set <nb_low> and <nb_high> values so that they may be reused by this loop
2395  * for(int i = nb_low; i <= nb_high; i++)... with nb_low >= 1.
2396  * Fails if 'low' < 0 or 'high' is present and not higher than 'low'.
2397  * Returns 0 if succeeded, -1 if not.
2398  */
_srv_parse_tmpl_range(struct server * srv,const char * arg,int * nb_low,int * nb_high)2399 static int _srv_parse_tmpl_range(struct server *srv, const char *arg,
2400                                  int *nb_low, int *nb_high)
2401 {
2402 	char *nb_high_arg;
2403 
2404 	*nb_high = 0;
2405 	chunk_printf(&trash, "%s", arg);
2406 	*nb_low = atoi(trash.area);
2407 
2408 	if ((nb_high_arg = strchr(trash.area, '-'))) {
2409 		*nb_high_arg++ = '\0';
2410 		*nb_high = atoi(nb_high_arg);
2411 	}
2412 	else {
2413 		*nb_high += *nb_low;
2414 		*nb_low = 1;
2415 	}
2416 
2417 	if (*nb_low < 0 || *nb_high < *nb_low)
2418 		return -1;
2419 
2420 	return 0;
2421 }
2422 
2423 /* Parse as much as possible such a range string argument: low[-high]
2424  * Set <nb_low> and <nb_high> values so that they may be reused by this loop
2425  * for(int i = nb_low; i <= nb_high; i++)... with nb_low >= 1.
2426  *
2427  * This function is first intended to be used through parse_server to
2428  * initialize a new server on startup.
2429  *
2430  * Fails if 'low' < 0 or 'high' is present and not higher than 'low'.
2431  * Returns 0 if succeeded, -1 if not.
2432  */
_srv_parse_set_id_from_prefix(struct server * srv,const char * prefix,int nb)2433 static inline void _srv_parse_set_id_from_prefix(struct server *srv,
2434                                                  const char *prefix, int nb)
2435 {
2436 	chunk_printf(&trash, "%s%d", prefix, nb);
2437 	free(srv->id);
2438 	srv->id = strdup(trash.area);
2439 }
2440 
2441 /* Initialize as much as possible servers from <srv> server template.
2442  * Note that a server template is a special server with
2443  * a few different parameters than a server which has
2444  * been parsed mostly the same way as a server.
2445  *
2446  * This function is first intended to be used through parse_server to
2447  * initialize a new server on startup.
2448  *
2449  * Returns the number of servers successfully allocated,
2450  * 'srv' template included.
2451  */
_srv_parse_tmpl_init(struct server * srv,struct proxy * px)2452 static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
2453 {
2454 	int i;
2455 	struct server *newsrv;
2456 
2457 	for (i = srv->tmpl_info.nb_low + 1; i <= srv->tmpl_info.nb_high; i++) {
2458 		newsrv = new_server(px);
2459 		if (!newsrv)
2460 			goto err;
2461 
2462 		newsrv->conf.file = strdup(srv->conf.file);
2463 		newsrv->conf.line = srv->conf.line;
2464 
2465 		srv_settings_cpy(newsrv, srv, 1);
2466 		srv_prepare_for_resolution(newsrv, srv->hostname);
2467 
2468 		if (newsrv->sni_expr) {
2469 			newsrv->ssl_ctx.sni = srv_sni_sample_parse_expr(newsrv, px, NULL, 0, NULL);
2470 			if (!newsrv->ssl_ctx.sni)
2471 				goto err;
2472 		}
2473 
2474 		/* append to list of servers available to receive an hostname */
2475 		if (newsrv->srvrq)
2476 			LIST_APPEND(&newsrv->srvrq->attached_servers, &newsrv->srv_rec_item);
2477 
2478 		/* Set this new server ID. */
2479 		_srv_parse_set_id_from_prefix(newsrv, srv->tmpl_info.prefix, i);
2480 
2481 		/* Linked backwards first. This will be restablished after parsing. */
2482 		newsrv->next = px->srv;
2483 		px->srv = newsrv;
2484 	}
2485 	_srv_parse_set_id_from_prefix(srv, srv->tmpl_info.prefix, srv->tmpl_info.nb_low);
2486 
2487 	return i - srv->tmpl_info.nb_low;
2488 
2489  err:
2490 	_srv_parse_set_id_from_prefix(srv, srv->tmpl_info.prefix, srv->tmpl_info.nb_low);
2491 	if (newsrv)  {
2492 		release_sample_expr(newsrv->ssl_ctx.sni);
2493 		free_check(&newsrv->agent);
2494 		free_check(&newsrv->check);
2495 		LIST_DELETE(&newsrv->global_list);
2496 	}
2497 	free(newsrv);
2498 	return i - srv->tmpl_info.nb_low;
2499 }
2500 
2501 /* Allocate a new server pointed by <srv> and try to parse the first arguments
2502  * in <args> as an address for a server or an address-range for a template or
2503  * nothing for a default-server. <cur_arg> is incremented to the next argument.
2504  *
2505  * This function is first intended to be used through parse_server to
2506  * initialize a new server on startup.
2507  *
2508  * A mask of errors is returned. On a parsing error, ERR_FATAL is set. In case
2509  * of memory exhaustion, ERR_ABORT is set. If the server cannot be allocated,
2510  * <srv> will be set to NULL.
2511  */
_srv_parse_init(struct server ** srv,char ** args,int * cur_arg,struct proxy * curproxy,int parse_flags,char ** errmsg)2512 static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
2513                            struct proxy *curproxy,
2514                            int parse_flags, char **errmsg)
2515 {
2516 	struct server *newsrv = NULL;
2517 	const char *err = NULL;
2518 	int err_code = 0;
2519 	char *fqdn = NULL;
2520 	int tmpl_range_low = 0, tmpl_range_high = 0;
2521 
2522 	*srv = NULL;
2523 
2524 	/* There is no mandatory first arguments for default server. */
2525 	if (parse_flags & SRV_PARSE_PARSE_ADDR) {
2526 		if (parse_flags & SRV_PARSE_TEMPLATE) {
2527 			if (!*args[3]) {
2528 				/* 'server-template' line number of argument check. */
2529 				memprintf(errmsg, "'%s' expects <prefix> <nb | range> <addr>[:<port>] as arguments.",
2530 				          args[0]);
2531 				err_code |= ERR_ALERT | ERR_FATAL;
2532 				goto out;
2533 			}
2534 
2535 			err = invalid_prefix_char(args[1]);
2536 		}
2537 		else {
2538 			if (!*args[2]) {
2539 				/* 'server' line number of argument check. */
2540 				memprintf(errmsg, "'%s' expects <name> and <addr>[:<port>] as arguments.",
2541 				          args[0]);
2542 				err_code |= ERR_ALERT | ERR_FATAL;
2543 				goto out;
2544 			}
2545 
2546 			err = invalid_char(args[1]);
2547 		}
2548 
2549 		if (err) {
2550 			memprintf(errmsg, "character '%c' is not permitted in %s %s '%s'.",
2551 			          *err, args[0], !(parse_flags & SRV_PARSE_TEMPLATE) ? "name" : "prefix", args[1]);
2552 			err_code |= ERR_ALERT | ERR_FATAL;
2553 			goto out;
2554 		}
2555 	}
2556 
2557 	*cur_arg = 2;
2558 	if (parse_flags & SRV_PARSE_TEMPLATE) {
2559 		/* Parse server-template <nb | range> arg. */
2560 		if (_srv_parse_tmpl_range(newsrv, args[*cur_arg], &tmpl_range_low, &tmpl_range_high) < 0) {
2561 			memprintf(errmsg, "Wrong %s number or range arg '%s'.",
2562 			          args[0], args[*cur_arg]);
2563 			err_code |= ERR_ALERT | ERR_FATAL;
2564 			goto out;
2565 		}
2566 		(*cur_arg)++;
2567 	}
2568 
2569 	if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
2570 		struct sockaddr_storage *sk;
2571 		int port1, port2, port;
2572 
2573 		*srv = newsrv = new_server(curproxy);
2574 		if (!newsrv) {
2575 			memprintf(errmsg, "out of memory.");
2576 			err_code |= ERR_ALERT | ERR_ABORT;
2577 			goto out;
2578 		}
2579 
2580 		if (parse_flags & SRV_PARSE_TEMPLATE) {
2581 			newsrv->tmpl_info.nb_low = tmpl_range_low;
2582 			newsrv->tmpl_info.nb_high = tmpl_range_high;
2583 		}
2584 
2585 		if (parse_flags & SRV_PARSE_DYNAMIC)
2586 			newsrv->flags |= SRV_F_DYNAMIC;
2587 
2588 		/* Note: for a server template, its id is its prefix.
2589 		 * This is a temporary id which will be used for server allocations to come
2590 		 * after parsing.
2591 		 */
2592 		if (!(parse_flags & SRV_PARSE_TEMPLATE))
2593 			newsrv->id = strdup(args[1]);
2594 		else
2595 			newsrv->tmpl_info.prefix = strdup(args[1]);
2596 
2597 		/* several ways to check the port component :
2598 		 *  - IP    => port=+0, relative (IPv4 only)
2599 		 *  - IP:   => port=+0, relative
2600 		 *  - IP:N  => port=N, absolute
2601 		 *  - IP:+N => port=+N, relative
2602 		 *  - IP:-N => port=-N, relative
2603 		 */
2604 		if (!(parse_flags & SRV_PARSE_PARSE_ADDR))
2605 			goto skip_addr;
2606 
2607 		sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, NULL,
2608 		                  errmsg, NULL, &fqdn,
2609 		                  (parse_flags & SRV_PARSE_INITIAL_RESOLVE ? PA_O_RESOLVE : 0) | PA_O_PORT_OK | PA_O_PORT_OFS | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
2610 		if (!sk) {
2611 			memprintf(errmsg, "'%s %s' : %s", args[0], args[1], *errmsg);
2612 			err_code |= ERR_ALERT | ERR_FATAL;
2613 			goto out;
2614 		}
2615 
2616 		if (!port1 || !port2) {
2617 			/* no port specified, +offset, -offset */
2618 			newsrv->flags |= SRV_F_MAPPORTS;
2619 		}
2620 
2621 		/* save hostname and create associated name resolution */
2622 		if (fqdn) {
2623 			if (fqdn[0] == '_') { /* SRV record */
2624 				/* Check if a SRV request already exists, and if not, create it */
2625 				if ((newsrv->srvrq = find_srvrq_by_name(fqdn, curproxy)) == NULL)
2626 					newsrv->srvrq = new_resolv_srvrq(newsrv, fqdn);
2627 				if (newsrv->srvrq == NULL) {
2628 					err_code |= ERR_ALERT | ERR_FATAL;
2629 					goto out;
2630 				}
2631 				LIST_APPEND(&newsrv->srvrq->attached_servers, &newsrv->srv_rec_item);
2632 			}
2633 			else if (srv_prepare_for_resolution(newsrv, fqdn) == -1) {
2634 				memprintf(errmsg, "Can't create DNS resolution for server '%s'",
2635 				          newsrv->id);
2636 				err_code |= ERR_ALERT | ERR_FATAL;
2637 				goto out;
2638 			}
2639 		}
2640 
2641 		newsrv->addr = *sk;
2642 		newsrv->svc_port = port;
2643 		/*
2644 		 * we don't need to lock the server here, because
2645 		 * we are in the process of initializing.
2646 		 *
2647 		 * Note that the server is not attached into the proxy tree if
2648 		 * this is a dynamic server.
2649 		 */
2650 		srv_set_addr_desc(newsrv, !(parse_flags & SRV_PARSE_DYNAMIC));
2651 
2652 		if (!newsrv->srvrq && !newsrv->hostname && !protocol_by_family(newsrv->addr.ss_family)) {
2653 			memprintf(errmsg, "Unknown protocol family %d '%s'",
2654 			          newsrv->addr.ss_family, args[*cur_arg]);
2655 			err_code |= ERR_ALERT | ERR_FATAL;
2656 			goto out;
2657 		}
2658 
2659 		(*cur_arg)++;
2660  skip_addr:
2661 		if (!(parse_flags & SRV_PARSE_DYNAMIC)) {
2662 			/* Copy default server settings to new server */
2663 			srv_settings_cpy(newsrv, &curproxy->defsrv, 0);
2664 		} else {
2665 			/* Initialize dynamic server weight to 1 */
2666 			newsrv->uweight = newsrv->iweight = 1;
2667 
2668 			/* A dynamic server is disabled on startup */
2669 			newsrv->next_admin = SRV_ADMF_FMAINT;
2670 			newsrv->next_state = SRV_ST_STOPPED;
2671 			server_recalc_eweight(newsrv, 0);
2672 		}
2673 		HA_SPIN_INIT(&newsrv->lock);
2674 	}
2675 	else {
2676 		*srv = newsrv = &curproxy->defsrv;
2677 		*cur_arg = 1;
2678 		newsrv->resolv_opts.family_prio = AF_INET6;
2679 		newsrv->resolv_opts.accept_duplicate_ip = 0;
2680 	}
2681 
2682 	free(fqdn);
2683 	return 0;
2684 
2685 out:
2686 	free(fqdn);
2687 	return err_code;
2688 }
2689 
2690 /* Parse the server keyword in <args>.
2691  * <cur_arg> is incremented beyond the keyword optional value. Note that this
2692  * might not be the case if an error is reported.
2693  *
2694  * This function is first intended to be used through parse_server to
2695  * initialize a new server on startup.
2696  *
2697  * A mask of errors is returned. ERR_FATAL is set if the parsing should be
2698  * interrupted.
2699  */
_srv_parse_kw(struct server * srv,char ** args,int * cur_arg,struct proxy * curproxy,int parse_flags,char ** errmsg)2700 static int _srv_parse_kw(struct server *srv, char **args, int *cur_arg,
2701                          struct proxy *curproxy,
2702                          int parse_flags, char **errmsg)
2703 {
2704 	int err_code = 0;
2705 	struct srv_kw *kw;
2706 	const char *best;
2707 
2708 	kw = srv_find_kw(args[*cur_arg]);
2709 	if (!kw) {
2710 		best = srv_find_best_kw(args[*cur_arg]);
2711 		if (best)
2712 			memprintf(errmsg, "unknown keyword '%s'; did you mean '%s' maybe ?",
2713 			          args[*cur_arg], best);
2714 		else
2715 			memprintf(errmsg, "unknown keyword '%s'.",
2716 			          args[*cur_arg]);
2717 
2718 		return ERR_ALERT | ERR_FATAL;
2719 	}
2720 
2721 	if (!kw->parse) {
2722 		memprintf(errmsg, "'%s' option is not implemented in this version (check build options)",
2723 		          args[*cur_arg]);
2724 		err_code = ERR_ALERT | ERR_FATAL;
2725 		goto out;
2726 	}
2727 
2728 	if ((parse_flags & SRV_PARSE_DEFAULT_SERVER) && !kw->default_ok) {
2729 		memprintf(errmsg, "'%s' option is not accepted in default-server sections",
2730 		          args[*cur_arg]);
2731 		err_code = ERR_ALERT;
2732 		goto out;
2733 	}
2734 	else if ((parse_flags & SRV_PARSE_DYNAMIC) && !kw->dynamic_ok) {
2735 		memprintf(errmsg, "'%s' option is not accepted for dynamic server",
2736 		          args[*cur_arg]);
2737 		err_code |= ERR_ALERT;
2738 		goto out;
2739 	}
2740 
2741 	err_code = kw->parse(args, cur_arg, curproxy, srv, errmsg);
2742 
2743 out:
2744 	if (kw->skip != -1)
2745 		*cur_arg += 1 + kw->skip;
2746 
2747 	return err_code;
2748 }
2749 
2750 /* This function is first intended to be used through parse_server to
2751  * initialize a new server on startup.
2752  */
_srv_parse_sni_expr_init(char ** args,int cur_arg,struct server * srv,struct proxy * proxy,char ** errmsg)2753 static int _srv_parse_sni_expr_init(char **args, int cur_arg,
2754                                     struct server *srv, struct proxy *proxy,
2755                                     char **errmsg)
2756 {
2757 	int ret;
2758 
2759 	if (!srv->sni_expr)
2760 		return 0;
2761 
2762 	ret = server_parse_sni_expr(srv, proxy, errmsg);
2763 	if (!ret)
2764 	    return 0;
2765 
2766 	return ret;
2767 }
2768 
2769 /* Server initializations finalization.
2770  * Initialize health check, agent check and SNI expression if enabled.
2771  * Must not be called for a default server instance.
2772  *
2773  * This function is first intended to be used through parse_server to
2774  * initialize a new server on startup.
2775  */
_srv_parse_finalize(char ** args,int cur_arg,struct server * srv,struct proxy * px,int parse_flags,char ** errmsg)2776 static int _srv_parse_finalize(char **args, int cur_arg,
2777                                struct server *srv, struct proxy *px,
2778                                int parse_flags, char **errmsg)
2779 {
2780 	int ret;
2781 
2782 	if (srv->do_check && srv->trackit) {
2783 		memprintf(errmsg, "unable to enable checks and tracking at the same time!");
2784 		return ERR_ALERT | ERR_FATAL;
2785 	}
2786 
2787 	if (srv->do_agent && !srv->agent.port) {
2788 		memprintf(errmsg, "server %s does not have agent port. Agent check has been disabled.",
2789 		          srv->id);
2790 		return ERR_ALERT | ERR_FATAL;
2791 	}
2792 
2793 	if ((ret = _srv_parse_sni_expr_init(args, cur_arg, srv, px, errmsg)) != 0)
2794 		return ret;
2795 
2796 	/* A dynamic server is disabled on startup. It must not be counted as
2797 	 * an active backend entry.
2798 	 */
2799 	if (!(parse_flags & SRV_PARSE_DYNAMIC)) {
2800 		if (srv->flags & SRV_F_BACKUP)
2801 			px->srv_bck++;
2802 		else
2803 			px->srv_act++;
2804 	}
2805 
2806 	srv_lb_commit_status(srv);
2807 
2808 	return 0;
2809 }
2810 
parse_server(const char * file,int linenum,char ** args,struct proxy * curproxy,const struct proxy * defproxy,int parse_flags)2811 int parse_server(const char *file, int linenum, char **args,
2812                  struct proxy *curproxy, const struct proxy *defproxy,
2813                  int parse_flags)
2814 {
2815 	struct server *newsrv = NULL;
2816 	char *errmsg = NULL;
2817 	int err_code = 0;
2818 
2819 	int cur_arg;
2820 
2821 	if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER) && curproxy == defproxy) {
2822 		ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2823 		err_code |= ERR_ALERT | ERR_FATAL;
2824 		goto out;
2825 	}
2826 	else if (failifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
2827 		err_code |= ERR_ALERT | ERR_FATAL;
2828 		goto out;
2829 	}
2830 
2831 	if ((parse_flags & (SRV_PARSE_IN_PEER_SECTION|SRV_PARSE_PARSE_ADDR)) ==
2832 	    (SRV_PARSE_IN_PEER_SECTION|SRV_PARSE_PARSE_ADDR)) {
2833 		if (!*args[2])
2834 			return 0;
2835 	}
2836 
2837 	err_code = _srv_parse_init(&newsrv, args, &cur_arg, curproxy,
2838 	                           parse_flags, &errmsg);
2839 	if (errmsg) {
2840 		ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
2841 		free(errmsg);
2842 	}
2843 
2844 	/* the servers are linked backwards first */
2845 	if (newsrv && !(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
2846 		newsrv->next = curproxy->srv;
2847 		curproxy->srv = newsrv;
2848 	}
2849 
2850 	if (err_code & ERR_CODE)
2851 		goto out;
2852 
2853 	newsrv->conf.file = strdup(file);
2854 	newsrv->conf.line = linenum;
2855 
2856 	while (*args[cur_arg]) {
2857 		errmsg = NULL;
2858 		err_code = _srv_parse_kw(newsrv, args, &cur_arg, curproxy,
2859 		                         parse_flags, &errmsg);
2860 
2861 		if (err_code & ERR_ALERT) {
2862 			display_parser_err(file, linenum, args, cur_arg, err_code, &errmsg);
2863 			free(errmsg);
2864 		}
2865 
2866 		if (err_code & ERR_FATAL)
2867 			goto out;
2868 	}
2869 
2870 	if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
2871 		err_code |= _srv_parse_finalize(args, cur_arg, newsrv, curproxy, parse_flags, &errmsg);
2872 		if (err_code) {
2873 			display_parser_err(file, linenum, args, cur_arg, err_code, &errmsg);
2874 			free(errmsg);
2875 		}
2876 
2877 		if (err_code & ERR_FATAL)
2878 			goto out;
2879 	}
2880 
2881 	if (parse_flags & SRV_PARSE_TEMPLATE)
2882 		_srv_parse_tmpl_init(newsrv, curproxy);
2883 
2884 	/* If the server id is fixed, insert it in the proxy used_id tree.
2885 	 * This is needed to detect a later duplicate id via srv_parse_id.
2886 	 *
2887 	 * If no is specified, a dynamic one is generated in
2888 	 * check_config_validity.
2889 	 */
2890 	if (newsrv->flags & SRV_F_FORCED_ID)
2891 		eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
2892 
2893 	HA_DIAG_WARNING_COND((curproxy->cap & PR_CAP_LB) && !newsrv->uweight,
2894 	                     "parsing [%s:%d] : 'server %s' : configured with weight of 0 will never be selected by load balancing algorithms\n",
2895 	                     file, linenum, newsrv->id);
2896 
2897 	return 0;
2898 
2899  out:
2900 	return err_code;
2901 }
2902 
2903 /* Returns a pointer to the first server matching either id <id>.
2904  * NULL is returned if no match is found.
2905  * the lookup is performed in the backend <bk>
2906  */
server_find_by_id(struct proxy * bk,int id)2907 struct server *server_find_by_id(struct proxy *bk, int id)
2908 {
2909 	struct eb32_node *eb32;
2910 	struct server *curserver;
2911 
2912 	if (!bk || (id ==0))
2913 		return NULL;
2914 
2915 	/* <bk> has no backend capabilities, so it can't have a server */
2916 	if (!(bk->cap & PR_CAP_BE))
2917 		return NULL;
2918 
2919 	curserver = NULL;
2920 
2921 	eb32 = eb32_lookup(&bk->conf.used_server_id, id);
2922 	if (eb32)
2923 		curserver = container_of(eb32, struct server, conf.id);
2924 
2925 	return curserver;
2926 }
2927 
2928 /* Returns a pointer to the first server matching either name <name>, or id
2929  * if <name> starts with a '#'. NULL is returned if no match is found.
2930  * the lookup is performed in the backend <bk>
2931  */
server_find_by_name(struct proxy * bk,const char * name)2932 struct server *server_find_by_name(struct proxy *bk, const char *name)
2933 {
2934 	struct server *curserver;
2935 
2936 	if (!bk || !name)
2937 		return NULL;
2938 
2939 	/* <bk> has no backend capabilities, so it can't have a server */
2940 	if (!(bk->cap & PR_CAP_BE))
2941 		return NULL;
2942 
2943 	curserver = NULL;
2944 	if (*name == '#') {
2945 		curserver = server_find_by_id(bk, atoi(name + 1));
2946 		if (curserver)
2947 			return curserver;
2948 	}
2949 	else {
2950 		curserver = bk->srv;
2951 
2952 		while (curserver && (strcmp(curserver->id, name) != 0))
2953 			curserver = curserver->next;
2954 
2955 		if (curserver)
2956 			return curserver;
2957 	}
2958 
2959 	return NULL;
2960 }
2961 
server_find_best_match(struct proxy * bk,char * name,int id,int * diff)2962 struct server *server_find_best_match(struct proxy *bk, char *name, int id, int *diff)
2963 {
2964 	struct server *byname;
2965 	struct server *byid;
2966 
2967 	if (!name && !id)
2968 		return NULL;
2969 
2970 	if (diff)
2971 		*diff = 0;
2972 
2973 	byname = byid = NULL;
2974 
2975 	if (name) {
2976 		byname = server_find_by_name(bk, name);
2977 		if (byname && (!id || byname->puid == id))
2978 			return byname;
2979 	}
2980 
2981 	/* remaining possibilities :
2982 	 *  - name not set
2983 	 *  - name set but not found
2984 	 *  - name found but ID doesn't match
2985 	 */
2986 	if (id) {
2987 		byid = server_find_by_id(bk, id);
2988 		if (byid) {
2989 			if (byname) {
2990 				/* use id only if forced by configuration */
2991 				if (byid->flags & SRV_F_FORCED_ID) {
2992 					if (diff)
2993 						*diff |= 2;
2994 					return byid;
2995 				}
2996 				else {
2997 					if (diff)
2998 						*diff |= 1;
2999 					return byname;
3000 				}
3001 			}
3002 
3003 			/* remaining possibilities:
3004 			 *   - name not set
3005 			 *   - name set but not found
3006 			 */
3007 			if (name && diff)
3008 				*diff |= 2;
3009 			return byid;
3010 		}
3011 
3012 		/* id bot found */
3013 		if (byname) {
3014 			if (diff)
3015 				*diff |= 1;
3016 			return byname;
3017 		}
3018 	}
3019 
3020 	return NULL;
3021 }
3022 
3023 /*
3024  * update a server's current IP address.
3025  * ip is a pointer to the new IP address, whose address family is ip_sin_family.
3026  * ip is in network format.
3027  * updater is a string which contains an information about the requester of the update.
3028  * updater is used if not NULL.
3029  *
3030  * A log line and a stderr warning message is generated based on server's backend options.
3031  *
3032  * Must be called with the server lock held.
3033  */
srv_update_addr(struct server * s,void * ip,int ip_sin_family,const char * updater)3034 int srv_update_addr(struct server *s, void *ip, int ip_sin_family, const char *updater)
3035 {
3036 	/* save the new IP family & address if necessary */
3037 	switch (ip_sin_family) {
3038 	case AF_INET:
3039 		if (s->addr.ss_family == ip_sin_family &&
3040 		    !memcmp(ip, &((struct sockaddr_in *)&s->addr)->sin_addr.s_addr, 4))
3041 			return 0;
3042 		break;
3043 	case AF_INET6:
3044 		if (s->addr.ss_family == ip_sin_family &&
3045 		    !memcmp(ip, &((struct sockaddr_in6 *)&s->addr)->sin6_addr.s6_addr, 16))
3046 			return 0;
3047 		break;
3048 	};
3049 
3050 	/* generates a log line and a warning on stderr */
3051 	if (1) {
3052 		/* book enough space for both IPv4 and IPv6 */
3053 		char oldip[INET6_ADDRSTRLEN];
3054 		char newip[INET6_ADDRSTRLEN];
3055 
3056 		memset(oldip, '\0', INET6_ADDRSTRLEN);
3057 		memset(newip, '\0', INET6_ADDRSTRLEN);
3058 
3059 		/* copy old IP address in a string */
3060 		switch (s->addr.ss_family) {
3061 		case AF_INET:
3062 			inet_ntop(s->addr.ss_family, &((struct sockaddr_in *)&s->addr)->sin_addr, oldip, INET_ADDRSTRLEN);
3063 			break;
3064 		case AF_INET6:
3065 			inet_ntop(s->addr.ss_family, &((struct sockaddr_in6 *)&s->addr)->sin6_addr, oldip, INET6_ADDRSTRLEN);
3066 			break;
3067 		default:
3068 			strcpy(oldip, "(none)");
3069 			break;
3070 		};
3071 
3072 		/* copy new IP address in a string */
3073 		switch (ip_sin_family) {
3074 		case AF_INET:
3075 			inet_ntop(ip_sin_family, ip, newip, INET_ADDRSTRLEN);
3076 			break;
3077 		case AF_INET6:
3078 			inet_ntop(ip_sin_family, ip, newip, INET6_ADDRSTRLEN);
3079 			break;
3080 		};
3081 
3082 		/* save log line into a buffer */
3083 		chunk_printf(&trash, "%s/%s changed its IP from %s to %s by %s",
3084 				s->proxy->id, s->id, oldip, newip, updater);
3085 
3086 		/* write the buffer on stderr */
3087 		ha_warning("%s.\n", trash.area);
3088 
3089 		/* send a log */
3090 		send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.area);
3091 	}
3092 
3093 	/* save the new IP family */
3094 	s->addr.ss_family = ip_sin_family;
3095 	/* save the new IP address */
3096 	switch (ip_sin_family) {
3097 	case AF_INET:
3098 		memcpy(&((struct sockaddr_in *)&s->addr)->sin_addr.s_addr, ip, 4);
3099 		break;
3100 	case AF_INET6:
3101 		memcpy(((struct sockaddr_in6 *)&s->addr)->sin6_addr.s6_addr, ip, 16);
3102 		break;
3103 	};
3104 	srv_set_dyncookie(s);
3105 	srv_set_addr_desc(s, 1);
3106 
3107 	return 0;
3108 }
3109 
3110 /* update agent health check address and port
3111  * addr can be ip4/ip6 or a hostname
3112  * if one error occurs, don't apply anything
3113  * must be called with the server lock held.
3114  */
srv_update_agent_addr_port(struct server * s,const char * addr,const char * port)3115 const char *srv_update_agent_addr_port(struct server *s, const char *addr, const char *port)
3116 {
3117 	struct sockaddr_storage sk;
3118 	struct buffer *msg;
3119 	int new_port;
3120 
3121 	msg = get_trash_chunk();
3122 	chunk_reset(msg);
3123 
3124 	if (!(s->agent.state & CHK_ST_ENABLED)) {
3125 		chunk_strcat(msg, "agent checks are not enabled on this server");
3126 		goto out;
3127 	}
3128 	if (addr) {
3129 		memset(&sk, 0, sizeof(struct sockaddr_storage));
3130 		if (str2ip(addr, &sk) == NULL) {
3131 			chunk_appendf(msg, "invalid addr '%s'", addr);
3132 			goto out;
3133 		}
3134 	}
3135 	if (port) {
3136 		if (strl2irc(port, strlen(port), &new_port) != 0) {
3137 			chunk_appendf(msg, "provided port is not an integer");
3138 			goto out;
3139 		}
3140 		if (new_port < 0 || new_port > 65535) {
3141 			chunk_appendf(msg, "provided port is invalid");
3142 			goto out;
3143 		}
3144 	}
3145 out:
3146 	if (msg->data)
3147 		return msg->area;
3148 	else {
3149 		if (addr)
3150 			set_srv_agent_addr(s, &sk);
3151 		if (port)
3152 			set_srv_agent_port(s, new_port);
3153 	}
3154 	return NULL;
3155 }
3156 
3157 /* update server health check address and port
3158  * addr must be ip4 or ip6, it won't be resolved
3159  * if one error occurs, don't apply anything
3160  * must be called with the server lock held.
3161  */
srv_update_check_addr_port(struct server * s,const char * addr,const char * port)3162 const char *srv_update_check_addr_port(struct server *s, const char *addr, const char *port)
3163 {
3164 	struct sockaddr_storage sk;
3165 	struct buffer *msg;
3166 	int new_port;
3167 
3168 	msg = get_trash_chunk();
3169 	chunk_reset(msg);
3170 
3171 	if (!(s->check.state & CHK_ST_ENABLED)) {
3172 		chunk_strcat(msg, "health checks are not enabled on this server");
3173 		goto out;
3174 	}
3175 	if (addr) {
3176 		memset(&sk, 0, sizeof(struct sockaddr_storage));
3177 		if (str2ip2(addr, &sk, 0) == NULL) {
3178 			chunk_appendf(msg, "invalid addr '%s'", addr);
3179 			goto out;
3180 		}
3181 	}
3182 	if (port) {
3183 		if (strl2irc(port, strlen(port), &new_port) != 0) {
3184 			chunk_appendf(msg, "provided port is not an integer");
3185 			goto out;
3186 		}
3187 		if (new_port < 0 || new_port > 65535) {
3188 			chunk_appendf(msg, "provided port is invalid");
3189 			goto out;
3190 		}
3191 		/* prevent the update of port to 0 if MAPPORTS are in use */
3192 		if ((s->flags & SRV_F_MAPPORTS) && new_port == 0) {
3193 			chunk_appendf(msg, "can't unset 'port' since MAPPORTS is in use");
3194 			goto out;
3195 		}
3196 	}
3197 out:
3198 	if (msg->data)
3199 		return msg->area;
3200 	else {
3201 		if (addr)
3202 			s->check.addr = sk;
3203 		if (port)
3204 			s->check.port = new_port;
3205 	}
3206 	return NULL;
3207 }
3208 
3209 /*
3210  * This function update a server's addr and port only for AF_INET and AF_INET6 families.
3211  *
3212  * Caller can pass its name through <updater> to get it integrated in the response message
3213  * returned by the function.
3214  *
3215  * The function first does the following, in that order:
3216  * - validates the new addr and/or port
3217  * - checks if an update is required (new IP or port is different than current ones)
3218  * - checks the update is allowed:
3219  *   - don't switch from/to a family other than AF_INET4 and AF_INET6
3220  *   - allow all changes if no CHECKS are configured
3221  *   - if CHECK is configured:
3222  *     - if switch to port map (SRV_F_MAPPORTS), ensure health check have their own ports
3223  * - applies required changes to both ADDR and PORT if both 'required' and 'allowed'
3224  *   conditions are met
3225  *
3226  * Must be called with the server lock held.
3227  */
srv_update_addr_port(struct server * s,const char * addr,const char * port,char * updater)3228 const char *srv_update_addr_port(struct server *s, const char *addr, const char *port, char *updater)
3229 {
3230 	struct sockaddr_storage sa;
3231 	int ret, port_change_required;
3232 	char current_addr[INET6_ADDRSTRLEN];
3233 	uint16_t current_port, new_port;
3234 	struct buffer *msg;
3235 	int changed = 0;
3236 
3237 	msg = get_trash_chunk();
3238 	chunk_reset(msg);
3239 
3240 	if (addr) {
3241 		memset(&sa, 0, sizeof(struct sockaddr_storage));
3242 		if (str2ip2(addr, &sa, 0) == NULL) {
3243 			chunk_printf(msg, "Invalid addr '%s'", addr);
3244 			goto out;
3245 		}
3246 
3247 		/* changes are allowed on AF_INET* families only */
3248 		if ((sa.ss_family != AF_INET) && (sa.ss_family != AF_INET6)) {
3249 			chunk_printf(msg, "Update to families other than AF_INET and AF_INET6 supported only through configuration file");
3250 			goto out;
3251 		}
3252 
3253 		/* collecting data currently setup */
3254 		memset(current_addr, '\0', sizeof(current_addr));
3255 		ret = addr_to_str(&s->addr, current_addr, sizeof(current_addr));
3256 		/* changes are allowed on AF_INET* families only */
3257 		if ((ret != AF_INET) && (ret != AF_INET6)) {
3258 			chunk_printf(msg, "Update for the current server address family is only supported through configuration file");
3259 			goto out;
3260 		}
3261 
3262 		/* applying ADDR changes if required and allowed
3263 		 * ipcmp returns 0 when both ADDR are the same
3264 		 */
3265 		if (ipcmp(&s->addr, &sa) == 0) {
3266 			chunk_appendf(msg, "no need to change the addr");
3267 			goto port;
3268 		}
3269 		ipcpy(&sa, &s->addr);
3270 		changed = 1;
3271 
3272 		/* update report for caller */
3273 		chunk_printf(msg, "IP changed from '%s' to '%s'", current_addr, addr);
3274 	}
3275 
3276  port:
3277 	if (port) {
3278 		char sign = '\0';
3279 		char *endptr;
3280 
3281 		if (addr)
3282 			chunk_appendf(msg, ", ");
3283 
3284 		/* collecting data currently setup */
3285 		current_port = s->svc_port;
3286 
3287 		/* check if PORT change is required */
3288 		port_change_required = 0;
3289 
3290 		sign = *port;
3291 		errno = 0;
3292 		new_port = strtol(port, &endptr, 10);
3293 		if ((errno != 0) || (port == endptr)) {
3294 			chunk_appendf(msg, "problem converting port '%s' to an int", port);
3295 			goto out;
3296 		}
3297 
3298 		/* check if caller triggers a port mapped or offset */
3299 		if (sign == '-' || (sign == '+')) {
3300 			/* check if server currently uses port map */
3301 			if (!(s->flags & SRV_F_MAPPORTS)) {
3302 				/* switch from fixed port to port map mandatorily triggers
3303 				 * a port change */
3304 				port_change_required = 1;
3305 				/* check is configured
3306 				 * we're switching from a fixed port to a SRV_F_MAPPORTS (mapped) port
3307 				 * prevent PORT change if check doesn't have it's dedicated port while switching
3308 				 * to port mapping */
3309 				if (!s->check.port) {
3310 					chunk_appendf(msg, "can't change <port> to port map because it is incompatible with current health check port configuration (use 'port' statement from the 'server' directive.");
3311 					goto out;
3312 				}
3313 			}
3314 			/* we're already using port maps */
3315 			else {
3316 				port_change_required = current_port != new_port;
3317 			}
3318 		}
3319 		/* fixed port */
3320 		else {
3321 			port_change_required = current_port != new_port;
3322 		}
3323 
3324 		/* applying PORT changes if required and update response message */
3325 		if (port_change_required) {
3326 			/* apply new port */
3327 			s->svc_port = new_port;
3328 			changed = 1;
3329 
3330 			/* prepare message */
3331 			chunk_appendf(msg, "port changed from '");
3332 			if (s->flags & SRV_F_MAPPORTS)
3333 				chunk_appendf(msg, "+");
3334 			chunk_appendf(msg, "%d' to '", current_port);
3335 
3336 			if (sign == '-') {
3337 				s->flags |= SRV_F_MAPPORTS;
3338 				chunk_appendf(msg, "%c", sign);
3339 				/* just use for result output */
3340 				new_port = -new_port;
3341 			}
3342 			else if (sign == '+') {
3343 				s->flags |= SRV_F_MAPPORTS;
3344 				chunk_appendf(msg, "%c", sign);
3345 			}
3346 			else {
3347 				s->flags &= ~SRV_F_MAPPORTS;
3348 			}
3349 
3350 			chunk_appendf(msg, "%d'", new_port);
3351 		}
3352 		else {
3353 			chunk_appendf(msg, "no need to change the port");
3354 		}
3355 	}
3356 
3357 out:
3358 	if (changed) {
3359 		/* force connection cleanup on the given server */
3360 		srv_cleanup_connections(s);
3361 		srv_set_dyncookie(s);
3362 		srv_set_addr_desc(s, 1);
3363 	}
3364 	if (updater)
3365 		chunk_appendf(msg, " by '%s'", updater);
3366 	chunk_appendf(msg, "\n");
3367 	return msg->area;
3368 }
3369 
3370 /*
3371  * update server status based on result of SRV resolution
3372  * returns:
3373  *  0 if server status is updated
3374  *  1 if server status has not changed
3375  *
3376  * Must be called with the server lock held.
3377  */
srvrq_update_srv_status(struct server * s,int has_no_ip)3378 int srvrq_update_srv_status(struct server *s, int has_no_ip)
3379 {
3380 	if (!s->srvrq)
3381 		return 1;
3382 
3383 	/* since this server has an IP, it can go back in production */
3384 	if (has_no_ip == 0) {
3385 		srv_clr_admin_flag(s, SRV_ADMF_RMAINT);
3386 		return 1;
3387 	}
3388 
3389 	if (s->next_admin & SRV_ADMF_RMAINT)
3390 		return 1;
3391 
3392 	srv_set_admin_flag(s, SRV_ADMF_RMAINT, "entry removed from SRV record");
3393 	return 0;
3394 }
3395 
3396 /*
3397  * update server status based on result of name resolution
3398  * returns:
3399  *  0 if server status is updated
3400  *  1 if server status has not changed
3401  *
3402  * Must be called with the server lock held.
3403  */
snr_update_srv_status(struct server * s,int has_no_ip)3404 int snr_update_srv_status(struct server *s, int has_no_ip)
3405 {
3406 	struct resolvers  *resolvers  = s->resolvers;
3407 	struct resolv_resolution *resolution = (s->resolv_requester ? s->resolv_requester->resolution : NULL);
3408 	int exp;
3409 
3410 	/* If resolution is NULL we're dealing with SRV records Additional records */
3411 	if (resolution == NULL)
3412 		return srvrq_update_srv_status(s, has_no_ip);
3413 
3414 	switch (resolution->status) {
3415 		case RSLV_STATUS_NONE:
3416 			/* status when HAProxy has just (re)started.
3417 			 * Nothing to do, since the task is already automatically started */
3418 			break;
3419 
3420 		case RSLV_STATUS_VALID:
3421 			/*
3422 			 * resume health checks
3423 			 * server will be turned back on if health check is safe
3424 			 */
3425 			if (has_no_ip) {
3426 				if (s->next_admin & SRV_ADMF_RMAINT)
3427 					return 1;
3428 				srv_set_admin_flag(s, SRV_ADMF_RMAINT,
3429 				    "No IP for server ");
3430 				return 0;
3431 			}
3432 
3433 			if (!(s->next_admin & SRV_ADMF_RMAINT))
3434 				return 1;
3435 			srv_clr_admin_flag(s, SRV_ADMF_RMAINT);
3436 			chunk_printf(&trash, "Server %s/%s administratively READY thanks to valid DNS answer",
3437 			             s->proxy->id, s->id);
3438 
3439 			ha_warning("%s.\n", trash.area);
3440 			send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.area);
3441 			return 0;
3442 
3443 		case RSLV_STATUS_NX:
3444 			/* stop server if resolution is NX for a long enough period */
3445 			exp = tick_add(resolution->last_valid, resolvers->hold.nx);
3446 			if (!tick_is_expired(exp, now_ms))
3447 				break;
3448 
3449 			if (s->next_admin & SRV_ADMF_RMAINT)
3450 				return 1;
3451 			srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS NX status");
3452 			return 0;
3453 
3454 		case RSLV_STATUS_TIMEOUT:
3455 			/* stop server if resolution is TIMEOUT for a long enough period */
3456 			exp = tick_add(resolution->last_valid, resolvers->hold.timeout);
3457 			if (!tick_is_expired(exp, now_ms))
3458 				break;
3459 
3460 			if (s->next_admin & SRV_ADMF_RMAINT)
3461 				return 1;
3462 			srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS timeout status");
3463 			return 0;
3464 
3465 		case RSLV_STATUS_REFUSED:
3466 			/* stop server if resolution is REFUSED for a long enough period */
3467 			exp = tick_add(resolution->last_valid, resolvers->hold.refused);
3468 			if (!tick_is_expired(exp, now_ms))
3469 				break;
3470 
3471 			if (s->next_admin & SRV_ADMF_RMAINT)
3472 				return 1;
3473 			srv_set_admin_flag(s, SRV_ADMF_RMAINT, "DNS refused status");
3474 			return 0;
3475 
3476 		default:
3477 			/* stop server if resolution failed for a long enough period */
3478 			exp = tick_add(resolution->last_valid, resolvers->hold.other);
3479 			if (!tick_is_expired(exp, now_ms))
3480 				break;
3481 
3482 			if (s->next_admin & SRV_ADMF_RMAINT)
3483 				return 1;
3484 			srv_set_admin_flag(s, SRV_ADMF_RMAINT, "unspecified DNS error");
3485 			return 0;
3486 	}
3487 
3488 	return 1;
3489 }
3490 
3491 /*
3492  * Server Name Resolution valid response callback
3493  * It expects:
3494  *  - <nameserver>: the name server which answered the valid response
3495  *  - <response>: buffer containing a valid DNS response
3496  *  - <response_len>: size of <response>
3497  * It performs the following actions:
3498  *  - ignore response if current ip found and server family not met
3499  *  - update with first new ip found if family is met and current IP is not found
3500  * returns:
3501  *  0 on error
3502  *  1 when no error or safe ignore
3503  *
3504  * Must be called with server lock held
3505  */
snr_resolution_cb(struct resolv_requester * requester,struct dns_counters * counters)3506 int snr_resolution_cb(struct resolv_requester *requester, struct dns_counters *counters)
3507 {
3508 	struct server *s = NULL;
3509 	struct resolv_resolution *resolution = NULL;
3510 	void *serverip, *firstip;
3511 	short server_sin_family, firstip_sin_family;
3512 	int ret;
3513 	struct buffer *chk = get_trash_chunk();
3514 	int has_no_ip = 0;
3515 
3516 	s = objt_server(requester->owner);
3517 	if (!s)
3518 		return 1;
3519 
3520 	if (s->srvrq) {
3521 		/* If DNS resolution is disabled ignore it.
3522 		 * This is the case if the server was associated to
3523 		 * a SRV record and this record is now expired.
3524 		 */
3525 		if (s->flags & SRV_F_NO_RESOLUTION)
3526 			return 1;
3527 	}
3528 
3529 	resolution = (s->resolv_requester ? s->resolv_requester->resolution : NULL);
3530 	if (!resolution)
3531 		return 1;
3532 
3533 	/* initializing variables */
3534 	firstip = NULL;		/* pointer to the first valid response found */
3535 				/* it will be used as the new IP if a change is required */
3536 	firstip_sin_family = AF_UNSPEC;
3537 	serverip = NULL;	/* current server IP address */
3538 
3539 	/* initializing server IP pointer */
3540 	server_sin_family = s->addr.ss_family;
3541 	switch (server_sin_family) {
3542 		case AF_INET:
3543 			serverip = &((struct sockaddr_in *)&s->addr)->sin_addr.s_addr;
3544 			break;
3545 
3546 		case AF_INET6:
3547 			serverip = &((struct sockaddr_in6 *)&s->addr)->sin6_addr.s6_addr;
3548 			break;
3549 
3550 		case AF_UNSPEC:
3551 			break;
3552 
3553 		default:
3554 			goto invalid;
3555 	}
3556 
3557 	ret = resolv_get_ip_from_response(&resolution->response, &s->resolv_opts,
3558 	                                  serverip, server_sin_family, &firstip,
3559 	                                  &firstip_sin_family, s);
3560 
3561 	switch (ret) {
3562 		case RSLV_UPD_NO:
3563 			goto update_status;
3564 
3565 		case RSLV_UPD_SRVIP_NOT_FOUND:
3566 			goto save_ip;
3567 
3568 		case RSLV_UPD_NO_IP_FOUND:
3569 			has_no_ip = 1;
3570 			goto update_status;
3571 
3572 		case RSLV_UPD_NAME_ERROR:
3573 			/* update resolution status to OTHER error type */
3574 			resolution->status = RSLV_STATUS_OTHER;
3575 			has_no_ip = 1;
3576 			goto update_status;
3577 
3578 		default:
3579 			has_no_ip = 1;
3580 			goto invalid;
3581 
3582 	}
3583 
3584  save_ip:
3585 	if (counters) {
3586 		counters->update++;
3587 		/* save the first ip we found */
3588 		chunk_printf(chk, "%s/%s", counters->pid, counters->id);
3589 	}
3590 	else
3591 		chunk_printf(chk, "DNS cache");
3592 	srv_update_addr(s, firstip, firstip_sin_family, (char *) chk->area);
3593 
3594  update_status:
3595 	if (!snr_update_srv_status(s, has_no_ip) && has_no_ip)
3596 		memset(&s->addr, 0, sizeof(s->addr));
3597 	return 1;
3598 
3599  invalid:
3600 	if (counters) {
3601 		counters->invalid++;
3602 		goto update_status;
3603 	}
3604 	if (!snr_update_srv_status(s, has_no_ip) && has_no_ip)
3605 		memset(&s->addr, 0, sizeof(s->addr));
3606 	return 0;
3607 }
3608 
3609 /*
3610  * SRV record error management callback
3611  * returns:
3612  *  0 if we can trash answser items.
3613  *  1 when safely ignored and we must kept answer items
3614  *
3615  * Grabs the server's lock.
3616  */
srvrq_resolution_error_cb(struct resolv_requester * requester,int error_code)3617 int srvrq_resolution_error_cb(struct resolv_requester *requester, int error_code)
3618 {
3619 	struct resolv_srvrq *srvrq;
3620 	struct resolv_resolution *res;
3621 	struct resolvers *resolvers;
3622 	int exp;
3623 
3624 	/* SRV records */
3625 	srvrq = objt_resolv_srvrq(requester->owner);
3626 	if (!srvrq)
3627 		return 0;
3628 
3629 	resolvers = srvrq->resolvers;
3630 	res = requester->resolution;
3631 
3632 	switch (res->status) {
3633 
3634 		case RSLV_STATUS_NX:
3635 			/* stop server if resolution is NX for a long enough period */
3636 			exp = tick_add(res->last_valid, resolvers->hold.nx);
3637 			if (!tick_is_expired(exp, now_ms))
3638 				return 1;
3639 			break;
3640 
3641 		case RSLV_STATUS_TIMEOUT:
3642 			/* stop server if resolution is TIMEOUT for a long enough period */
3643 			exp = tick_add(res->last_valid, resolvers->hold.timeout);
3644 			if (!tick_is_expired(exp, now_ms))
3645 				return 1;
3646 			break;
3647 
3648 		case RSLV_STATUS_REFUSED:
3649 			/* stop server if resolution is REFUSED for a long enough period */
3650 			exp = tick_add(res->last_valid, resolvers->hold.refused);
3651 			if (!tick_is_expired(exp, now_ms))
3652 				return 1;
3653 			break;
3654 
3655 		default:
3656 			/* stop server if resolution failed for a long enough period */
3657 			exp = tick_add(res->last_valid, resolvers->hold.other);
3658 			if (!tick_is_expired(exp, now_ms))
3659 				return 1;
3660 	}
3661 
3662 	/* Remove any associated server ref */
3663 	resolv_detach_from_resolution_answer_items(res,  requester);
3664 
3665 	return 0;
3666 }
3667 
3668 /*
3669  * Server Name Resolution error management callback
3670  * returns:
3671  *  0 if we can trash answser items.
3672  *  1 when safely ignored and we must kept answer items
3673  *
3674  * Grabs the server's lock.
3675  */
snr_resolution_error_cb(struct resolv_requester * requester,int error_code)3676 int snr_resolution_error_cb(struct resolv_requester *requester, int error_code)
3677 {
3678 	struct server *s;
3679 
3680 	s = objt_server(requester->owner);
3681 	if (!s)
3682 		return 0;
3683 
3684 	HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
3685 	if (!snr_update_srv_status(s, 1)) {
3686 		memset(&s->addr, 0, sizeof(s->addr));
3687 		HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
3688 		resolv_detach_from_resolution_answer_items(requester->resolution, requester);
3689 		return 0;
3690 	}
3691 	HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
3692 
3693 	return 1;
3694 }
3695 
3696 /*
3697  * Function to check if <ip> is already affected to a server in the backend
3698  * which owns <srv> and is up.
3699  * It returns a pointer to the first server found or NULL if <ip> is not yet
3700  * assigned.
3701  *
3702  * Must be called with server lock held
3703  */
snr_check_ip_callback(struct server * srv,void * ip,unsigned char * ip_family)3704 struct server *snr_check_ip_callback(struct server *srv, void *ip, unsigned char *ip_family)
3705 {
3706 	struct server *tmpsrv;
3707 	struct proxy *be;
3708 
3709 	if (!srv)
3710 		return NULL;
3711 
3712 	be = srv->proxy;
3713 	for (tmpsrv = be->srv; tmpsrv; tmpsrv = tmpsrv->next) {
3714 		/* we found the current server is the same, ignore it */
3715 		if (srv == tmpsrv)
3716 			continue;
3717 
3718 		/* We want to compare the IP in the record with the IP of the servers in the
3719 		 * same backend, only if:
3720 		 *   * DNS resolution is enabled on the server
3721 		 *   * the hostname used for the resolution by our server is the same than the
3722 		 *     one used for the server found in the backend
3723 		 *   * the server found in the backend is not our current server
3724 		 */
3725 		HA_SPIN_LOCK(SERVER_LOCK, &tmpsrv->lock);
3726 		if ((tmpsrv->hostname_dn == NULL) ||
3727 		    (srv->hostname_dn_len != tmpsrv->hostname_dn_len) ||
3728 		    (strcasecmp(srv->hostname_dn, tmpsrv->hostname_dn) != 0) ||
3729 		    (srv->puid == tmpsrv->puid)) {
3730 			HA_SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
3731 			continue;
3732 		}
3733 
3734 		/* If the server has been taken down, don't consider it */
3735 		if (tmpsrv->next_admin & SRV_ADMF_RMAINT) {
3736 			HA_SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
3737 			continue;
3738 		}
3739 
3740 		/* At this point, we have 2 different servers using the same DNS hostname
3741 		 * for their respective resolution.
3742 		 */
3743 		if (*ip_family == tmpsrv->addr.ss_family &&
3744 		    ((tmpsrv->addr.ss_family == AF_INET &&
3745 		      memcmp(ip, &((struct sockaddr_in *)&tmpsrv->addr)->sin_addr, 4) == 0) ||
3746 		     (tmpsrv->addr.ss_family == AF_INET6 &&
3747 		      memcmp(ip, &((struct sockaddr_in6 *)&tmpsrv->addr)->sin6_addr, 16) == 0))) {
3748 			HA_SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
3749 			return tmpsrv;
3750 		}
3751 		HA_SPIN_UNLOCK(SERVER_LOCK, &tmpsrv->lock);
3752 	}
3753 
3754 
3755 	return NULL;
3756 }
3757 
3758 /* Sets the server's address (srv->addr) from srv->hostname using the libc's
3759  * resolver. This is suited for initial address configuration. Returns 0 on
3760  * success otherwise a non-zero error code. In case of error, *err_code, if
3761  * not NULL, is filled up.
3762  */
srv_set_addr_via_libc(struct server * srv,int * err_code)3763 int srv_set_addr_via_libc(struct server *srv, int *err_code)
3764 {
3765 	if (str2ip2(srv->hostname, &srv->addr, 1) == NULL) {
3766 		if (err_code)
3767 			*err_code |= ERR_WARN;
3768 		return 1;
3769 	}
3770 	return 0;
3771 }
3772 
3773 /* Set the server's FDQN (->hostname) from <hostname>.
3774  * Returns -1 if failed, 0 if not.
3775  *
3776  * Must be called with the server lock held.
3777  */
srv_set_fqdn(struct server * srv,const char * hostname,int resolv_locked)3778 int srv_set_fqdn(struct server *srv, const char *hostname, int resolv_locked)
3779 {
3780 	struct resolv_resolution *resolution;
3781 	char                  *hostname_dn;
3782 	int                    hostname_len, hostname_dn_len;
3783 
3784 	/* Note that the server lock is already held. */
3785 	if (!srv->resolvers)
3786 		return -1;
3787 
3788 	if (!resolv_locked)
3789 		HA_SPIN_LOCK(DNS_LOCK, &srv->resolvers->lock);
3790 	/* run time DNS/SRV resolution was not active for this server
3791 	 * and we can't enable it at run time for now.
3792 	 */
3793 	if (!srv->resolv_requester && !srv->srvrq)
3794 		goto err;
3795 
3796 	chunk_reset(&trash);
3797 	hostname_len    = strlen(hostname);
3798 	hostname_dn     = trash.area;
3799 	hostname_dn_len = resolv_str_to_dn_label(hostname, hostname_len,
3800 	                                         hostname_dn, trash.size);
3801 	if (hostname_dn_len == -1)
3802 		goto err;
3803 
3804 	resolution = (srv->resolv_requester ? srv->resolv_requester->resolution : NULL);
3805 	if (resolution &&
3806 	    resolution->hostname_dn &&
3807 	    resolution->hostname_dn_len == hostname_dn_len &&
3808 	    strcasecmp(resolution->hostname_dn, hostname_dn) == 0)
3809 		goto end;
3810 
3811 	resolv_unlink_resolution(srv->resolv_requester);
3812 
3813 	free(srv->hostname);
3814 	free(srv->hostname_dn);
3815 	srv->hostname        = strdup(hostname);
3816 	srv->hostname_dn     = strdup(hostname_dn);
3817 	srv->hostname_dn_len = hostname_dn_len;
3818 	if (!srv->hostname || !srv->hostname_dn)
3819 		goto err;
3820 
3821 	if (srv->flags & SRV_F_NO_RESOLUTION)
3822 		goto end;
3823 
3824 	if (resolv_link_resolution(srv, OBJ_TYPE_SERVER, 1) == -1)
3825 		goto err;
3826 
3827   end:
3828 	if (!resolv_locked)
3829 		HA_SPIN_UNLOCK(DNS_LOCK, &srv->resolvers->lock);
3830 	return 0;
3831 
3832   err:
3833 	if (!resolv_locked)
3834 		HA_SPIN_UNLOCK(DNS_LOCK, &srv->resolvers->lock);
3835 	return -1;
3836 }
3837 
3838 /* Sets the server's address (srv->addr) from srv->lastaddr which was filled
3839  * from the state file. This is suited for initial address configuration.
3840  * Returns 0 on success otherwise a non-zero error code. In case of error,
3841  * *err_code, if not NULL, is filled up.
3842  */
srv_apply_lastaddr(struct server * srv,int * err_code)3843 static int srv_apply_lastaddr(struct server *srv, int *err_code)
3844 {
3845 	if (!str2ip2(srv->lastaddr, &srv->addr, 0)) {
3846 		if (err_code)
3847 			*err_code |= ERR_WARN;
3848 		return 1;
3849 	}
3850 	return 0;
3851 }
3852 
3853 /* returns 0 if no error, otherwise a combination of ERR_* flags */
srv_iterate_initaddr(struct server * srv)3854 static int srv_iterate_initaddr(struct server *srv)
3855 {
3856 	char *name = srv->hostname;
3857 	int return_code = 0;
3858 	int err_code;
3859 	unsigned int methods;
3860 
3861 	/* If no addr and no hostname set, get the name from the DNS SRV request */
3862 	if (!name && srv->srvrq)
3863 		name = srv->srvrq->name;
3864 
3865 	methods = srv->init_addr_methods;
3866 	if (!methods) {
3867 		/* otherwise default to "last,libc" */
3868 		srv_append_initaddr(&methods, SRV_IADDR_LAST);
3869 		srv_append_initaddr(&methods, SRV_IADDR_LIBC);
3870 		if (srv->resolvers_id) {
3871 			/* dns resolution is configured, add "none" to not fail on startup */
3872 			srv_append_initaddr(&methods, SRV_IADDR_NONE);
3873 		}
3874 	}
3875 
3876 	/* "-dr" : always append "none" so that server addresses resolution
3877 	 * failures are silently ignored, this is convenient to validate some
3878 	 * configs out of their environment.
3879 	 */
3880 	if (global.tune.options & GTUNE_RESOLVE_DONTFAIL)
3881 		srv_append_initaddr(&methods, SRV_IADDR_NONE);
3882 
3883 	while (methods) {
3884 		err_code = 0;
3885 		switch (srv_get_next_initaddr(&methods)) {
3886 		case SRV_IADDR_LAST:
3887 			if (!srv->lastaddr)
3888 				continue;
3889 			if (srv_apply_lastaddr(srv, &err_code) == 0)
3890 				goto out;
3891 			return_code |= err_code;
3892 			break;
3893 
3894 		case SRV_IADDR_LIBC:
3895 			if (!srv->hostname)
3896 				continue;
3897 			if (srv_set_addr_via_libc(srv, &err_code) == 0)
3898 				goto out;
3899 			return_code |= err_code;
3900 			break;
3901 
3902 		case SRV_IADDR_NONE:
3903 			srv_set_admin_flag(srv, SRV_ADMF_RMAINT, NULL);
3904 			if (return_code) {
3905 				ha_warning("parsing [%s:%d] : 'server %s' : could not resolve address '%s', disabling server.\n",
3906 					   srv->conf.file, srv->conf.line, srv->id, name);
3907 			}
3908 			return return_code;
3909 
3910 		case SRV_IADDR_IP:
3911 			ipcpy(&srv->init_addr, &srv->addr);
3912 			if (return_code) {
3913 				ha_warning("parsing [%s:%d] : 'server %s' : could not resolve address '%s', falling back to configured address.\n",
3914 					   srv->conf.file, srv->conf.line, srv->id, name);
3915 			}
3916 			goto out;
3917 
3918 		default: /* unhandled method */
3919 			break;
3920 		}
3921 	}
3922 
3923 	if (!return_code) {
3924 		ha_alert("parsing [%s:%d] : 'server %s' : no method found to resolve address '%s'\n",
3925 		      srv->conf.file, srv->conf.line, srv->id, name);
3926 	}
3927 	else {
3928 		ha_alert("parsing [%s:%d] : 'server %s' : could not resolve address '%s'.\n",
3929 		      srv->conf.file, srv->conf.line, srv->id, name);
3930 	}
3931 
3932 	return_code |= ERR_ALERT | ERR_FATAL;
3933 	return return_code;
3934 out:
3935 	srv_set_dyncookie(srv);
3936 	srv_set_addr_desc(srv, 1);
3937 	return return_code;
3938 }
3939 
3940 /*
3941  * This function parses all backends and all servers within each backend
3942  * and performs servers' addr resolution based on information provided by:
3943  *   - configuration file
3944  *   - server-state file (states provided by an 'old' haproxy process)
3945  *
3946  * Returns 0 if no error, otherwise, a combination of ERR_ flags.
3947  */
srv_init_addr(void)3948 int srv_init_addr(void)
3949 {
3950 	struct proxy *curproxy;
3951 	int return_code = 0;
3952 
3953 	curproxy = proxies_list;
3954 	while (curproxy) {
3955 		struct server *srv;
3956 
3957 		/* servers are in backend only */
3958 		if (!(curproxy->cap & PR_CAP_BE) || curproxy->disabled)
3959 			goto srv_init_addr_next;
3960 
3961 		for (srv = curproxy->srv; srv; srv = srv->next)
3962 			if (srv->hostname || srv->srvrq)
3963 				return_code |= srv_iterate_initaddr(srv);
3964 
3965  srv_init_addr_next:
3966 		curproxy = curproxy->next;
3967 	}
3968 
3969 	return return_code;
3970 }
3971 
3972 /*
3973  * Must be called with the server lock held.
3974  */
srv_update_fqdn(struct server * server,const char * fqdn,const char * updater,int resolv_locked)3975 const char *srv_update_fqdn(struct server *server, const char *fqdn, const char *updater, int resolv_locked)
3976 {
3977 
3978 	struct buffer *msg;
3979 
3980 	msg = get_trash_chunk();
3981 	chunk_reset(msg);
3982 
3983 	if (server->hostname && strcmp(fqdn, server->hostname) == 0) {
3984 		chunk_appendf(msg, "no need to change the FDQN");
3985 		goto out;
3986 	}
3987 
3988 	if (strlen(fqdn) > DNS_MAX_NAME_SIZE || invalid_domainchar(fqdn)) {
3989 		chunk_appendf(msg, "invalid fqdn '%s'", fqdn);
3990 		goto out;
3991 	}
3992 
3993 	chunk_appendf(msg, "%s/%s changed its FQDN from %s to %s",
3994 	              server->proxy->id, server->id, server->hostname, fqdn);
3995 
3996 	if (srv_set_fqdn(server, fqdn, resolv_locked) < 0) {
3997 		chunk_reset(msg);
3998 		chunk_appendf(msg, "could not update %s/%s FQDN",
3999 		              server->proxy->id, server->id);
4000 		goto out;
4001 	}
4002 
4003 	/* Flag as FQDN set from stats socket. */
4004 	server->next_admin |= SRV_ADMF_HMAINT;
4005 
4006  out:
4007 	if (updater)
4008 		chunk_appendf(msg, " by '%s'", updater);
4009 	chunk_appendf(msg, "\n");
4010 
4011 	return msg->area;
4012 }
4013 
4014 
4015 /* Expects to find a backend and a server in <arg> under the form <backend>/<server>,
4016  * and returns the pointer to the server. Otherwise, display adequate error messages
4017  * on the CLI, sets the CLI's state to CLI_ST_PRINT and returns NULL. This is only
4018  * used for CLI commands requiring a server name.
4019  * Important: the <arg> is modified to remove the '/'.
4020  */
cli_find_server(struct appctx * appctx,char * arg)4021 struct server *cli_find_server(struct appctx *appctx, char *arg)
4022 {
4023 	struct proxy *px;
4024 	struct server *sv;
4025 	char *line;
4026 
4027 	/* split "backend/server" and make <line> point to server */
4028 	for (line = arg; *line; line++)
4029 		if (*line == '/') {
4030 			*line++ = '\0';
4031 			break;
4032 		}
4033 
4034 	if (!*line || !*arg) {
4035 		cli_err(appctx, "Require 'backend/server'.\n");
4036 		return NULL;
4037 	}
4038 
4039 	if (!get_backend_server(arg, line, &px, &sv)) {
4040 		cli_err(appctx, px ? "No such server.\n" : "No such backend.\n");
4041 		return NULL;
4042 	}
4043 
4044 	if (px->disabled) {
4045 		cli_err(appctx, "Proxy is disabled.\n");
4046 		return NULL;
4047 	}
4048 
4049 	return sv;
4050 }
4051 
4052 
4053 /* grabs the server lock */
cli_parse_set_server(char ** args,char * payload,struct appctx * appctx,void * private)4054 static int cli_parse_set_server(char **args, char *payload, struct appctx *appctx, void *private)
4055 {
4056 	struct server *sv;
4057 	const char *warning;
4058 
4059 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4060 		return 1;
4061 
4062 	sv = cli_find_server(appctx, args[2]);
4063 	if (!sv)
4064 		return 1;
4065 
4066 	if (strcmp(args[3], "weight") == 0) {
4067 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4068 		warning = server_parse_weight_change_request(sv, args[4]);
4069 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4070 		if (warning)
4071 			cli_err(appctx, warning);
4072 	}
4073 	else if (strcmp(args[3], "state") == 0) {
4074 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4075 		if (strcmp(args[4], "ready") == 0)
4076 			srv_adm_set_ready(sv);
4077 		else if (strcmp(args[4], "drain") == 0)
4078 			srv_adm_set_drain(sv);
4079 		else if (strcmp(args[4], "maint") == 0)
4080 			srv_adm_set_maint(sv);
4081 		else
4082 			cli_err(appctx, "'set server <srv> state' expects 'ready', 'drain' and 'maint'.\n");
4083 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4084 	}
4085 	else if (strcmp(args[3], "health") == 0) {
4086 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4087 		if (sv->track)
4088 			cli_err(appctx, "cannot change health on a tracking server.\n");
4089 		else if (strcmp(args[4], "up") == 0) {
4090 			sv->check.health = sv->check.rise + sv->check.fall - 1;
4091 			srv_set_running(sv, "changed from CLI", NULL);
4092 		}
4093 		else if (strcmp(args[4], "stopping") == 0) {
4094 			sv->check.health = sv->check.rise + sv->check.fall - 1;
4095 			srv_set_stopping(sv, "changed from CLI", NULL);
4096 		}
4097 		else if (strcmp(args[4], "down") == 0) {
4098 			sv->check.health = 0;
4099 			srv_set_stopped(sv, "changed from CLI", NULL);
4100 		}
4101 		else
4102 			cli_err(appctx, "'set server <srv> health' expects 'up', 'stopping', or 'down'.\n");
4103 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4104 	}
4105 	else if (strcmp(args[3], "agent") == 0) {
4106 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4107 		if (!(sv->agent.state & CHK_ST_ENABLED))
4108 			cli_err(appctx, "agent checks are not enabled on this server.\n");
4109 		else if (strcmp(args[4], "up") == 0) {
4110 			sv->agent.health = sv->agent.rise + sv->agent.fall - 1;
4111 			srv_set_running(sv, "changed from CLI", NULL);
4112 		}
4113 		else if (strcmp(args[4], "down") == 0) {
4114 			sv->agent.health = 0;
4115 			srv_set_stopped(sv, "changed from CLI", NULL);
4116 		}
4117 		else
4118 			cli_err(appctx, "'set server <srv> agent' expects 'up' or 'down'.\n");
4119 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4120 	}
4121 	else if (strcmp(args[3], "agent-addr") == 0) {
4122 		char *addr = NULL;
4123 		char *port = NULL;
4124 		if (strlen(args[4]) == 0) {
4125 			cli_err(appctx, "set server <b>/<s> agent-addr requires"
4126 					" an address and optionally a port.\n");
4127 			goto out;
4128 		}
4129 		addr = args[4];
4130 		if (strcmp(args[5], "port") == 0)
4131 			port = args[6];
4132 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4133 		warning = srv_update_agent_addr_port(sv, addr, port);
4134 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4135 		if (warning)
4136 			cli_msg(appctx, LOG_WARNING, warning);
4137 	}
4138 	else if (strcmp(args[3], "agent-port") == 0) {
4139 		char *port = NULL;
4140 		if (strlen(args[4]) == 0) {
4141 			cli_err(appctx, "set server <b>/<s> agent-port requires"
4142 					" a port.\n");
4143 			goto out;
4144 		}
4145 		port = args[4];
4146 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4147 		warning = srv_update_agent_addr_port(sv, NULL, port);
4148 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4149 		if (warning)
4150 			cli_msg(appctx, LOG_WARNING, warning);
4151 	}
4152 	else if (strcmp(args[3], "agent-send") == 0) {
4153 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4154 		if (!(sv->agent.state & CHK_ST_ENABLED))
4155 			cli_err(appctx, "agent checks are not enabled on this server.\n");
4156 		else {
4157 			if (!set_srv_agent_send(sv, args[4]))
4158 				cli_err(appctx, "cannot allocate memory for new string.\n");
4159 		}
4160 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4161 	}
4162 	else if (strcmp(args[3], "check-addr") == 0) {
4163 		char *addr = NULL;
4164 		char *port = NULL;
4165 		if (strlen(args[4]) == 0) {
4166 			cli_err(appctx, "set server <b>/<s> check-addr requires"
4167 					" an address and optionally a port.\n");
4168 			goto out;
4169 		}
4170 		addr = args[4];
4171 		if (strcmp(args[5], "port") == 0)
4172 			port = args[6];
4173 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4174 		warning = srv_update_check_addr_port(sv, addr, port);
4175 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4176 		if (warning)
4177 			cli_msg(appctx, LOG_WARNING, warning);
4178 	}
4179 	else if (strcmp(args[3], "check-port") == 0) {
4180 		char *port = NULL;
4181 		if (strlen(args[4]) == 0) {
4182 			cli_err(appctx, "set server <b>/<s> check-port requires"
4183 					" a port.\n");
4184 			goto out;
4185 		}
4186 		port = args[4];
4187 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4188 		warning = srv_update_check_addr_port(sv, NULL, port);
4189 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4190 		if (warning)
4191 			cli_msg(appctx, LOG_WARNING, warning);
4192 	}
4193 	else if (strcmp(args[3], "addr") == 0) {
4194 		char *addr = NULL;
4195 		char *port = NULL;
4196 		if (strlen(args[4]) == 0) {
4197 			cli_err(appctx, "set server <b>/<s> addr requires an address and optionally a port.\n");
4198 			goto out;
4199 		}
4200 		else {
4201 			addr = args[4];
4202 		}
4203 		if (strcmp(args[5], "port") == 0) {
4204 			port = args[6];
4205 		}
4206 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4207 		warning = srv_update_addr_port(sv, addr, port, "stats socket command");
4208 		if (warning)
4209 			cli_msg(appctx, LOG_WARNING, warning);
4210 		srv_clr_admin_flag(sv, SRV_ADMF_RMAINT);
4211 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4212 	}
4213 	else if (strcmp(args[3], "fqdn") == 0) {
4214 		if (!*args[4]) {
4215 			cli_err(appctx, "set server <b>/<s> fqdn requires a FQDN.\n");
4216 			goto out;
4217 		}
4218 		if (!sv->resolvers) {
4219 			cli_err(appctx, "set server <b>/<s> fqdn failed because no resolution is configured.\n");
4220 			goto out;
4221 		}
4222 		if (sv->srvrq) {
4223 			cli_err(appctx, "set server <b>/<s> fqdn failed because SRV resolution is configured.\n");
4224 			goto out;
4225 		}
4226 		HA_SPIN_LOCK(DNS_LOCK, &sv->resolvers->lock);
4227 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4228 		/* ensure runtime resolver will process this new fqdn */
4229 		if (sv->flags & SRV_F_NO_RESOLUTION) {
4230 			sv->flags &= ~SRV_F_NO_RESOLUTION;
4231 		}
4232 		warning = srv_update_fqdn(sv, args[4], "stats socket command", 1);
4233 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4234 		HA_SPIN_UNLOCK(DNS_LOCK, &sv->resolvers->lock);
4235 		if (warning)
4236 			cli_msg(appctx, LOG_WARNING, warning);
4237 	}
4238 	else if (strcmp(args[3], "ssl") == 0) {
4239 #ifdef USE_OPENSSL
4240 		if (sv->ssl_ctx.ctx == NULL) {
4241 			cli_err(appctx, "'set server <srv> ssl' cannot be set. "
4242 					" default-server should define ssl settings\n");
4243 			goto out;
4244 		}
4245 
4246 		HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4247 		if (strcmp(args[4], "on") == 0) {
4248 			ssl_sock_set_srv(sv, 1);
4249 		} else if (strcmp(args[4], "off") == 0) {
4250 			ssl_sock_set_srv(sv, 0);
4251 		} else {
4252 			HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4253 			cli_err(appctx, "'set server <srv> ssl' expects 'on' or 'off'.\n");
4254 			goto out;
4255 		}
4256 		srv_cleanup_connections(sv);
4257 		HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4258 		cli_msg(appctx, LOG_NOTICE, "server ssl setting updated.\n");
4259 #else
4260 		cli_msg(appctx, LOG_NOTICE, "server ssl setting not supported.\n");
4261 #endif
4262 	} else {
4263 		cli_err(appctx,
4264 			"usage: set server <backend>/<server> "
4265 			"addr | agent | agent-addr | agent-port | agent-send | "
4266 			"check-addr | check-port | fqdn | health | ssl | "
4267 			"state | weight\n");
4268 	}
4269  out:
4270 	return 1;
4271 }
4272 
cli_parse_get_weight(char ** args,char * payload,struct appctx * appctx,void * private)4273 static int cli_parse_get_weight(char **args, char *payload, struct appctx *appctx, void *private)
4274 {
4275 	struct stream_interface *si = appctx->owner;
4276 	struct proxy *px;
4277 	struct server *sv;
4278 	char *line;
4279 
4280 
4281 	/* split "backend/server" and make <line> point to server */
4282 	for (line = args[2]; *line; line++)
4283 		if (*line == '/') {
4284 			*line++ = '\0';
4285 			break;
4286 		}
4287 
4288 	if (!*line)
4289 		return cli_err(appctx, "Require 'backend/server'.\n");
4290 
4291 	if (!get_backend_server(args[2], line, &px, &sv))
4292 		return cli_err(appctx, px ? "No such server.\n" : "No such backend.\n");
4293 
4294 	/* return server's effective weight at the moment */
4295 	snprintf(trash.area, trash.size, "%d (initial %d)\n", sv->uweight,
4296 		 sv->iweight);
4297 	if (ci_putstr(si_ic(si), trash.area) == -1) {
4298 		si_rx_room_blk(si);
4299 		return 0;
4300 	}
4301 	return 1;
4302 }
4303 
4304 /* Parse a "set weight" command.
4305  *
4306  * Grabs the server lock.
4307  */
cli_parse_set_weight(char ** args,char * payload,struct appctx * appctx,void * private)4308 static int cli_parse_set_weight(char **args, char *payload, struct appctx *appctx, void *private)
4309 {
4310 	struct server *sv;
4311 	const char *warning;
4312 
4313 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4314 		return 1;
4315 
4316 	sv = cli_find_server(appctx, args[2]);
4317 	if (!sv)
4318 		return 1;
4319 
4320 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4321 
4322 	warning = server_parse_weight_change_request(sv, args[3]);
4323 	if (warning)
4324 		cli_err(appctx, warning);
4325 
4326 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4327 
4328 	return 1;
4329 }
4330 
4331 /* parse a "set maxconn server" command. It always returns 1.
4332  *
4333  * Grabs the server lock.
4334  */
cli_parse_set_maxconn_server(char ** args,char * payload,struct appctx * appctx,void * private)4335 static int cli_parse_set_maxconn_server(char **args, char *payload, struct appctx *appctx, void *private)
4336 {
4337 	struct server *sv;
4338 	const char *warning;
4339 
4340 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4341 		return 1;
4342 
4343 	sv = cli_find_server(appctx, args[3]);
4344 	if (!sv)
4345 		return 1;
4346 
4347 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4348 
4349 	warning = server_parse_maxconn_change_request(sv, args[4]);
4350 	if (warning)
4351 		cli_err(appctx, warning);
4352 
4353 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4354 
4355 	return 1;
4356 }
4357 
4358 /* parse a "disable agent" command. It always returns 1.
4359  *
4360  * Grabs the server lock.
4361  */
cli_parse_disable_agent(char ** args,char * payload,struct appctx * appctx,void * private)4362 static int cli_parse_disable_agent(char **args, char *payload, struct appctx *appctx, void *private)
4363 {
4364 	struct server *sv;
4365 
4366 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4367 		return 1;
4368 
4369 	sv = cli_find_server(appctx, args[2]);
4370 	if (!sv)
4371 		return 1;
4372 
4373 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4374 	sv->agent.state &= ~CHK_ST_ENABLED;
4375 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4376 	return 1;
4377 }
4378 
4379 /* parse a "disable health" command. It always returns 1.
4380  *
4381  * Grabs the server lock.
4382  */
cli_parse_disable_health(char ** args,char * payload,struct appctx * appctx,void * private)4383 static int cli_parse_disable_health(char **args, char *payload, struct appctx *appctx, void *private)
4384 {
4385 	struct server *sv;
4386 
4387 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4388 		return 1;
4389 
4390 	sv = cli_find_server(appctx, args[2]);
4391 	if (!sv)
4392 		return 1;
4393 
4394 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4395 	sv->check.state &= ~CHK_ST_ENABLED;
4396 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4397 	return 1;
4398 }
4399 
4400 /* parse a "disable server" command. It always returns 1.
4401  *
4402  * Grabs the server lock.
4403  */
cli_parse_disable_server(char ** args,char * payload,struct appctx * appctx,void * private)4404 static int cli_parse_disable_server(char **args, char *payload, struct appctx *appctx, void *private)
4405 {
4406 	struct server *sv;
4407 
4408 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4409 		return 1;
4410 
4411 	sv = cli_find_server(appctx, args[2]);
4412 	if (!sv)
4413 		return 1;
4414 
4415 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4416 	srv_adm_set_maint(sv);
4417 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4418 	return 1;
4419 }
4420 
4421 /* parse a "enable agent" command. It always returns 1.
4422  *
4423  * Grabs the server lock.
4424  */
cli_parse_enable_agent(char ** args,char * payload,struct appctx * appctx,void * private)4425 static int cli_parse_enable_agent(char **args, char *payload, struct appctx *appctx, void *private)
4426 {
4427 	struct server *sv;
4428 
4429 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4430 		return 1;
4431 
4432 	sv = cli_find_server(appctx, args[2]);
4433 	if (!sv)
4434 		return 1;
4435 
4436 	if (!(sv->agent.state & CHK_ST_CONFIGURED))
4437 		return cli_err(appctx, "Agent was not configured on this server, cannot enable.\n");
4438 
4439 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4440 	sv->agent.state |= CHK_ST_ENABLED;
4441 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4442 	return 1;
4443 }
4444 
4445 /* parse a "enable health" command. It always returns 1.
4446  *
4447  * Grabs the server lock.
4448  */
cli_parse_enable_health(char ** args,char * payload,struct appctx * appctx,void * private)4449 static int cli_parse_enable_health(char **args, char *payload, struct appctx *appctx, void *private)
4450 {
4451 	struct server *sv;
4452 
4453 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4454 		return 1;
4455 
4456 	sv = cli_find_server(appctx, args[2]);
4457 	if (!sv)
4458 		return 1;
4459 
4460 	if (!(sv->check.state & CHK_ST_CONFIGURED))
4461 		return cli_err(appctx, "Health check was not configured on this server, cannot enable.\n");
4462 
4463 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4464 	sv->check.state |= CHK_ST_ENABLED;
4465 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4466 	return 1;
4467 }
4468 
4469 /* parse a "enable server" command. It always returns 1.
4470  *
4471  * Grabs the server lock.
4472  */
cli_parse_enable_server(char ** args,char * payload,struct appctx * appctx,void * private)4473 static int cli_parse_enable_server(char **args, char *payload, struct appctx *appctx, void *private)
4474 {
4475 	struct server *sv;
4476 
4477 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4478 		return 1;
4479 
4480 	sv = cli_find_server(appctx, args[2]);
4481 	if (!sv)
4482 		return 1;
4483 
4484 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
4485 	srv_adm_set_ready(sv);
4486 	if (!(sv->flags & SRV_F_COOKIESET)
4487 	    && (sv->proxy->ck_opts & PR_CK_DYNAMIC) &&
4488 	    sv->cookie)
4489 		srv_check_for_dup_dyncookie(sv);
4490 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
4491 	return 1;
4492 }
4493 
4494 /* Allocates data structure related to load balancing for the server <sv>. It
4495  * is only required for dynamic servers.
4496  *
4497  * At the moment, the server lock is not used as this function is only called
4498  * for a dynamic server not yet registered.
4499  *
4500  * Returns 1 on success, 0 on allocation failure.
4501  */
srv_alloc_lb(struct server * sv,struct proxy * be)4502 static int srv_alloc_lb(struct server *sv, struct proxy *be)
4503 {
4504 	int node;
4505 
4506 	sv->lb_tree = (sv->flags & SRV_F_BACKUP) ?
4507 	              &be->lbprm.chash.bck : &be->lbprm.chash.act;
4508 	sv->lb_nodes_tot = sv->uweight * BE_WEIGHT_SCALE;
4509 	sv->lb_nodes_now = 0;
4510 
4511 	if (((be->lbprm.algo & (BE_LB_KIND | BE_LB_PARM)) == (BE_LB_KIND_RR | BE_LB_RR_RANDOM)) ||
4512 	    ((be->lbprm.algo & (BE_LB_KIND | BE_LB_HASH_TYPE)) == (BE_LB_KIND_HI | BE_LB_HASH_CONS))) {
4513 		sv->lb_nodes = calloc(sv->lb_nodes_tot, sizeof(*sv->lb_nodes));
4514 
4515 		if (!sv->lb_nodes)
4516 			return 0;
4517 
4518 		for (node = 0; node < sv->lb_nodes_tot; node++) {
4519 			sv->lb_nodes[node].server = sv;
4520 			sv->lb_nodes[node].node.key = full_hash(sv->puid * SRV_EWGHT_RANGE + node);
4521 		}
4522 	}
4523 
4524 	return 1;
4525 }
4526 
4527 /* Parse a "add server" command
4528  * Returns 0 if the server has been successfully initialized, 1 on failure.
4529  */
cli_parse_add_server(char ** args,char * payload,struct appctx * appctx,void * private)4530 static int cli_parse_add_server(char **args, char *payload, struct appctx *appctx, void *private)
4531 {
4532 	struct proxy *be;
4533 	struct server *srv;
4534 	char *be_name, *sv_name;
4535 	char *errmsg = NULL;
4536 	int errcode, argc;
4537 	int next_id, i;
4538 	const int parse_flags = SRV_PARSE_DYNAMIC|SRV_PARSE_PARSE_ADDR;
4539 
4540 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4541 		return 1;
4542 
4543 	++args;
4544 
4545 	sv_name = be_name = args[1];
4546 	/* split backend/server arg */
4547 	while (*sv_name && *(++sv_name)) {
4548 		if (*sv_name == '/') {
4549 			*sv_name = '\0';
4550 			++sv_name;
4551 			break;
4552 		}
4553 	}
4554 
4555 	if (!*sv_name)
4556 		return cli_err(appctx, "Require 'backend/server'.");
4557 
4558 	be = proxy_be_by_name(be_name);
4559 	if (!be)
4560 		return cli_err(appctx, "No such backend.");
4561 
4562 	if (!(be->lbprm.algo & BE_LB_PROP_DYN)) {
4563 		cli_err(appctx, "Backend must use a dynamic load balancing to support dynamic servers.");
4564 		return 1;
4565 	}
4566 
4567 	/* At this point, some operations might not be thread-safe anymore. This
4568 	 * might be the case for parsing handlers which were designed to run
4569 	 * only at the starting stage on single-thread mode.
4570 	 *
4571 	 * Activate thread isolation to ensure thread-safety.
4572 	 */
4573 	thread_isolate();
4574 
4575 	args[1] = sv_name;
4576 	errcode = _srv_parse_init(&srv, args, &argc, be, parse_flags, &errmsg);
4577 	if (srv)
4578 		srv_use_dynsrv(srv);
4579 
4580 	if (errcode) {
4581 		if (errmsg)
4582 			cli_dynerr(appctx, errmsg);
4583 		goto out;
4584 	}
4585 
4586 	while (*args[argc]) {
4587 		errcode = _srv_parse_kw(srv, args, &argc, be, parse_flags, &errmsg);
4588 
4589 		if (errcode) {
4590 			if (errmsg)
4591 				cli_dynerr(appctx, errmsg);
4592 			goto out;
4593 		}
4594 	}
4595 
4596 	_srv_parse_finalize(args, argc, srv, be, parse_flags, &errmsg);
4597 	if (errmsg) {
4598 		cli_dynerr(appctx, errmsg);
4599 		goto out;
4600 	}
4601 
4602 	/* A dynamic server does not currently support resolution.
4603 	 *
4604 	 * Initialize it explicitly to the "none" method to ensure no
4605 	 * resolution will ever be executed.
4606 	 */
4607 	srv->init_addr_methods = SRV_IADDR_NONE;
4608 
4609 	if (srv->mux_proto) {
4610 		if (!conn_get_best_mux_entry(srv->mux_proto->token, PROTO_SIDE_BE, be->mode)) {
4611 			cli_err(appctx, "MUX protocol is not usable for server.");
4612 			goto out;
4613 		}
4614 	}
4615 
4616 	srv->per_thr = calloc(global.nbthread, sizeof(*srv->per_thr));
4617 	if (!srv->per_thr) {
4618 		cli_err(appctx, "failed to allocate per-thread lists for server.");
4619 		goto out;
4620 	}
4621 
4622 	for (i = 0; i < global.nbthread; i++) {
4623 		srv->per_thr[i].idle_conns = EB_ROOT;
4624 		srv->per_thr[i].safe_conns = EB_ROOT;
4625 		srv->per_thr[i].avail_conns = EB_ROOT;
4626 		MT_LIST_INIT(&srv->per_thr[i].streams);
4627 	}
4628 
4629 	if (srv->max_idle_conns != 0) {
4630 		srv->curr_idle_thr = calloc(global.nbthread, sizeof(*srv->curr_idle_thr));
4631 		if (!srv->curr_idle_thr) {
4632 			cli_err(appctx, "failed to allocate counters for server.");
4633 			goto out;
4634 		}
4635 	}
4636 
4637 	if (!srv_alloc_lb(srv, be)) {
4638 		cli_err(appctx, "Failed to initialize load-balancing data.");
4639 		goto out;
4640 	}
4641 
4642 	if (!stats_allocate_proxy_counters_internal(&srv->extra_counters,
4643 	                                            COUNTERS_SV,
4644 	                                            STATS_PX_CAP_SRV)) {
4645 		cli_err(appctx, "failed to allocate extra counters for server.");
4646 		goto out;
4647 	}
4648 
4649 	/* Attach the server to the end of the proxy linked list. Note that this
4650 	 * operation is not thread-safe so this is executed under thread
4651 	 * isolation.
4652 	 *
4653 	 * If a server with the same name is found, reject the new one.
4654 	 */
4655 
4656 	/* TODO use a double-linked list for px->srv */
4657 	if (be->srv) {
4658 		struct server *next = be->srv;
4659 
4660 		while (1) {
4661 			/* check for duplicate server */
4662 			if (!strcmp(srv->id, next->id)) {
4663 				cli_err(appctx, "Already exists a server with the same name in backend.");
4664 				goto out;
4665 			}
4666 
4667 			if (!next->next)
4668 				break;
4669 
4670 			next = next->next;
4671 		}
4672 
4673 		next->next = srv;
4674 	}
4675 	else {
4676 		srv->next = be->srv;
4677 		be->srv = srv;
4678 	}
4679 
4680 	/* generate the server id if not manually specified */
4681 	if (!srv->puid) {
4682 		next_id = get_next_id(&be->conf.used_server_id, 1);
4683 		if (!next_id) {
4684 			ha_alert("Cannot attach server : no id left in proxy\n");
4685 			goto out;
4686 		}
4687 
4688 		srv->conf.id.key = srv->puid = next_id;
4689 	}
4690 	srv->conf.name.key = srv->id;
4691 
4692 	/* insert the server in the backend trees */
4693 	eb32_insert(&be->conf.used_server_id, &srv->conf.id);
4694 	ebis_insert(&be->conf.used_server_name, &srv->conf.name);
4695 	ebis_insert(&be->used_server_addr, &srv->addr_node);
4696 
4697 	thread_release();
4698 
4699 	ha_notice("New server %s/%s registered.\n", be->id, srv->id);
4700 	cli_msg(appctx, LOG_INFO, "New server registered.");
4701 
4702 	return 0;
4703 
4704 out:
4705 	if (srv) {
4706 		/* remove the server from the proxy linked list */
4707 		if (be->srv == srv) {
4708 			be->srv = srv->next;
4709 		}
4710 		else {
4711 			struct server *prev;
4712 			for (prev = be->srv; prev && prev->next != srv; prev = prev->next)
4713 				;
4714 			if (prev)
4715 				prev->next = srv->next;
4716 		}
4717 
4718 	}
4719 
4720 	thread_release();
4721 	if (srv)
4722 		free_server(srv);
4723 	return 1;
4724 }
4725 
4726 /* Parse a "del server" command
4727  * Returns 0 if the server has been successfully initialized, 1 on failure.
4728  */
cli_parse_delete_server(char ** args,char * payload,struct appctx * appctx,void * private)4729 static int cli_parse_delete_server(char **args, char *payload, struct appctx *appctx, void *private)
4730 {
4731 	struct proxy *be;
4732 	struct server *srv;
4733 	char *be_name, *sv_name;
4734 
4735 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
4736 		return 1;
4737 
4738 	++args;
4739 
4740 	sv_name = be_name = args[1];
4741 	/* split backend/server arg */
4742 	while (*sv_name && *(++sv_name)) {
4743 		if (*sv_name == '/') {
4744 			*sv_name = '\0';
4745 			++sv_name;
4746 			break;
4747 		}
4748 	}
4749 
4750 	if (!*sv_name)
4751 		return cli_err(appctx, "Require 'backend/server'.");
4752 
4753 	/* The proxy servers list is currently not protected by a lock so this
4754 	 * requires thread isolation.
4755 	 */
4756 
4757 	/* WARNING there is maybe a potential violation of the thread isolation
4758 	 * mechanism by the pool allocator. The allocator marks the thread as
4759 	 * harmless before the allocation, but a processing outside of it could
4760 	 * relies on a particular server triggered at the same time by a
4761 	 * 'delete server'. Currently, it is unknown if such case is present in
4762 	 * the current code. If it happens to be, the thread isolation
4763 	 * mechanism should be improved, maybe with a differentiation between
4764 	 * read and read+write safe sections.
4765 	 */
4766 	thread_isolate();
4767 
4768 	get_backend_server(be_name, sv_name, &be, &srv);
4769 	if (!be) {
4770 		cli_err(appctx, "No such backend.");
4771 		goto out;
4772 	}
4773 
4774 	if (!srv) {
4775 		cli_err(appctx, "No such server.");
4776 		goto out;
4777 	}
4778 
4779 	if (!(srv->flags & SRV_F_DYNAMIC)) {
4780 		cli_err(appctx, "Only servers added at runtime via <add server> CLI cmd can be deleted.");
4781 		goto out;
4782 	}
4783 
4784 	/* Only servers in maintenance can be deleted. This ensures that the
4785 	 * server is not present anymore in the lb structures (through
4786 	 * lbprm.set_server_status_down).
4787 	 */
4788 	if (!(srv->cur_admin & SRV_ADMF_MAINT)) {
4789 		cli_err(appctx, "Only servers in maintenance mode can be deleted.");
4790 		goto out;
4791 	}
4792 
4793 	/* Ensure that there is no active/idle/pending connection on the server.
4794 	 *
4795 	 * TODO idle connections should not prevent server deletion. A proper
4796 	 * cleanup function should be implemented to be used here.
4797 	 */
4798 	if (srv->cur_sess || srv->curr_idle_conns ||
4799 	    !eb_is_empty(&srv->pendconns)) {
4800 		cli_err(appctx, "Server still has connections attached to it, cannot remove it.");
4801 		goto out;
4802 	}
4803 
4804 	/* TODO remove server for check list once 'check' will be implemented for
4805 	 * dynamic servers
4806 	 */
4807 
4808 	/* detach the server from the proxy linked list
4809 	 * The proxy servers list is currently not protected by a lock, so this
4810 	 * requires thread_isolate/release.
4811 	 */
4812 
4813 	/* be->srv cannot be empty since we have already found the server with
4814 	 * get_backend_server */
4815 	BUG_ON(!be->srv);
4816 	if (be->srv == srv) {
4817 		be->srv = srv->next;
4818 	}
4819 	else {
4820 		struct server *next;
4821 		for (next = be->srv; srv != next->next; next = next->next) {
4822 			/* srv cannot be not found since we have already found
4823 			 * it with get_backend_server */
4824 			BUG_ON(!next);
4825 		}
4826 
4827 		next->next = srv->next;
4828 	}
4829 
4830 	/* remove srv from addr_node tree */
4831 	eb32_delete(&srv->conf.id);
4832 	ebpt_delete(&srv->conf.name);
4833 	ebpt_delete(&srv->addr_node);
4834 
4835 	/* remove srv from idle_node tree for idle conn cleanup */
4836 	eb32_delete(&srv->idle_node);
4837 
4838 	thread_release();
4839 
4840 	ha_notice("Server %s/%s deleted.\n", be->id, srv->id);
4841 	free_server(srv);
4842 
4843 	cli_msg(appctx, LOG_INFO, "Server deleted.");
4844 
4845 	return 0;
4846 
4847 out:
4848 	thread_release();
4849 
4850 	return 1;
4851 }
4852 
4853 /* register cli keywords */
4854 static struct cli_kw_list cli_kws = {{ },{
4855 	{ { "disable", "agent",  NULL },         "disable agent                           : disable agent checks",                                        cli_parse_disable_agent, NULL },
4856 	{ { "disable", "health",  NULL },        "disable health                          : disable health checks",                                       cli_parse_disable_health, NULL },
4857 	{ { "disable", "server",  NULL },        "disable server (DEPRECATED)             : disable a server for maintenance (use 'set server' instead)", cli_parse_disable_server, NULL },
4858 	{ { "enable", "agent",  NULL },          "enable agent                            : enable agent checks",                                         cli_parse_enable_agent, NULL },
4859 	{ { "enable", "health",  NULL },         "enable health                           : enable health checks",                                        cli_parse_enable_health, NULL },
4860 	{ { "enable", "server",  NULL },         "enable server  (DEPRECATED)             : enable a disabled server (use 'set server' instead)",         cli_parse_enable_server, NULL },
4861 	{ { "set", "maxconn", "server",  NULL }, "set maxconn server <bk>/<srv>           : change a server's maxconn setting",                           cli_parse_set_maxconn_server, NULL },
4862 	{ { "set", "server", NULL },             "set server <bk>/<srv> [opts]            : change a server's state, weight, address or ssl",             cli_parse_set_server },
4863 	{ { "get", "weight", NULL },             "get weight <bk>/<srv>                   : report a server's current weight",                            cli_parse_get_weight },
4864 	{ { "set", "weight", NULL },             "set weight <bk>/<srv>  (DEPRECATED)     : change a server's weight (use 'set server' instead)",         cli_parse_set_weight },
4865 	{ { "add", "server", NULL },             "add server <bk>/<srv>                   : create a new server (EXPERIMENTAL)",                          cli_parse_add_server, NULL, NULL, NULL, ACCESS_EXPERIMENTAL },
4866 	{ { "del", "server", NULL },             "del server <bk>/<srv>                   : remove a dynamically added server (EXPERIMENTAL)",            cli_parse_delete_server, NULL, NULL, NULL, ACCESS_EXPERIMENTAL },
4867 	{{},}
4868 }};
4869 
4870 INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
4871 
4872 /*
4873  * This function applies server's status changes, it is
4874  * is designed to be called asynchronously.
4875  *
4876  * Must be called with the server lock held. This may also be called at init
4877  * time as the result of parsing the state file, in which case no lock will be
4878  * held, and the server's warmup task can be null.
4879  */
srv_update_status(struct server * s)4880 static void srv_update_status(struct server *s)
4881 {
4882 	struct check *check = &s->check;
4883 	int xferred;
4884 	struct proxy *px = s->proxy;
4885 	int prev_srv_count = s->proxy->srv_bck + s->proxy->srv_act;
4886 	int srv_was_stopping = (s->cur_state == SRV_ST_STOPPING) || (s->cur_admin & SRV_ADMF_DRAIN);
4887 	int log_level;
4888 	struct buffer *tmptrash = NULL;
4889 
4890 	/* If currently main is not set we try to apply pending state changes */
4891 	if (!(s->cur_admin & SRV_ADMF_MAINT)) {
4892 		int next_admin;
4893 
4894 		/* Backup next admin */
4895 		next_admin = s->next_admin;
4896 
4897 		/* restore current admin state */
4898 		s->next_admin = s->cur_admin;
4899 
4900 		if ((s->cur_state != SRV_ST_STOPPED) && (s->next_state == SRV_ST_STOPPED)) {
4901 			s->last_change = now.tv_sec;
4902 			if (s->proxy->lbprm.set_server_status_down)
4903 				s->proxy->lbprm.set_server_status_down(s);
4904 
4905 			if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
4906 				srv_shutdown_streams(s, SF_ERR_DOWN);
4907 
4908 			/* we might have streams queued on this server and waiting for
4909 			 * a connection. Those which are redispatchable will be queued
4910 			 * to another server or to the proxy itself.
4911 			 */
4912 			xferred = pendconn_redistribute(s);
4913 
4914 			tmptrash = alloc_trash_chunk();
4915 			if (tmptrash) {
4916 				chunk_printf(tmptrash,
4917 				             "%sServer %s/%s is DOWN", s->flags & SRV_F_BACKUP ? "Backup " : "",
4918 				             s->proxy->id, s->id);
4919 
4920 				srv_append_status(tmptrash, s, NULL, xferred, 0);
4921 				ha_warning("%s.\n", tmptrash->area);
4922 
4923 				/* we don't send an alert if the server was previously paused */
4924 				log_level = srv_was_stopping ? LOG_NOTICE : LOG_ALERT;
4925 				send_log(s->proxy, log_level, "%s.\n",
4926 					 tmptrash->area);
4927 				send_email_alert(s, log_level, "%s",
4928 						 tmptrash->area);
4929 				free_trash_chunk(tmptrash);
4930 				tmptrash = NULL;
4931 			}
4932 			if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
4933 				set_backend_down(s->proxy);
4934 
4935 			s->counters.down_trans++;
4936 		}
4937 		else if ((s->cur_state != SRV_ST_STOPPING) && (s->next_state == SRV_ST_STOPPING)) {
4938 			s->last_change = now.tv_sec;
4939 			if (s->proxy->lbprm.set_server_status_down)
4940 				s->proxy->lbprm.set_server_status_down(s);
4941 
4942 			/* we might have streams queued on this server and waiting for
4943 			 * a connection. Those which are redispatchable will be queued
4944 			 * to another server or to the proxy itself.
4945 			 */
4946 			xferred = pendconn_redistribute(s);
4947 
4948 			tmptrash = alloc_trash_chunk();
4949 			if (tmptrash) {
4950 				chunk_printf(tmptrash,
4951 				             "%sServer %s/%s is stopping", s->flags & SRV_F_BACKUP ? "Backup " : "",
4952 				             s->proxy->id, s->id);
4953 
4954 				srv_append_status(tmptrash, s, NULL, xferred, 0);
4955 
4956 				ha_warning("%s.\n", tmptrash->area);
4957 				send_log(s->proxy, LOG_NOTICE, "%s.\n",
4958 					 tmptrash->area);
4959 				free_trash_chunk(tmptrash);
4960 				tmptrash = NULL;
4961 			}
4962 
4963 			if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
4964 				set_backend_down(s->proxy);
4965 		}
4966 		else if (((s->cur_state != SRV_ST_RUNNING) && (s->next_state == SRV_ST_RUNNING))
4967 			 || ((s->cur_state != SRV_ST_STARTING) && (s->next_state == SRV_ST_STARTING))) {
4968 			if (s->proxy->srv_bck == 0 && s->proxy->srv_act == 0) {
4969 				if (s->proxy->last_change < now.tv_sec)		// ignore negative times
4970 					s->proxy->down_time += now.tv_sec - s->proxy->last_change;
4971 				s->proxy->last_change = now.tv_sec;
4972 			}
4973 
4974 			if (s->cur_state == SRV_ST_STOPPED && s->last_change < now.tv_sec)	// ignore negative times
4975 				s->down_time += now.tv_sec - s->last_change;
4976 
4977 			s->last_change = now.tv_sec;
4978 			if (s->next_state == SRV_ST_STARTING && s->warmup)
4979 				task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
4980 
4981 			server_recalc_eweight(s, 0);
4982 			/* now propagate the status change to any LB algorithms */
4983 			if (px->lbprm.update_server_eweight)
4984 				px->lbprm.update_server_eweight(s);
4985 			else if (srv_willbe_usable(s)) {
4986 				if (px->lbprm.set_server_status_up)
4987 					px->lbprm.set_server_status_up(s);
4988 			}
4989 			else {
4990 				if (px->lbprm.set_server_status_down)
4991 					px->lbprm.set_server_status_down(s);
4992 			}
4993 
4994 			/* If the server is set with "on-marked-up shutdown-backup-sessions",
4995 			 * and it's not a backup server and its effective weight is > 0,
4996 			 * then it can accept new connections, so we shut down all streams
4997 			 * on all backup servers.
4998 			 */
4999 			if ((s->onmarkedup & HANA_ONMARKEDUP_SHUTDOWNBACKUPSESSIONS) &&
5000 			    !(s->flags & SRV_F_BACKUP) && s->next_eweight)
5001 				srv_shutdown_backup_streams(s->proxy, SF_ERR_UP);
5002 
5003 			/* check if we can handle some connections queued at the proxy. We
5004 			 * will take as many as we can handle.
5005 			 */
5006 			xferred = pendconn_grab_from_px(s);
5007 
5008 			tmptrash = alloc_trash_chunk();
5009 			if (tmptrash) {
5010 				chunk_printf(tmptrash,
5011 				             "%sServer %s/%s is UP", s->flags & SRV_F_BACKUP ? "Backup " : "",
5012 				             s->proxy->id, s->id);
5013 
5014 				srv_append_status(tmptrash, s, NULL, xferred, 0);
5015 				ha_warning("%s.\n", tmptrash->area);
5016 				send_log(s->proxy, LOG_NOTICE, "%s.\n",
5017 					 tmptrash->area);
5018 				send_email_alert(s, LOG_NOTICE, "%s",
5019 						 tmptrash->area);
5020 				free_trash_chunk(tmptrash);
5021 				tmptrash = NULL;
5022 			}
5023 
5024 			if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
5025 				set_backend_down(s->proxy);
5026 		}
5027 		else if (s->cur_eweight != s->next_eweight) {
5028 			/* now propagate the status change to any LB algorithms */
5029 			if (px->lbprm.update_server_eweight)
5030 				px->lbprm.update_server_eweight(s);
5031 			else if (srv_willbe_usable(s)) {
5032 				if (px->lbprm.set_server_status_up)
5033 					px->lbprm.set_server_status_up(s);
5034 			}
5035 			else {
5036 				if (px->lbprm.set_server_status_down)
5037 					px->lbprm.set_server_status_down(s);
5038 			}
5039 
5040 			if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
5041 				set_backend_down(s->proxy);
5042 		}
5043 
5044 		s->next_admin = next_admin;
5045 	}
5046 
5047 	/* reset operational state change */
5048 	*s->op_st_chg.reason = 0;
5049 	s->op_st_chg.status = s->op_st_chg.code = -1;
5050 	s->op_st_chg.duration = 0;
5051 
5052 	/* Now we try to apply pending admin changes */
5053 
5054 	/* Maintenance must also disable health checks */
5055 	if (!(s->cur_admin & SRV_ADMF_MAINT) && (s->next_admin & SRV_ADMF_MAINT)) {
5056 		if (s->check.state & CHK_ST_ENABLED) {
5057 			s->check.state |= CHK_ST_PAUSED;
5058 			check->health = 0;
5059 		}
5060 
5061 		if (s->cur_state == SRV_ST_STOPPED) {	/* server was already down */
5062 			tmptrash = alloc_trash_chunk();
5063 			if (tmptrash) {
5064 				chunk_printf(tmptrash,
5065 				    "%sServer %s/%s was DOWN and now enters maintenance%s%s%s",
5066 				    s->flags & SRV_F_BACKUP ? "Backup " : "", s->proxy->id, s->id,
5067 				    *(s->adm_st_chg_cause) ? " (" : "", s->adm_st_chg_cause, *(s->adm_st_chg_cause) ? ")" : "");
5068 
5069 				srv_append_status(tmptrash, s, NULL, -1, (s->next_admin & SRV_ADMF_FMAINT));
5070 
5071 				if (!(global.mode & MODE_STARTING)) {
5072 					ha_warning("%s.\n", tmptrash->area);
5073 					send_log(s->proxy, LOG_NOTICE, "%s.\n",
5074 						 tmptrash->area);
5075 				}
5076 				free_trash_chunk(tmptrash);
5077 				tmptrash = NULL;
5078 			}
5079 			/* commit new admin status */
5080 
5081 			s->cur_admin = s->next_admin;
5082 		}
5083 		else {	/* server was still running */
5084 			check->health = 0; /* failure */
5085 			s->last_change = now.tv_sec;
5086 
5087 			s->next_state = SRV_ST_STOPPED;
5088 			if (s->proxy->lbprm.set_server_status_down)
5089 				s->proxy->lbprm.set_server_status_down(s);
5090 
5091 			if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
5092 				srv_shutdown_streams(s, SF_ERR_DOWN);
5093 
5094 			/* force connection cleanup on the given server */
5095 			srv_cleanup_connections(s);
5096 			/* we might have streams queued on this server and waiting for
5097 			 * a connection. Those which are redispatchable will be queued
5098 			 * to another server or to the proxy itself.
5099 			 */
5100 			xferred = pendconn_redistribute(s);
5101 
5102 			tmptrash = alloc_trash_chunk();
5103 			if (tmptrash) {
5104 				chunk_printf(tmptrash,
5105 				             "%sServer %s/%s is going DOWN for maintenance%s%s%s",
5106 				             s->flags & SRV_F_BACKUP ? "Backup " : "",
5107 				             s->proxy->id, s->id,
5108 				             *(s->adm_st_chg_cause) ? " (" : "", s->adm_st_chg_cause, *(s->adm_st_chg_cause) ? ")" : "");
5109 
5110 				srv_append_status(tmptrash, s, NULL, xferred, (s->next_admin & SRV_ADMF_FMAINT));
5111 
5112 				if (!(global.mode & MODE_STARTING)) {
5113 					ha_warning("%s.\n", tmptrash->area);
5114 					send_log(s->proxy, srv_was_stopping ? LOG_NOTICE : LOG_ALERT, "%s.\n",
5115 						 tmptrash->area);
5116 				}
5117 				free_trash_chunk(tmptrash);
5118 				tmptrash = NULL;
5119 			}
5120 			if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
5121 				set_backend_down(s->proxy);
5122 
5123 			s->counters.down_trans++;
5124 		}
5125 	}
5126 	else if ((s->cur_admin & SRV_ADMF_MAINT) && !(s->next_admin & SRV_ADMF_MAINT)) {
5127 		/* OK here we're leaving maintenance, we have many things to check,
5128 		 * because the server might possibly be coming back up depending on
5129 		 * its state. In practice, leaving maintenance means that we should
5130 		 * immediately turn to UP (more or less the slowstart) under the
5131 		 * following conditions :
5132 		 *   - server is neither checked nor tracked
5133 		 *   - server tracks another server which is not checked
5134 		 *   - server tracks another server which is already up
5135 		 * Which sums up as something simpler :
5136 		 * "either the tracking server is up or the server's checks are disabled
5137 		 * or up". Otherwise we only re-enable health checks. There's a special
5138 		 * case associated to the stopping state which can be inherited. Note
5139 		 * that the server might still be in drain mode, which is naturally dealt
5140 		 * with by the lower level functions.
5141 		 */
5142 
5143 		if (s->check.state & CHK_ST_ENABLED) {
5144 			s->check.state &= ~CHK_ST_PAUSED;
5145 			check->health = check->rise; /* start OK but check immediately */
5146 		}
5147 
5148 		if ((!s->track || s->track->next_state != SRV_ST_STOPPED) &&
5149 		    (!(s->agent.state & CHK_ST_ENABLED) || (s->agent.health >= s->agent.rise)) &&
5150 		    (!(s->check.state & CHK_ST_ENABLED) || (s->check.health >= s->check.rise))) {
5151 			if (s->track && s->track->next_state == SRV_ST_STOPPING) {
5152 				s->next_state = SRV_ST_STOPPING;
5153 			}
5154 			else {
5155 				s->last_change = now.tv_sec;
5156 				s->next_state = SRV_ST_STARTING;
5157 				if (s->slowstart > 0) {
5158 					if (s->warmup)
5159 						task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
5160 				}
5161 				else
5162 					s->next_state = SRV_ST_RUNNING;
5163 			}
5164 
5165 		}
5166 
5167 		tmptrash = alloc_trash_chunk();
5168 		if (tmptrash) {
5169 			if (!(s->next_admin & SRV_ADMF_FMAINT) && (s->cur_admin & SRV_ADMF_FMAINT)) {
5170 				chunk_printf(tmptrash,
5171 					     "%sServer %s/%s is %s/%s (leaving forced maintenance)",
5172 					     s->flags & SRV_F_BACKUP ? "Backup " : "",
5173 					     s->proxy->id, s->id,
5174 					     (s->next_state == SRV_ST_STOPPED) ? "DOWN" : "UP",
5175 					     (s->next_admin & SRV_ADMF_DRAIN) ? "DRAIN" : "READY");
5176 			}
5177 			if (!(s->next_admin & SRV_ADMF_RMAINT) && (s->cur_admin & SRV_ADMF_RMAINT)) {
5178 				chunk_printf(tmptrash,
5179 					     "%sServer %s/%s ('%s') is %s/%s (resolves again)",
5180 					     s->flags & SRV_F_BACKUP ? "Backup " : "",
5181 					     s->proxy->id, s->id, s->hostname,
5182 					     (s->next_state == SRV_ST_STOPPED) ? "DOWN" : "UP",
5183 					     (s->next_admin & SRV_ADMF_DRAIN) ? "DRAIN" : "READY");
5184 			}
5185 			if (!(s->next_admin & SRV_ADMF_IMAINT) && (s->cur_admin & SRV_ADMF_IMAINT)) {
5186 				chunk_printf(tmptrash,
5187 					     "%sServer %s/%s is %s/%s (leaving maintenance)",
5188 					     s->flags & SRV_F_BACKUP ? "Backup " : "",
5189 					     s->proxy->id, s->id,
5190 					     (s->next_state == SRV_ST_STOPPED) ? "DOWN" : "UP",
5191 					     (s->next_admin & SRV_ADMF_DRAIN) ? "DRAIN" : "READY");
5192 			}
5193 			ha_warning("%s.\n", tmptrash->area);
5194 			send_log(s->proxy, LOG_NOTICE, "%s.\n",
5195 				 tmptrash->area);
5196 			free_trash_chunk(tmptrash);
5197 			tmptrash = NULL;
5198 		}
5199 
5200 		server_recalc_eweight(s, 0);
5201 		/* now propagate the status change to any LB algorithms */
5202 		if (px->lbprm.update_server_eweight)
5203 			px->lbprm.update_server_eweight(s);
5204 		else if (srv_willbe_usable(s)) {
5205 			if (px->lbprm.set_server_status_up)
5206 				px->lbprm.set_server_status_up(s);
5207 		}
5208 		else {
5209 			if (px->lbprm.set_server_status_down)
5210 				px->lbprm.set_server_status_down(s);
5211 		}
5212 
5213 		if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
5214 			set_backend_down(s->proxy);
5215 		else if (!prev_srv_count && (s->proxy->srv_bck || s->proxy->srv_act))
5216 			s->proxy->last_change = now.tv_sec;
5217 
5218 		/* If the server is set with "on-marked-up shutdown-backup-sessions",
5219 		 * and it's not a backup server and its effective weight is > 0,
5220 		 * then it can accept new connections, so we shut down all streams
5221 		 * on all backup servers.
5222 		 */
5223 		if ((s->onmarkedup & HANA_ONMARKEDUP_SHUTDOWNBACKUPSESSIONS) &&
5224 		    !(s->flags & SRV_F_BACKUP) && s->next_eweight)
5225 			srv_shutdown_backup_streams(s->proxy, SF_ERR_UP);
5226 
5227 		/* check if we can handle some connections queued at the proxy. We
5228 		 * will take as many as we can handle.
5229 		 */
5230 		xferred = pendconn_grab_from_px(s);
5231 	}
5232 	else if (s->next_admin & SRV_ADMF_MAINT) {
5233 		/* remaining in maintenance mode, let's inform precisely about the
5234 		 * situation.
5235 		 */
5236 		if (!(s->next_admin & SRV_ADMF_FMAINT) && (s->cur_admin & SRV_ADMF_FMAINT)) {
5237 			tmptrash = alloc_trash_chunk();
5238 			if (tmptrash) {
5239 				chunk_printf(tmptrash,
5240 				             "%sServer %s/%s is leaving forced maintenance but remains in maintenance",
5241 				             s->flags & SRV_F_BACKUP ? "Backup " : "",
5242 				             s->proxy->id, s->id);
5243 
5244 				if (s->track) /* normally it's mandatory here */
5245 					chunk_appendf(tmptrash, " via %s/%s",
5246 				              s->track->proxy->id, s->track->id);
5247 				ha_warning("%s.\n", tmptrash->area);
5248 				send_log(s->proxy, LOG_NOTICE, "%s.\n",
5249 					 tmptrash->area);
5250 				free_trash_chunk(tmptrash);
5251 				tmptrash = NULL;
5252 			}
5253 		}
5254 		if (!(s->next_admin & SRV_ADMF_RMAINT) && (s->cur_admin & SRV_ADMF_RMAINT)) {
5255 			tmptrash = alloc_trash_chunk();
5256 			if (tmptrash) {
5257 				chunk_printf(tmptrash,
5258 				             "%sServer %s/%s ('%s') resolves again but remains in maintenance",
5259 				             s->flags & SRV_F_BACKUP ? "Backup " : "",
5260 				             s->proxy->id, s->id, s->hostname);
5261 
5262 				if (s->track) /* normally it's mandatory here */
5263 					chunk_appendf(tmptrash, " via %s/%s",
5264 				              s->track->proxy->id, s->track->id);
5265 				ha_warning("%s.\n", tmptrash->area);
5266 				send_log(s->proxy, LOG_NOTICE, "%s.\n",
5267 					 tmptrash->area);
5268 				free_trash_chunk(tmptrash);
5269 				tmptrash = NULL;
5270 			}
5271 		}
5272 		else if (!(s->next_admin & SRV_ADMF_IMAINT) && (s->cur_admin & SRV_ADMF_IMAINT)) {
5273 			tmptrash = alloc_trash_chunk();
5274 			if (tmptrash) {
5275 				chunk_printf(tmptrash,
5276 				             "%sServer %s/%s remains in forced maintenance",
5277 				             s->flags & SRV_F_BACKUP ? "Backup " : "",
5278 				             s->proxy->id, s->id);
5279 				ha_warning("%s.\n", tmptrash->area);
5280 				send_log(s->proxy, LOG_NOTICE, "%s.\n",
5281 					 tmptrash->area);
5282 				free_trash_chunk(tmptrash);
5283 				tmptrash = NULL;
5284 			}
5285 		}
5286 		/* don't report anything when leaving drain mode and remaining in maintenance */
5287 
5288 		s->cur_admin = s->next_admin;
5289 	}
5290 
5291 	if (!(s->next_admin & SRV_ADMF_MAINT)) {
5292 		if (!(s->cur_admin & SRV_ADMF_DRAIN) && (s->next_admin & SRV_ADMF_DRAIN)) {
5293 			/* drain state is applied only if not yet in maint */
5294 
5295 			s->last_change = now.tv_sec;
5296 			if (px->lbprm.set_server_status_down)
5297 				px->lbprm.set_server_status_down(s);
5298 
5299 			/* we might have streams queued on this server and waiting for
5300 			 * a connection. Those which are redispatchable will be queued
5301 			 * to another server or to the proxy itself.
5302 			 */
5303 			xferred = pendconn_redistribute(s);
5304 
5305 			tmptrash = alloc_trash_chunk();
5306 			if (tmptrash) {
5307 				chunk_printf(tmptrash, "%sServer %s/%s enters drain state%s%s%s",
5308 					     s->flags & SRV_F_BACKUP ? "Backup " : "", s->proxy->id, s->id,
5309 				             *(s->adm_st_chg_cause) ? " (" : "", s->adm_st_chg_cause, *(s->adm_st_chg_cause) ? ")" : "");
5310 
5311 				srv_append_status(tmptrash, s, NULL, xferred, (s->next_admin & SRV_ADMF_FDRAIN));
5312 
5313 				if (!(global.mode & MODE_STARTING)) {
5314 					ha_warning("%s.\n", tmptrash->area);
5315 					send_log(s->proxy, LOG_NOTICE, "%s.\n",
5316 						 tmptrash->area);
5317 					send_email_alert(s, LOG_NOTICE, "%s",
5318 							 tmptrash->area);
5319 				}
5320 				free_trash_chunk(tmptrash);
5321 				tmptrash = NULL;
5322 			}
5323 
5324 			if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
5325 				set_backend_down(s->proxy);
5326 		}
5327 		else if ((s->cur_admin & SRV_ADMF_DRAIN) && !(s->next_admin & SRV_ADMF_DRAIN)) {
5328 			/* OK completely leaving drain mode */
5329 			if (s->proxy->srv_bck == 0 && s->proxy->srv_act == 0) {
5330 				if (s->proxy->last_change < now.tv_sec)         // ignore negative times
5331 					s->proxy->down_time += now.tv_sec - s->proxy->last_change;
5332 				s->proxy->last_change = now.tv_sec;
5333 			}
5334 
5335 			if (s->last_change < now.tv_sec)                        // ignore negative times
5336 				s->down_time += now.tv_sec - s->last_change;
5337 			s->last_change = now.tv_sec;
5338 			server_recalc_eweight(s, 0);
5339 
5340 			tmptrash = alloc_trash_chunk();
5341 			if (tmptrash) {
5342 				if (!(s->next_admin & SRV_ADMF_FDRAIN)) {
5343 					chunk_printf(tmptrash,
5344 						     "%sServer %s/%s is %s (leaving forced drain)",
5345 						     s->flags & SRV_F_BACKUP ? "Backup " : "",
5346 					             s->proxy->id, s->id,
5347 					             (s->next_state == SRV_ST_STOPPED) ? "DOWN" : "UP");
5348 				}
5349 				else {
5350 					chunk_printf(tmptrash,
5351 					             "%sServer %s/%s is %s (leaving drain)",
5352 					             s->flags & SRV_F_BACKUP ? "Backup " : "",
5353 						     s->proxy->id, s->id,
5354 						     (s->next_state == SRV_ST_STOPPED) ? "DOWN" : "UP");
5355 					if (s->track) /* normally it's mandatory here */
5356 						chunk_appendf(tmptrash, " via %s/%s",
5357 					s->track->proxy->id, s->track->id);
5358 				}
5359 
5360 				ha_warning("%s.\n", tmptrash->area);
5361 				send_log(s->proxy, LOG_NOTICE, "%s.\n",
5362 					 tmptrash->area);
5363 				free_trash_chunk(tmptrash);
5364 				tmptrash = NULL;
5365 			}
5366 
5367 			/* now propagate the status change to any LB algorithms */
5368 			if (px->lbprm.update_server_eweight)
5369 				px->lbprm.update_server_eweight(s);
5370 			else if (srv_willbe_usable(s)) {
5371 				if (px->lbprm.set_server_status_up)
5372 					px->lbprm.set_server_status_up(s);
5373 			}
5374 			else {
5375 				if (px->lbprm.set_server_status_down)
5376 					px->lbprm.set_server_status_down(s);
5377 			}
5378 		}
5379 		else if ((s->next_admin & SRV_ADMF_DRAIN)) {
5380 			/* remaining in drain mode after removing one of its flags */
5381 
5382 			tmptrash = alloc_trash_chunk();
5383 			if (tmptrash) {
5384 				if (!(s->next_admin & SRV_ADMF_FDRAIN)) {
5385 					chunk_printf(tmptrash,
5386 					             "%sServer %s/%s is leaving forced drain but remains in drain mode",
5387 					             s->flags & SRV_F_BACKUP ? "Backup " : "",
5388 					             s->proxy->id, s->id);
5389 
5390 					if (s->track) /* normally it's mandatory here */
5391 						chunk_appendf(tmptrash, " via %s/%s",
5392 					              s->track->proxy->id, s->track->id);
5393 				}
5394 				else {
5395 					chunk_printf(tmptrash,
5396 					             "%sServer %s/%s remains in forced drain mode",
5397 					             s->flags & SRV_F_BACKUP ? "Backup " : "",
5398 					             s->proxy->id, s->id);
5399 				}
5400 				ha_warning("%s.\n", tmptrash->area);
5401 				send_log(s->proxy, LOG_NOTICE, "%s.\n",
5402 					 tmptrash->area);
5403 				free_trash_chunk(tmptrash);
5404 				tmptrash = NULL;
5405 			}
5406 
5407 			/* commit new admin status */
5408 
5409 			s->cur_admin = s->next_admin;
5410 		}
5411 	}
5412 
5413 	/* Re-set log strings to empty */
5414 	*s->adm_st_chg_cause = 0;
5415 }
5416 
srv_cleanup_toremove_conns(struct task * task,void * context,unsigned int state)5417 struct task *srv_cleanup_toremove_conns(struct task *task, void *context, unsigned int state)
5418 {
5419 	struct connection *conn;
5420 
5421 	while ((conn = MT_LIST_POP(&idle_conns[tid].toremove_conns,
5422 	                               struct connection *, toremove_list)) != NULL) {
5423 		conn->mux->destroy(conn->ctx);
5424 	}
5425 
5426 	return task;
5427 }
5428 
5429 /* Move toremove_nb connections from idle_tree to toremove_list, -1 means
5430  * moving them all.
5431  * Returns the number of connections moved.
5432  *
5433  * Must be called with idle_conns_lock held.
5434  */
srv_migrate_conns_to_remove(struct eb_root * idle_tree,struct mt_list * toremove_list,int toremove_nb)5435 static int srv_migrate_conns_to_remove(struct eb_root *idle_tree, struct mt_list *toremove_list, int toremove_nb)
5436 {
5437 	struct eb_node *node, *next;
5438 	struct conn_hash_node *hash_node;
5439 	int i = 0;
5440 
5441 	node = eb_first(idle_tree);
5442 	while (node) {
5443 		next = eb_next(node);
5444 		if (toremove_nb != -1 && i >= toremove_nb)
5445 			break;
5446 
5447 		hash_node = ebmb_entry(node, struct conn_hash_node, node);
5448 		eb_delete(node);
5449 		MT_LIST_APPEND(toremove_list, &hash_node->conn->toremove_list);
5450 		i++;
5451 
5452 		node = next;
5453 	}
5454 	return i;
5455 }
5456 /* cleanup connections for a given server
5457  * might be useful when going on forced maintenance or live changing ip/port
5458  */
srv_cleanup_connections(struct server * srv)5459 static void srv_cleanup_connections(struct server *srv)
5460 {
5461 	int did_remove;
5462 	int i;
5463 
5464 	/* nothing to do if pool-max-conn is null */
5465 	if (!srv->max_idle_conns)
5466 		return;
5467 
5468 	/* check all threads starting with ours */
5469 	for (i = tid;;) {
5470 		did_remove = 0;
5471 		HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[i].idle_conns_lock);
5472 		if (srv_migrate_conns_to_remove(&srv->per_thr[i].idle_conns, &idle_conns[i].toremove_conns, -1) > 0)
5473 			did_remove = 1;
5474 		if (srv_migrate_conns_to_remove(&srv->per_thr[i].safe_conns, &idle_conns[i].toremove_conns, -1) > 0)
5475 			did_remove = 1;
5476 		HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[i].idle_conns_lock);
5477 		if (did_remove)
5478 			task_wakeup(idle_conns[i].cleanup_task, TASK_WOKEN_OTHER);
5479 
5480 		if ((i = ((i + 1 == global.nbthread) ? 0 : i + 1)) == tid)
5481 			break;
5482 	}
5483 }
5484 
srv_cleanup_idle_conns(struct task * task,void * context,unsigned int state)5485 struct task *srv_cleanup_idle_conns(struct task *task, void *context, unsigned int state)
5486 {
5487 	struct server *srv;
5488 	struct eb32_node *eb;
5489 	int i;
5490 	unsigned int next_wakeup;
5491 
5492 	next_wakeup = TICK_ETERNITY;
5493 	HA_SPIN_LOCK(OTHER_LOCK, &idle_conn_srv_lock);
5494 	while (1) {
5495 		int exceed_conns;
5496 		int to_kill;
5497 		int curr_idle;
5498 
5499 		eb = eb32_lookup_ge(&idle_conn_srv, now_ms - TIMER_LOOK_BACK);
5500 		if (!eb) {
5501 			/* we might have reached the end of the tree, typically because
5502 			 * <now_ms> is in the first half and we're first scanning the last
5503 			* half. Let's loop back to the beginning of the tree now.
5504 			*/
5505 
5506 			eb = eb32_first(&idle_conn_srv);
5507 			if (likely(!eb))
5508 				break;
5509 		}
5510 		if (tick_is_lt(now_ms, eb->key)) {
5511 			/* timer not expired yet, revisit it later */
5512 			next_wakeup = eb->key;
5513 			break;
5514 		}
5515 		srv = eb32_entry(eb, struct server, idle_node);
5516 
5517 		/* Calculate how many idle connections we want to kill :
5518 		 * we want to remove half the difference between the total
5519 		 * of established connections (used or idle) and the max
5520 		 * number of used connections.
5521 		 */
5522 		curr_idle = srv->curr_idle_conns;
5523 		if (curr_idle == 0)
5524 			goto remove;
5525 		exceed_conns = srv->curr_used_conns + curr_idle - MAX(srv->max_used_conns, srv->est_need_conns);
5526 		exceed_conns = to_kill = exceed_conns / 2 + (exceed_conns & 1);
5527 
5528 		srv->est_need_conns = (srv->est_need_conns + srv->max_used_conns) / 2;
5529 		if (srv->est_need_conns < srv->max_used_conns)
5530 			srv->est_need_conns = srv->max_used_conns;
5531 
5532 		srv->max_used_conns = srv->curr_used_conns;
5533 
5534 		if (exceed_conns <= 0)
5535 			goto remove;
5536 
5537 		/* check all threads starting with ours */
5538 		for (i = tid;;) {
5539 			int max_conn;
5540 			int j;
5541 			int did_remove = 0;
5542 
5543 			max_conn = (exceed_conns * srv->curr_idle_thr[i]) /
5544 			           curr_idle + 1;
5545 
5546 			HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[i].idle_conns_lock);
5547 			j = srv_migrate_conns_to_remove(&srv->per_thr[i].idle_conns, &idle_conns[i].toremove_conns, max_conn);
5548 			if (j > 0)
5549 				did_remove = 1;
5550 			if (max_conn - j > 0 &&
5551 			    srv_migrate_conns_to_remove(&srv->per_thr[i].safe_conns, &idle_conns[i].toremove_conns, max_conn - j) > 0)
5552 				did_remove = 1;
5553 			HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[i].idle_conns_lock);
5554 
5555 			if (did_remove)
5556 				task_wakeup(idle_conns[i].cleanup_task, TASK_WOKEN_OTHER);
5557 
5558 			if ((i = ((i + 1 == global.nbthread) ? 0 : i + 1)) == tid)
5559 				break;
5560 		}
5561 remove:
5562 		eb32_delete(&srv->idle_node);
5563 
5564 		if (srv->curr_idle_conns) {
5565 			/* There are still more idle connections, add the
5566 			 * server back in the tree.
5567 			 */
5568 			srv->idle_node.key = tick_add(srv->pool_purge_delay, now_ms);
5569 			eb32_insert(&idle_conn_srv, &srv->idle_node);
5570 			next_wakeup = tick_first(next_wakeup, srv->idle_node.key);
5571 		}
5572 	}
5573 	HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conn_srv_lock);
5574 
5575 	task->expire = next_wakeup;
5576 	return task;
5577 }
5578 
5579 /* Close remaining idle connections. This functions is designed to be run on
5580  * process shutdown. This guarantees a proper socket shutdown to avoid
5581  * TIME_WAIT state. For a quick operation, only ctrl is closed, xprt stack is
5582  * bypassed.
5583  *
5584  * This function is not thread-safe so it must only be called via a global
5585  * deinit function.
5586  */
srv_close_idle_conns(struct server * srv)5587 static void srv_close_idle_conns(struct server *srv)
5588 {
5589 	struct eb_root **cleaned_tree;
5590 	int i;
5591 
5592 	for (i = 0; i < global.nbthread; ++i) {
5593 		struct eb_root *conn_trees[] = {
5594 			&srv->per_thr[i].idle_conns,
5595 			&srv->per_thr[i].safe_conns,
5596 			&srv->per_thr[i].avail_conns,
5597 			NULL
5598 		};
5599 
5600 		for (cleaned_tree = conn_trees; *cleaned_tree; ++cleaned_tree) {
5601 			while (!eb_is_empty(*cleaned_tree)) {
5602 				struct ebmb_node *node = ebmb_first(*cleaned_tree);
5603 				struct conn_hash_node *conn_hash_node = ebmb_entry(node, struct conn_hash_node, node);
5604 				struct connection *conn = conn_hash_node->conn;
5605 
5606 				if (conn->ctrl->ctrl_close)
5607 					conn->ctrl->ctrl_close(conn);
5608 				ebmb_delete(node);
5609 			}
5610 		}
5611 	}
5612 }
5613 
5614 REGISTER_SERVER_DEINIT(srv_close_idle_conns);
5615 
5616 /* config parser for global "tune.idle-pool.shared", accepts "on" or "off" */
cfg_parse_idle_pool_shared(char ** args,int section_type,struct proxy * curpx,const struct proxy * defpx,const char * file,int line,char ** err)5617 static int cfg_parse_idle_pool_shared(char **args, int section_type, struct proxy *curpx,
5618                                       const struct proxy *defpx, const char *file, int line,
5619                                       char **err)
5620 {
5621 	if (too_many_args(1, args, err, NULL))
5622 		return -1;
5623 
5624 	if (strcmp(args[1], "on") == 0)
5625 		global.tune.options |= GTUNE_IDLE_POOL_SHARED;
5626 	else if (strcmp(args[1], "off") == 0)
5627 		global.tune.options &= ~GTUNE_IDLE_POOL_SHARED;
5628 	else {
5629 		memprintf(err, "'%s' expects either 'on' or 'off' but got '%s'.", args[0], args[1]);
5630 		return -1;
5631 	}
5632 	return 0;
5633 }
5634 
5635 /* config parser for global "tune.pool-{low,high}-fd-ratio" */
cfg_parse_pool_fd_ratio(char ** args,int section_type,struct proxy * curpx,const struct proxy * defpx,const char * file,int line,char ** err)5636 static int cfg_parse_pool_fd_ratio(char **args, int section_type, struct proxy *curpx,
5637                                    const struct proxy *defpx, const char *file, int line,
5638                                    char **err)
5639 {
5640 	int arg = -1;
5641 
5642 	if (too_many_args(1, args, err, NULL))
5643 		return -1;
5644 
5645 	if (*(args[1]) != 0)
5646 		arg = atoi(args[1]);
5647 
5648 	if (arg < 0 || arg > 100) {
5649 		memprintf(err, "'%s' expects an integer argument between 0 and 100.", args[0]);
5650 		return -1;
5651 	}
5652 
5653 	if (args[0][10] == 'h')
5654 		global.tune.pool_high_ratio = arg;
5655 	else
5656 		global.tune.pool_low_ratio = arg;
5657 	return 0;
5658 }
5659 
5660 /* config keyword parsers */
5661 static struct cfg_kw_list cfg_kws = {ILH, {
5662 	{ CFG_GLOBAL, "tune.idle-pool.shared",       cfg_parse_idle_pool_shared },
5663 	{ CFG_GLOBAL, "tune.pool-high-fd-ratio",     cfg_parse_pool_fd_ratio },
5664 	{ CFG_GLOBAL, "tune.pool-low-fd-ratio",      cfg_parse_pool_fd_ratio },
5665 	{ 0, NULL, NULL }
5666 }};
5667 
5668 INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
5669 
5670 /*
5671  * Local variables:
5672  *  c-indent-level: 8
5673  *  c-basic-offset: 8
5674  * End:
5675  */
5676