1 /*
2  * Proxy variables and functions.
3  *
4  * Copyright 2000-2009 Willy Tarreau <w@1wt.eu>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  */
12 
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <sys/stat.h>
19 
20 #include <common/defaults.h>
21 #include <common/cfgparse.h>
22 #include <common/compat.h>
23 #include <common/config.h>
24 #include <common/errors.h>
25 #include <common/initcall.h>
26 #include <common/memory.h>
27 #include <common/time.h>
28 
29 #include <eb32tree.h>
30 #include <ebistree.h>
31 
32 #include <types/capture.h>
33 #include <types/cli.h>
34 #include <types/global.h>
35 #include <types/obj_type.h>
36 #include <types/peers.h>
37 #include <types/stats.h>
38 
39 #include <proto/applet.h>
40 #include <proto/cli.h>
41 #include <proto/backend.h>
42 #include <proto/fd.h>
43 #include <proto/filters.h>
44 #include <proto/listener.h>
45 #include <proto/log.h>
46 #include <proto/proto_tcp.h>
47 #include <proto/http_ana.h>
48 #include <proto/proxy.h>
49 #include <proto/server.h>
50 #include <proto/signal.h>
51 #include <proto/stream.h>
52 #include <proto/stream_interface.h>
53 #include <proto/task.h>
54 
55 
56 int listeners;	/* # of proxy listeners, set by cfgparse */
57 struct proxy *proxies_list  = NULL;	/* list of all existing proxies */
58 struct eb_root used_proxy_id = EB_ROOT;	/* list of proxy IDs in use */
59 struct eb_root proxy_by_name = EB_ROOT; /* tree of proxies sorted by name */
60 unsigned int error_snapshot_id = 0;     /* global ID assigned to each error then incremented */
61 
62 /* proxy->options */
63 const struct cfg_opt cfg_opts[] =
64 {
65 	{ "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
66 	{ "allbackups",   PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
67 	{ "checkcache",   PR_O_CHK_CACHE,  PR_CAP_BE, 0, PR_MODE_HTTP },
68 	{ "clitcpka",     PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
69 	{ "contstats",    PR_O_CONTSTATS,  PR_CAP_FE, 0, 0 },
70 	{ "dontlognull",  PR_O_NULLNOLOG,  PR_CAP_FE, 0, 0 },
71 	{ "http_proxy",	  PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
72 	{ "http-buffer-request", PR_O_WREQ_BODY,  PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
73 	{ "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
74 	{ "prefer-last-server", PR_O_PREF_LAST,  PR_CAP_BE, 0, PR_MODE_HTTP },
75 	{ "logasap",      PR_O_LOGASAP,    PR_CAP_FE, 0, 0 },
76 	{ "nolinger",     PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
77 	{ "persist",      PR_O_PERSIST,    PR_CAP_BE, 0, 0 },
78 	{ "srvtcpka",     PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
79 #ifdef USE_TPROXY
80 	{ "transparent",  PR_O_TRANSP,     PR_CAP_BE, 0, 0 },
81 #else
82 	{ "transparent",  0, 0, 0, 0 },
83 #endif
84 
85 	{ NULL, 0, 0, 0, 0 }
86 };
87 
88 /* proxy->options2 */
89 const struct cfg_opt cfg_opts2[] =
90 {
91 #ifdef USE_LINUX_SPLICE
92 	{ "splice-request",  PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
93 	{ "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
94 	{ "splice-auto",     PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
95 #else
96         { "splice-request",  0, 0, 0, 0 },
97         { "splice-response", 0, 0, 0, 0 },
98         { "splice-auto",     0, 0, 0, 0 },
99 #endif
100 	{ "accept-invalid-http-request",  PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
101 	{ "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
102 	{ "dontlog-normal",               PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
103 	{ "log-separate-errors",          PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
104 	{ "log-health-checks",            PR_O2_LOGHCHKS,  PR_CAP_BE, 0, 0 },
105 	{ "socket-stats",                 PR_O2_SOCKSTAT,  PR_CAP_FE, 0, 0 },
106 	{ "tcp-smart-accept",             PR_O2_SMARTACC,  PR_CAP_FE, 0, 0 },
107 	{ "tcp-smart-connect",            PR_O2_SMARTCON,  PR_CAP_BE, 0, 0 },
108 	{ "independent-streams",          PR_O2_INDEPSTR,  PR_CAP_FE|PR_CAP_BE, 0, 0 },
109 	{ "http-use-proxy-header",        PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
110 	{ "http-pretend-keepalive",       PR_O2_FAKE_KA,   PR_CAP_BE, 0, PR_MODE_HTTP },
111 	{ "http-no-delay",                PR_O2_NODELAY,   PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
112 	{ "http-use-htx",                 0,               PR_CAP_FE|PR_CAP_BE, 0, 0 }, // deprecated
113 
114 	{"h1-case-adjust-bogus-client",   PR_O2_H1_ADJ_BUGCLI, PR_CAP_FE, 0, PR_MODE_HTTP },
115 	{"h1-case-adjust-bogus-server",   PR_O2_H1_ADJ_BUGSRV, PR_CAP_BE, 0, PR_MODE_HTTP },
116 	{ NULL, 0, 0, 0 }
117 };
118 
119 /*
120  * This function returns a string containing a name describing capabilities to
121  * report comprehensible error messages. Specifically, it will return the words
122  * "frontend", "backend" when appropriate, or "proxy" for all other
123  * cases including the proxies declared in "listen" mode.
124  */
proxy_cap_str(int cap)125 const char *proxy_cap_str(int cap)
126 {
127 	if ((cap & PR_CAP_LISTEN) != PR_CAP_LISTEN) {
128 		if (cap & PR_CAP_FE)
129 			return "frontend";
130 		else if (cap & PR_CAP_BE)
131 			return "backend";
132 	}
133 	return "proxy";
134 }
135 
136 /*
137  * This function returns a string containing the mode of the proxy in a format
138  * suitable for error messages.
139  */
proxy_mode_str(int mode)140 const char *proxy_mode_str(int mode) {
141 
142 	if (mode == PR_MODE_TCP)
143 		return "tcp";
144 	else if (mode == PR_MODE_HTTP)
145 		return "http";
146 	else if (mode == PR_MODE_HEALTH)
147 		return "health";
148 	else if (mode == PR_MODE_CLI)
149 		return "cli";
150 	else
151 		return "unknown";
152 }
153 
154 /*
155  * This function scans the list of backends and servers to retrieve the first
156  * backend and the first server with the given names, and sets them in both
157  * parameters. It returns zero if either is not found, or non-zero and sets
158  * the ones it did not found to NULL. If a NULL pointer is passed for the
159  * backend, only the pointer to the server will be updated.
160  */
get_backend_server(const char * bk_name,const char * sv_name,struct proxy ** bk,struct server ** sv)161 int get_backend_server(const char *bk_name, const char *sv_name,
162 		       struct proxy **bk, struct server **sv)
163 {
164 	struct proxy *p;
165 	struct server *s;
166 	int sid;
167 
168 	*sv = NULL;
169 
170 	sid = -1;
171 	if (*sv_name == '#')
172 		sid = atoi(sv_name + 1);
173 
174 	p = proxy_be_by_name(bk_name);
175 	if (bk)
176 		*bk = p;
177 	if (!p)
178 		return 0;
179 
180 	for (s = p->srv; s; s = s->next)
181 		if ((sid >= 0 && s->puid == sid) ||
182 		    (sid < 0 && strcmp(s->id, sv_name) == 0))
183 			break;
184 	*sv = s;
185 	if (!s)
186 		return 0;
187 	return 1;
188 }
189 
190 /* This function parses a "timeout" statement in a proxy section. It returns
191  * -1 if there is any error, 1 for a warning, otherwise zero. If it does not
192  * return zero, it will write an error or warning message into a preallocated
193  * buffer returned at <err>. The trailing is not be written. The function must
194  * be called with <args> pointing to the first command line word, with <proxy>
195  * pointing to the proxy being parsed, and <defpx> to the default proxy or NULL.
196  * As a special case for compatibility with older configs, it also accepts
197  * "{cli|srv|con}timeout" in args[0].
198  */
proxy_parse_timeout(char ** args,int section,struct proxy * proxy,struct proxy * defpx,const char * file,int line,char ** err)199 static int proxy_parse_timeout(char **args, int section, struct proxy *proxy,
200                                struct proxy *defpx, const char *file, int line,
201                                char **err)
202 {
203 	unsigned timeout;
204 	int retval, cap;
205 	const char *res, *name;
206 	int *tv = NULL;
207 	int *td = NULL;
208 
209 	retval = 0;
210 
211 	/* simply skip "timeout" but remain compatible with old form */
212 	if (strcmp(args[0], "timeout") == 0)
213 		args++;
214 
215 	name = args[0];
216 	if (!strcmp(args[0], "client")) {
217 		name = "client";
218 		tv = &proxy->timeout.client;
219 		td = &defpx->timeout.client;
220 		cap = PR_CAP_FE;
221 	} else if (!strcmp(args[0], "tarpit")) {
222 		tv = &proxy->timeout.tarpit;
223 		td = &defpx->timeout.tarpit;
224 		cap = PR_CAP_FE | PR_CAP_BE;
225 	} else if (!strcmp(args[0], "http-keep-alive")) {
226 		tv = &proxy->timeout.httpka;
227 		td = &defpx->timeout.httpka;
228 		cap = PR_CAP_FE | PR_CAP_BE;
229 	} else if (!strcmp(args[0], "http-request")) {
230 		tv = &proxy->timeout.httpreq;
231 		td = &defpx->timeout.httpreq;
232 		cap = PR_CAP_FE | PR_CAP_BE;
233 	} else if (!strcmp(args[0], "server")) {
234 		name = "server";
235 		tv = &proxy->timeout.server;
236 		td = &defpx->timeout.server;
237 		cap = PR_CAP_BE;
238 	} else if (!strcmp(args[0], "connect")) {
239 		name = "connect";
240 		tv = &proxy->timeout.connect;
241 		td = &defpx->timeout.connect;
242 		cap = PR_CAP_BE;
243 	} else if (!strcmp(args[0], "check")) {
244 		tv = &proxy->timeout.check;
245 		td = &defpx->timeout.check;
246 		cap = PR_CAP_BE;
247 	} else if (!strcmp(args[0], "queue")) {
248 		tv = &proxy->timeout.queue;
249 		td = &defpx->timeout.queue;
250 		cap = PR_CAP_BE;
251 	} else if (!strcmp(args[0], "tunnel")) {
252 		tv = &proxy->timeout.tunnel;
253 		td = &defpx->timeout.tunnel;
254 		cap = PR_CAP_BE;
255 	} else if (!strcmp(args[0], "client-fin")) {
256 		tv = &proxy->timeout.clientfin;
257 		td = &defpx->timeout.clientfin;
258 		cap = PR_CAP_FE;
259 	} else if (!strcmp(args[0], "server-fin")) {
260 		tv = &proxy->timeout.serverfin;
261 		td = &defpx->timeout.serverfin;
262 		cap = PR_CAP_BE;
263 	} else if (!strcmp(args[0], "clitimeout")) {
264 		memprintf(err, "the '%s' directive is not supported anymore since HAProxy 2.1. Use 'timeout client'.", args[0]);
265 		return -1;
266 	} else if (!strcmp(args[0], "srvtimeout")) {
267 		memprintf(err, "the '%s' directive is not supported anymore since HAProxy 2.1. Use 'timeout server'.", args[0]);
268 		return -1;
269 	} else if (!strcmp(args[0], "contimeout")) {
270 		memprintf(err, "the '%s' directive is not supported anymore since HAProxy 2.1. Use 'timeout connect'.", args[0]);
271 		return -1;
272 	} else {
273 		memprintf(err,
274 		          "'timeout' supports 'client', 'server', 'connect', 'check', "
275 		          "'queue', 'http-keep-alive', 'http-request', 'tunnel', 'tarpit', "
276 			  "'client-fin' and 'server-fin' (got '%s')",
277 		          args[0]);
278 		return -1;
279 	}
280 
281 	if (*args[1] == 0) {
282 		memprintf(err, "'timeout %s' expects an integer value (in milliseconds)", name);
283 		return -1;
284 	}
285 
286 	res = parse_time_err(args[1], &timeout, TIME_UNIT_MS);
287 	if (res == PARSE_TIME_OVER) {
288 		memprintf(err, "timer overflow in argument '%s' to 'timeout %s' (maximum value is 2147483647 ms or ~24.8 days)",
289 			  args[1], name);
290 		return -1;
291 	}
292 	else if (res == PARSE_TIME_UNDER) {
293 		memprintf(err, "timer underflow in argument '%s' to 'timeout %s' (minimum non-null value is 1 ms)",
294 			  args[1], name);
295 		return -1;
296 	}
297 	else if (res) {
298 		memprintf(err, "unexpected character '%c' in 'timeout %s'", *res, name);
299 		return -1;
300 	}
301 
302 	if (!(proxy->cap & cap)) {
303 		memprintf(err, "'timeout %s' will be ignored because %s '%s' has no %s capability",
304 		          name, proxy_type_str(proxy), proxy->id,
305 		          (cap & PR_CAP_BE) ? "backend" : "frontend");
306 		retval = 1;
307 	}
308 	else if (defpx && *tv != *td) {
309 		memprintf(err, "overwriting 'timeout %s' which was already specified", name);
310 		retval = 1;
311 	}
312 
313 	if (*args[2] != 0) {
314 		memprintf(err, "'timeout %s' : unexpected extra argument '%s' after value '%s'.", name, args[2], args[1]);
315 		retval = -1;
316 	}
317 
318 	*tv = MS_TO_TICKS(timeout);
319 	return retval;
320 }
321 
322 /* This function parses a "rate-limit" statement in a proxy section. It returns
323  * -1 if there is any error, 1 for a warning, otherwise zero. If it does not
324  * return zero, it will write an error or warning message into a preallocated
325  * buffer returned at <err>. The function must be called with <args> pointing
326  * to the first command line word, with <proxy> pointing to the proxy being
327  * parsed, and <defpx> to the default proxy or NULL.
328  */
proxy_parse_rate_limit(char ** args,int section,struct proxy * proxy,struct proxy * defpx,const char * file,int line,char ** err)329 static int proxy_parse_rate_limit(char **args, int section, struct proxy *proxy,
330                                   struct proxy *defpx, const char *file, int line,
331                                   char **err)
332 {
333 	int retval, cap;
334 	char *res;
335 	unsigned int *tv = NULL;
336 	unsigned int *td = NULL;
337 	unsigned int val;
338 
339 	retval = 0;
340 
341 	if (strcmp(args[1], "sessions") == 0) {
342 		tv = &proxy->fe_sps_lim;
343 		td = &defpx->fe_sps_lim;
344 		cap = PR_CAP_FE;
345 	}
346 	else {
347 		memprintf(err, "'%s' only supports 'sessions' (got '%s')", args[0], args[1]);
348 		return -1;
349 	}
350 
351 	if (*args[2] == 0) {
352 		memprintf(err, "'%s %s' expects expects an integer value (in sessions/second)", args[0], args[1]);
353 		return -1;
354 	}
355 
356 	val = strtoul(args[2], &res, 0);
357 	if (*res) {
358 		memprintf(err, "'%s %s' : unexpected character '%c' in integer value '%s'", args[0], args[1], *res, args[2]);
359 		return -1;
360 	}
361 
362 	if (!(proxy->cap & cap)) {
363 		memprintf(err, "%s %s will be ignored because %s '%s' has no %s capability",
364 			 args[0], args[1], proxy_type_str(proxy), proxy->id,
365 			 (cap & PR_CAP_BE) ? "backend" : "frontend");
366 		retval = 1;
367 	}
368 	else if (defpx && *tv != *td) {
369 		memprintf(err, "overwriting %s %s which was already specified", args[0], args[1]);
370 		retval = 1;
371 	}
372 
373 	*tv = val;
374 	return retval;
375 }
376 
377 /* This function parses a "max-keep-alive-queue" statement in a proxy section.
378  * It returns -1 if there is any error, 1 for a warning, otherwise zero. If it
379  * does not return zero, it will write an error or warning message into a
380  * preallocated buffer returned at <err>. The function must be called with
381  * <args> pointing to the first command line word, with <proxy> pointing to
382  * the proxy being parsed, and <defpx> to the default proxy or NULL.
383  */
proxy_parse_max_ka_queue(char ** args,int section,struct proxy * proxy,struct proxy * defpx,const char * file,int line,char ** err)384 static int proxy_parse_max_ka_queue(char **args, int section, struct proxy *proxy,
385                                     struct proxy *defpx, const char *file, int line,
386                                     char **err)
387 {
388 	int retval;
389 	char *res;
390 	unsigned int val;
391 
392 	retval = 0;
393 
394 	if (*args[1] == 0) {
395 		memprintf(err, "'%s' expects expects an integer value (or -1 to disable)", args[0]);
396 		return -1;
397 	}
398 
399 	val = strtol(args[1], &res, 0);
400 	if (*res) {
401 		memprintf(err, "'%s' : unexpected character '%c' in integer value '%s'", args[0], *res, args[1]);
402 		return -1;
403 	}
404 
405 	if (!(proxy->cap & PR_CAP_BE)) {
406 		memprintf(err, "%s will be ignored because %s '%s' has no backend capability",
407 		          args[0], proxy_type_str(proxy), proxy->id);
408 		retval = 1;
409 	}
410 
411 	/* we store <val+1> so that a user-facing value of -1 is stored as zero (default) */
412 	proxy->max_ka_queue = val + 1;
413 	return retval;
414 }
415 
416 /* This function parses a "declare" statement in a proxy section. It returns -1
417  * if there is any error, 1 for warning, otherwise 0. If it does not return zero,
418  * it will write an error or warning message into a preallocated buffer returned
419  * at <err>. The function must be called with <args> pointing to the first command
420  * line word, with <proxy> pointing to the proxy being parsed, and <defpx> to the
421  * default proxy or NULL.
422  */
proxy_parse_declare(char ** args,int section,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)423 static int proxy_parse_declare(char **args, int section, struct proxy *curpx,
424                                struct proxy *defpx, const char *file, int line,
425                                char **err)
426 {
427 	/* Capture keyword wannot be declared in a default proxy. */
428 	if (curpx == defpx) {
429 		memprintf(err, "'%s' not available in default section", args[0]);
430 		return -1;
431 	}
432 
433 	/* Capture keywork is only available in frontend. */
434 	if (!(curpx->cap & PR_CAP_FE)) {
435 		memprintf(err, "'%s' only available in frontend or listen section", args[0]);
436 		return -1;
437 	}
438 
439 	/* Check mandatory second keyword. */
440 	if (!args[1] || !*args[1]) {
441 		memprintf(err, "'%s' needs a second keyword that specify the type of declaration ('capture')", args[0]);
442 		return -1;
443 	}
444 
445 	/* Actually, declare is only available for declaring capture
446 	 * slot, but in the future it can declare maps or variables.
447 	 * So, this section permits to check and switch according with
448 	 * the second keyword.
449 	 */
450 	if (strcmp(args[1], "capture") == 0) {
451 		char *error = NULL;
452 		long len;
453 		struct cap_hdr *hdr;
454 
455 		/* Check the next keyword. */
456 		if (!args[2] || !*args[2] ||
457 		    (strcmp(args[2], "response") != 0 &&
458 		     strcmp(args[2], "request") != 0)) {
459 			memprintf(err, "'%s %s' requires a direction ('request' or 'response')", args[0], args[1]);
460 			return -1;
461 		}
462 
463 		/* Check the 'len' keyword. */
464 		if (!args[3] || !*args[3] || strcmp(args[3], "len") != 0) {
465 			memprintf(err, "'%s %s' requires a capture length ('len')", args[0], args[1]);
466 			return -1;
467 		}
468 
469 		/* Check the length value. */
470 		if (!args[4] || !*args[4]) {
471 			memprintf(err, "'%s %s': 'len' requires a numeric value that represents the "
472 			               "capture length",
473 			          args[0], args[1]);
474 			return -1;
475 		}
476 
477 		/* convert the length value. */
478 		len = strtol(args[4], &error, 10);
479 		if (*error != '\0') {
480 			memprintf(err, "'%s %s': cannot parse the length '%s'.",
481 			          args[0], args[1], args[3]);
482 			return -1;
483 		}
484 
485 		/* check length. */
486 		if (len <= 0) {
487 			memprintf(err, "length must be > 0");
488 			return -1;
489 		}
490 
491 		/* register the capture. */
492 		hdr = calloc(1, sizeof(*hdr));
493 		hdr->name = NULL; /* not a header capture */
494 		hdr->namelen = 0;
495 		hdr->len = len;
496 		hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
497 
498 		if (strcmp(args[2], "request") == 0) {
499 			hdr->next = curpx->req_cap;
500 			hdr->index = curpx->nb_req_cap++;
501 			curpx->req_cap = hdr;
502 		}
503 		if (strcmp(args[2], "response") == 0) {
504 			hdr->next = curpx->rsp_cap;
505 			hdr->index = curpx->nb_rsp_cap++;
506 			curpx->rsp_cap = hdr;
507 		}
508 		return 0;
509 	}
510 	else {
511 		memprintf(err, "unknown declaration type '%s' (supports 'capture')", args[1]);
512 		return -1;
513 	}
514 }
515 
516 /* This function parses a "retry-on" statement */
517 static int
proxy_parse_retry_on(char ** args,int section,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)518 proxy_parse_retry_on(char **args, int section, struct proxy *curpx,
519                                struct proxy *defpx, const char *file, int line,
520                                char **err)
521 {
522 	int i;
523 
524 	if (!(*args[1])) {
525 		memprintf(err, "'%s' needs at least one keyword to specify when to retry", args[0]);
526 		return -1;
527 	}
528 	if (!(curpx->cap & PR_CAP_BE)) {
529 		memprintf(err, "'%s' only available in backend or listen section", args[0]);
530 		return -1;
531 	}
532 	curpx->retry_type = 0;
533 	for (i = 1; *(args[i]); i++) {
534 		if (!strcmp(args[i], "conn-failure"))
535 			curpx->retry_type |= PR_RE_CONN_FAILED;
536 		else if (!strcmp(args[i], "empty-response"))
537 			curpx->retry_type |= PR_RE_DISCONNECTED;
538 		else if (!strcmp(args[i], "response-timeout"))
539 			curpx->retry_type |= PR_RE_TIMEOUT;
540 		else if (!strcmp(args[i], "404"))
541 			curpx->retry_type |= PR_RE_404;
542 		else if (!strcmp(args[i], "408"))
543 			curpx->retry_type |= PR_RE_408;
544 		else if (!strcmp(args[i], "425"))
545 			curpx->retry_type |= PR_RE_425;
546 		else if (!strcmp(args[i], "500"))
547 			curpx->retry_type |= PR_RE_500;
548 		else if (!strcmp(args[i], "501"))
549 			curpx->retry_type |= PR_RE_501;
550 		else if (!strcmp(args[i], "502"))
551 			curpx->retry_type |= PR_RE_502;
552 		else if (!strcmp(args[i], "503"))
553 			curpx->retry_type |= PR_RE_503;
554 		else if (!strcmp(args[i], "504"))
555 			curpx->retry_type |= PR_RE_504;
556 		else if (!strcmp(args[i], "0rtt-rejected"))
557 			curpx->retry_type |= PR_RE_EARLY_ERROR;
558 		else if (!strcmp(args[i], "junk-response"))
559 			curpx->retry_type |= PR_RE_JUNK_REQUEST;
560 		else if (!(strcmp(args[i], "all-retryable-errors")))
561 			curpx->retry_type |= PR_RE_CONN_FAILED | PR_RE_DISCONNECTED |
562 			                     PR_RE_TIMEOUT | PR_RE_500 | PR_RE_502 |
563 					     PR_RE_503 | PR_RE_504 | PR_RE_EARLY_ERROR |
564 					     PR_RE_JUNK_REQUEST;
565 		else if (!strcmp(args[i], "none")) {
566 			if (i != 1 || *args[i + 1]) {
567 				memprintf(err, "'%s' 'none' keyworld only usable alone", args[0]);
568 				return -1;
569 			}
570 		} else {
571 			memprintf(err, "'%s': unknown keyword '%s'", args[0], args[i]);
572 			return -1;
573 		}
574 
575 	}
576 
577 
578 	return 0;
579 }
580 
581 /* This function inserts proxy <px> into the tree of known proxies. The proxy's
582  * name is used as the storing key so it must already have been initialized.
583  */
proxy_store_name(struct proxy * px)584 void proxy_store_name(struct proxy *px)
585 {
586 	px->conf.by_name.key = px->id;
587 	ebis_insert(&proxy_by_name, &px->conf.by_name);
588 }
589 
590 /* Returns a pointer to the first proxy matching capabilities <cap> and id
591  * <id>. NULL is returned if no match is found. If <table> is non-zero, it
592  * only considers proxies having a table.
593  */
proxy_find_by_id(int id,int cap,int table)594 struct proxy *proxy_find_by_id(int id, int cap, int table)
595 {
596 	struct eb32_node *n;
597 
598 	for (n = eb32_lookup(&used_proxy_id, id); n; n = eb32_next(n)) {
599 		struct proxy *px = container_of(n, struct proxy, conf.id);
600 
601 		if (px->uuid != id)
602 			break;
603 
604 		if ((px->cap & cap) != cap)
605 			continue;
606 
607 		if (table && (!px->table || !px->table->size))
608 			continue;
609 
610 		return px;
611 	}
612 	return NULL;
613 }
614 
615 /* Returns a pointer to the first proxy matching either name <name>, or id
616  * <name> if <name> begins with a '#'. NULL is returned if no match is found.
617  * If <table> is non-zero, it only considers proxies having a table.
618  */
proxy_find_by_name(const char * name,int cap,int table)619 struct proxy *proxy_find_by_name(const char *name, int cap, int table)
620 {
621 	struct proxy *curproxy;
622 
623 	if (*name == '#') {
624 		curproxy = proxy_find_by_id(atoi(name + 1), cap, table);
625 		if (curproxy)
626 			return curproxy;
627 	}
628 	else {
629 		struct ebpt_node *node;
630 
631 		for (node = ebis_lookup(&proxy_by_name, name); node; node = ebpt_next(node)) {
632 			curproxy = container_of(node, struct proxy, conf.by_name);
633 
634 			if (strcmp(curproxy->id, name) != 0)
635 				break;
636 
637 			if ((curproxy->cap & cap) != cap)
638 				continue;
639 
640 			if (table && (!curproxy->table || !curproxy->table->size))
641 				continue;
642 
643 			return curproxy;
644 		}
645 	}
646 	return NULL;
647 }
648 
649 /* Finds the best match for a proxy with capabilities <cap>, name <name> and id
650  * <id>. At most one of <id> or <name> may be different provided that <cap> is
651  * valid. Either <id> or <name> may be left unspecified (0). The purpose is to
652  * find a proxy based on some information from a previous configuration, across
653  * reloads or during information exchange between peers.
654  *
655  * Names are looked up first if present, then IDs are compared if present. In
656  * case of an inexact match whatever is forced in the configuration has
657  * precedence in the following order :
658  *   - 1) forced ID (proves a renaming / change of proxy type)
659  *   - 2) proxy name+type (may indicate a move if ID differs)
660  *   - 3) automatic ID+type (may indicate a renaming)
661  *
662  * Depending on what is found, we can end up in the following situations :
663  *
664  *   name id cap  | possible causes
665  *   -------------+-----------------
666  *    --  --  --  | nothing found
667  *    --  --  ok  | nothing found
668  *    --  ok  --  | proxy deleted, ID points to next one
669  *    --  ok  ok  | proxy renamed, or deleted with ID pointing to next one
670  *    ok  --  --  | proxy deleted, but other half with same name still here (before)
671  *    ok  --  ok  | proxy's ID changed (proxy moved in the config file)
672  *    ok  ok  --  | proxy deleted, but other half with same name still here (after)
673  *    ok  ok  ok  | perfect match
674  *
675  * Upon return if <diff> is not NULL, it is zeroed then filled with up to 3 bits :
676  *   - PR_FBM_MISMATCH_ID        : proxy was found but ID differs
677  *                                 (and ID was not zero)
678  *   - PR_FBM_MISMATCH_NAME      : proxy was found by ID but name differs
679  *                                 (and name was not NULL)
680  *   - PR_FBM_MISMATCH_PROXYTYPE : a proxy of different type was found with
681  *                                 the same name and/or id
682  *
683  * Only a valid proxy is returned. If capabilities do not match, NULL is
684  * returned. The caller can check <diff> to report detailed warnings / errors,
685  * and decide whether or not to use what was found.
686  */
proxy_find_best_match(int cap,const char * name,int id,int * diff)687 struct proxy *proxy_find_best_match(int cap, const char *name, int id, int *diff)
688 {
689 	struct proxy *byname;
690 	struct proxy *byid;
691 
692 	if (!name && !id)
693 		return NULL;
694 
695 	if (diff)
696 		*diff = 0;
697 
698 	byname = byid = NULL;
699 
700 	if (name) {
701 		byname = proxy_find_by_name(name, cap, 0);
702 		if (byname && (!id || byname->uuid == id))
703 			return byname;
704 	}
705 
706 	/* remaining possibilities :
707 	 *   - name not set
708 	 *   - name set but not found
709 	 *   - name found, but ID doesn't match.
710 	 */
711 	if (id) {
712 		byid = proxy_find_by_id(id, cap, 0);
713 		if (byid) {
714 			if (byname) {
715 				/* id+type found, name+type found, but not all 3.
716 				 * ID wins only if forced, otherwise name wins.
717 				 */
718 				if (byid->options & PR_O_FORCED_ID) {
719 					if (diff)
720 						*diff |= PR_FBM_MISMATCH_NAME;
721 					return byid;
722 				}
723 				else {
724 					if (diff)
725 						*diff |= PR_FBM_MISMATCH_ID;
726 					return byname;
727 				}
728 			}
729 
730 			/* remaining possibilities :
731 			 *   - name not set
732 			 *   - name set but not found
733 			 */
734 			if (name && diff)
735 				*diff |= PR_FBM_MISMATCH_NAME;
736 			return byid;
737 		}
738 
739 		/* ID not found */
740 		if (byname) {
741 			if (diff)
742 				*diff |= PR_FBM_MISMATCH_ID;
743 			return byname;
744 		}
745 	}
746 
747 	/* All remaining possibilities will lead to NULL. If we can report more
748 	 * detailed information to the caller about changed types and/or name,
749 	 * we'll do it. For example, we could detect that "listen foo" was
750 	 * split into "frontend foo_ft" and "backend foo_bk" if IDs are forced.
751 	 *   - name not set, ID not found
752 	 *   - name not found, ID not set
753 	 *   - name not found, ID not found
754 	 */
755 	if (!diff)
756 		return NULL;
757 
758 	if (name) {
759 		byname = proxy_find_by_name(name, 0, 0);
760 		if (byname && (!id || byname->uuid == id))
761 			*diff |= PR_FBM_MISMATCH_PROXYTYPE;
762 	}
763 
764 	if (id) {
765 		byid = proxy_find_by_id(id, 0, 0);
766 		if (byid) {
767 			if (!name)
768 				*diff |= PR_FBM_MISMATCH_PROXYTYPE; /* only type changed */
769 			else if (byid->options & PR_O_FORCED_ID)
770 				*diff |= PR_FBM_MISMATCH_NAME | PR_FBM_MISMATCH_PROXYTYPE; /* name and type changed */
771 			/* otherwise it's a different proxy that was returned */
772 		}
773 	}
774 	return NULL;
775 }
776 
777 /*
778  * This function finds a server with matching name within selected proxy.
779  * It also checks if there are more matching servers with
780  * requested name as this often leads into unexpected situations.
781  */
782 
findserver(const struct proxy * px,const char * name)783 struct server *findserver(const struct proxy *px, const char *name) {
784 
785 	struct server *cursrv, *target = NULL;
786 
787 	if (!px)
788 		return NULL;
789 
790 	for (cursrv = px->srv; cursrv; cursrv = cursrv->next) {
791 		if (strcmp(cursrv->id, name))
792 			continue;
793 
794 		if (!target) {
795 			target = cursrv;
796 			continue;
797 		}
798 
799 		ha_alert("Refusing to use duplicated server '%s' found in proxy: %s!\n",
800 			 name, px->id);
801 
802 		return NULL;
803 	}
804 
805 	return target;
806 }
807 
808 /* This function checks that the designated proxy has no http directives
809  * enabled. It will output a warning if there are, and will fix some of them.
810  * It returns the number of fatal errors encountered. This should be called
811  * at the end of the configuration parsing if the proxy is not in http mode.
812  * The <file> argument is used to construct the error message.
813  */
proxy_cfg_ensure_no_http(struct proxy * curproxy)814 int proxy_cfg_ensure_no_http(struct proxy *curproxy)
815 {
816 	if (curproxy->cookie_name != NULL) {
817 		ha_warning("config : cookie will be ignored for %s '%s' (needs 'mode http').\n",
818 			   proxy_type_str(curproxy), curproxy->id);
819 	}
820 	if (curproxy->monitor_uri != NULL) {
821 		ha_warning("config : monitor-uri will be ignored for %s '%s' (needs 'mode http').\n",
822 			   proxy_type_str(curproxy), curproxy->id);
823 	}
824 	if (curproxy->lbprm.algo & BE_LB_NEED_HTTP) {
825 		curproxy->lbprm.algo &= ~BE_LB_ALGO;
826 		curproxy->lbprm.algo |= BE_LB_ALGO_RR;
827 		ha_warning("config : Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n",
828 			   proxy_type_str(curproxy), curproxy->id);
829 	}
830 	if (curproxy->to_log & (LW_REQ | LW_RESP)) {
831 		curproxy->to_log &= ~(LW_REQ | LW_RESP);
832 		ha_warning("parsing [%s:%d] : HTTP log/header format not usable with %s '%s' (needs 'mode http').\n",
833 			   curproxy->conf.lfs_file, curproxy->conf.lfs_line,
834 			   proxy_type_str(curproxy), curproxy->id);
835 	}
836 	if (curproxy->conf.logformat_string == default_http_log_format ||
837 	    curproxy->conf.logformat_string == clf_http_log_format) {
838 		/* Note: we don't change the directive's file:line number */
839 		curproxy->conf.logformat_string = default_tcp_log_format;
840 		ha_warning("parsing [%s:%d] : 'option httplog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n",
841 			   curproxy->conf.lfs_file, curproxy->conf.lfs_line,
842 			   proxy_type_str(curproxy), curproxy->id);
843 	}
844 
845 	return 0;
846 }
847 
848 /* Perform the most basic initialization of a proxy :
849  * memset(), list_init(*), reset_timeouts(*).
850  * Any new proxy or peer should be initialized via this function.
851  */
init_new_proxy(struct proxy * p)852 void init_new_proxy(struct proxy *p)
853 {
854 	memset(p, 0, sizeof(struct proxy));
855 	p->obj_type = OBJ_TYPE_PROXY;
856 	p->pendconns = EB_ROOT;
857 	LIST_INIT(&p->acl);
858 	LIST_INIT(&p->http_req_rules);
859 	LIST_INIT(&p->http_res_rules);
860 	LIST_INIT(&p->redirect_rules);
861 	LIST_INIT(&p->mon_fail_cond);
862 	LIST_INIT(&p->switching_rules);
863 	LIST_INIT(&p->server_rules);
864 	LIST_INIT(&p->persist_rules);
865 	LIST_INIT(&p->sticking_rules);
866 	LIST_INIT(&p->storersp_rules);
867 	LIST_INIT(&p->tcp_req.inspect_rules);
868 	LIST_INIT(&p->tcp_rep.inspect_rules);
869 	LIST_INIT(&p->tcp_req.l4_rules);
870 	LIST_INIT(&p->tcp_req.l5_rules);
871 	MT_LIST_INIT(&p->listener_queue);
872 	LIST_INIT(&p->logsrvs);
873 	LIST_INIT(&p->logformat);
874 	LIST_INIT(&p->logformat_sd);
875 	LIST_INIT(&p->format_unique_id);
876 	LIST_INIT(&p->conf.bind);
877 	LIST_INIT(&p->conf.listeners);
878 	LIST_INIT(&p->conf.args.list);
879 	LIST_INIT(&p->tcpcheck_rules);
880 	LIST_INIT(&p->filter_configs);
881 
882 	/* Timeouts are defined as -1 */
883 	proxy_reset_timeouts(p);
884 	p->tcp_rep.inspect_delay = TICK_ETERNITY;
885 
886 	/* initial uuid is unassigned (-1) */
887 	p->uuid = -1;
888 
889 	/* Default to only allow L4 retries */
890 	p->retry_type = PR_RE_CONN_FAILED;
891 
892 	HA_SPIN_INIT(&p->lock);
893 }
894 
895 /*
896  * This function creates all proxy sockets. It should be done very early,
897  * typically before privileges are dropped. The sockets will be registered
898  * but not added to any fd_set, in order not to loose them across the fork().
899  * The proxies also start in READY state because they all have their listeners
900  * bound.
901  *
902  * Its return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
903  * Retryable errors will only be printed if <verbose> is not zero.
904  */
start_proxies(int verbose)905 int start_proxies(int verbose)
906 {
907 	struct proxy *curproxy;
908 	struct listener *listener;
909 	int lerr, err = ERR_NONE;
910 	int pxerr;
911 	char msg[100];
912 
913 	for (curproxy = proxies_list; curproxy != NULL; curproxy = curproxy->next) {
914 		if (curproxy->state != PR_STNEW)
915 			continue; /* already initialized */
916 
917 		pxerr = 0;
918 		list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
919 			if (listener->state != LI_ASSIGNED)
920 				continue; /* already started */
921 
922 			lerr = listener->proto->bind(listener, msg, sizeof(msg));
923 
924 			/* errors are reported if <verbose> is set or if they are fatal */
925 			if (verbose || (lerr & (ERR_FATAL | ERR_ABORT))) {
926 				if (lerr & ERR_ALERT)
927 					ha_alert("Starting %s %s: %s\n",
928 						 proxy_type_str(curproxy), curproxy->id, msg);
929 				else if (lerr & ERR_WARN)
930 					ha_warning("Starting %s %s: %s\n",
931 						   proxy_type_str(curproxy), curproxy->id, msg);
932 			}
933 
934 			err |= lerr;
935 			if (lerr & (ERR_ABORT | ERR_FATAL)) {
936 				pxerr |= 1;
937 				break;
938 			}
939 			else if (lerr & ERR_CODE) {
940 				pxerr |= 1;
941 				continue;
942 			}
943 		}
944 
945 		if (!pxerr) {
946 			curproxy->state = PR_STREADY;
947 			send_log(curproxy, LOG_NOTICE, "Proxy %s started.\n", curproxy->id);
948 		}
949 
950 		if (err & ERR_ABORT)
951 			break;
952 	}
953 
954 	return err;
955 }
956 
957 
958 /*
959  * This is the proxy management task. It enables proxies when there are enough
960  * free streams, or stops them when the table is full. It is designed to be
961  * called as a task which is woken up upon stopping or when rate limiting must
962  * be enforced.
963  */
manage_proxy(struct task * t,void * context,unsigned short state)964 struct task *manage_proxy(struct task *t, void *context, unsigned short state)
965 {
966 	struct proxy *p = context;
967 	int next = TICK_ETERNITY;
968 	unsigned int wait;
969 
970 	/* We should periodically try to enable listeners waiting for a
971 	 * global resource here.
972 	 */
973 
974 	/* first, let's check if we need to stop the proxy */
975 	if (unlikely(stopping && p->state != PR_STSTOPPED)) {
976 		int t;
977 		t = tick_remain(now_ms, p->stop_time);
978 		if (t == 0) {
979 			ha_warning("Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
980 				   p->id, p->fe_counters.cum_conn, p->be_counters.cum_conn);
981 			send_log(p, LOG_WARNING, "Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
982 				 p->id, p->fe_counters.cum_conn, p->be_counters.cum_conn);
983 			stop_proxy(p);
984 			/* try to free more memory */
985 			pool_gc(NULL);
986 		}
987 		else {
988 			next = tick_first(next, p->stop_time);
989 		}
990 	}
991 
992 	/* If the proxy holds a stick table, we need to purge all unused
993 	 * entries. These are all the ones in the table with ref_cnt == 0
994 	 * and all the ones in the pool used to allocate new entries. Any
995 	 * entry attached to an existing stream waiting for a store will
996 	 * be in neither list. Any entry being dumped will have ref_cnt > 0.
997 	 * However we protect tables that are being synced to peers.
998 	 */
999 	if (unlikely(stopping && p->state == PR_STSTOPPED && p->table && p->table->current)) {
1000 		if (!p->table->syncing) {
1001 			stktable_trash_oldest(p->table, p->table->current);
1002 			pool_gc(NULL);
1003 		}
1004 		if (p->table->current) {
1005 			/* some entries still remain, let's recheck in one second */
1006 			next = tick_first(next, tick_add(now_ms, 1000));
1007 		}
1008 	}
1009 
1010 	/* the rest below is just for frontends */
1011 	if (!(p->cap & PR_CAP_FE))
1012 		goto out;
1013 
1014 	/* check the various reasons we may find to block the frontend */
1015 	if (unlikely(p->feconn >= p->maxconn)) {
1016 		if (p->state == PR_STREADY)
1017 			p->state = PR_STFULL;
1018 		goto out;
1019 	}
1020 
1021 	/* OK we have no reason to block, so let's unblock if we were blocking */
1022 	if (p->state == PR_STFULL)
1023 		p->state = PR_STREADY;
1024 
1025 	if (p->fe_sps_lim &&
1026 	    (wait = next_event_delay(&p->fe_sess_per_sec, p->fe_sps_lim, 0))) {
1027 		/* we're blocking because a limit was reached on the number of
1028 		 * requests/s on the frontend. We want to re-check ASAP, which
1029 		 * means in 1 ms before estimated expiration date, because the
1030 		 * timer will have settled down.
1031 		 */
1032 		next = tick_first(next, tick_add(now_ms, wait));
1033 		goto out;
1034 	}
1035 
1036 	/* The proxy is not limited so we can re-enable any waiting listener */
1037 	if (!MT_LIST_ISEMPTY(&p->listener_queue))
1038 		dequeue_all_listeners(&p->listener_queue);
1039  out:
1040 	t->expire = next;
1041 	task_queue(t);
1042 	return t;
1043 }
1044 
1045 
proxy_parse_hard_stop_after(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)1046 static int proxy_parse_hard_stop_after(char **args, int section_type, struct proxy *curpx,
1047                                 struct proxy *defpx, const char *file, int line,
1048                                 char **err)
1049 {
1050 	const char *res;
1051 
1052 	if (!*args[1]) {
1053 		memprintf(err, "'%s' expects <time> as argument.\n", args[0]);
1054 		return -1;
1055 	}
1056 	res = parse_time_err(args[1], &global.hard_stop_after, TIME_UNIT_MS);
1057 	if (res == PARSE_TIME_OVER) {
1058 		memprintf(err, "timer overflow in argument '%s' to '%s' (maximum value is 2147483647 ms or ~24.8 days)",
1059 			  args[1], args[0]);
1060 		return -1;
1061 	}
1062 	else if (res == PARSE_TIME_UNDER) {
1063 		memprintf(err, "timer underflow in argument '%s' to '%s' (minimum non-null value is 1 ms)",
1064 			  args[1], args[0]);
1065 		return -1;
1066 	}
1067 	else if (res) {
1068 		memprintf(err, "unexpected character '%c' in argument to <%s>.\n", *res, args[0]);
1069 		return -1;
1070 	}
1071 	return 0;
1072 }
1073 
hard_stop(struct task * t,void * context,unsigned short state)1074 struct task *hard_stop(struct task *t, void *context, unsigned short state)
1075 {
1076 	struct proxy *p;
1077 	struct stream *s;
1078 	int thr;
1079 
1080 	if (killed) {
1081 		ha_warning("Some tasks resisted to hard-stop, exiting now.\n");
1082 		send_log(NULL, LOG_WARNING, "Some tasks resisted to hard-stop, exiting now.\n");
1083 		killed = 2;
1084 		for (thr = 0; thr < global.nbthread; thr++)
1085 			if (((all_threads_mask & ~tid_bit) >> thr) & 1)
1086 				wake_thread(thr);
1087 		t->expire = TICK_ETERNITY;
1088 		return t;
1089 	}
1090 
1091 	ha_warning("soft-stop running for too long, performing a hard-stop.\n");
1092 	send_log(NULL, LOG_WARNING, "soft-stop running for too long, performing a hard-stop.\n");
1093 	p = proxies_list;
1094 	while (p) {
1095 		if ((p->cap & PR_CAP_FE) && (p->feconn > 0)) {
1096 			ha_warning("Proxy %s hard-stopped (%d remaining conns will be closed).\n",
1097 				   p->id, p->feconn);
1098 			send_log(p, LOG_WARNING, "Proxy %s hard-stopped (%d remaining conns will be closed).\n",
1099 				p->id, p->feconn);
1100 		}
1101 		p = p->next;
1102 	}
1103 
1104 	thread_isolate();
1105 	list_for_each_entry(s, &streams, list) {
1106 		stream_shutdown(s, SF_ERR_KILLED);
1107 	}
1108 	thread_release();
1109 
1110 	killed = 1;
1111 	t->expire = tick_add(now_ms, MS_TO_TICKS(1000));
1112 	return t;
1113 }
1114 
1115 /*
1116  * this function disables health-check servers so that the process will quickly be ignored
1117  * by load balancers. Note that if a proxy was already in the PAUSED state, then its grace
1118  * time will not be used since it would already not listen anymore to the socket.
1119  */
soft_stop(void)1120 void soft_stop(void)
1121 {
1122 	struct proxy *p;
1123 	struct peers *prs;
1124 	struct task *task;
1125 
1126 	stopping = 1;
1127 	/* disable busy polling to avoid cpu eating for the new process */
1128 	global.tune.options &= ~GTUNE_BUSY_POLLING;
1129 	if (tick_isset(global.hard_stop_after)) {
1130 		task = task_new(MAX_THREADS_MASK);
1131 		if (task) {
1132 			task->process = hard_stop;
1133 			task_schedule(task, tick_add(now_ms, global.hard_stop_after));
1134 		}
1135 		else {
1136 			ha_alert("out of memory trying to allocate the hard-stop task.\n");
1137 		}
1138 	}
1139 	p = proxies_list;
1140 	tv_update_date(0,1); /* else, the old time before select will be used */
1141 	while (p) {
1142 		/* Zombie proxy, let's close the file descriptors */
1143 		if (p->state == PR_STSTOPPED &&
1144 		    !LIST_ISEMPTY(&p->conf.listeners) &&
1145 		    LIST_ELEM(p->conf.listeners.n,
1146 		    struct listener *, by_fe)->state > LI_ASSIGNED) {
1147 			struct listener *l;
1148 			list_for_each_entry(l, &p->conf.listeners, by_fe) {
1149 				if (l->state > LI_ASSIGNED)
1150 					close(l->fd);
1151 				l->state = LI_INIT;
1152 			}
1153 		}
1154 
1155 		if (p->state != PR_STSTOPPED) {
1156 			ha_warning("Stopping %s %s in %d ms.\n", proxy_cap_str(p->cap), p->id, p->grace);
1157 			send_log(p, LOG_WARNING, "Stopping %s %s in %d ms.\n", proxy_cap_str(p->cap), p->id, p->grace);
1158 			p->stop_time = tick_add(now_ms, p->grace);
1159 
1160 			/* Note: do not wake up stopped proxies' task nor their tables'
1161 			 * tasks as these ones might point to already released entries.
1162 			 */
1163 			if (p->table && p->table->size && p->table->sync_task)
1164 				task_wakeup(p->table->sync_task, TASK_WOKEN_MSG);
1165 
1166 			if (p->task)
1167 				task_wakeup(p->task, TASK_WOKEN_MSG);
1168 		}
1169 		p = p->next;
1170 	}
1171 
1172 	prs = cfg_peers;
1173 	while (prs) {
1174 		if (prs->peers_fe)
1175 			stop_proxy(prs->peers_fe);
1176 		prs = prs->next;
1177 	}
1178 	/* signal zero is used to broadcast the "stopping" event */
1179 	signal_handler(0);
1180 }
1181 
1182 
1183 /* Temporarily disables listening on all of the proxy's listeners. Upon
1184  * success, the proxy enters the PR_PAUSED state. If disabling at least one
1185  * listener returns an error, then the proxy state is set to PR_STERROR
1186  * because we don't know how to resume from this. The function returns 0
1187  * if it fails, or non-zero on success.
1188  */
pause_proxy(struct proxy * p)1189 int pause_proxy(struct proxy *p)
1190 {
1191 	struct listener *l;
1192 
1193 	if (!(p->cap & PR_CAP_FE) || p->state == PR_STERROR ||
1194 	    p->state == PR_STSTOPPED || p->state == PR_STPAUSED)
1195 		return 1;
1196 
1197 	ha_warning("Pausing %s %s.\n", proxy_cap_str(p->cap), p->id);
1198 	send_log(p, LOG_WARNING, "Pausing %s %s.\n", proxy_cap_str(p->cap), p->id);
1199 
1200 	list_for_each_entry(l, &p->conf.listeners, by_fe) {
1201 		if (!pause_listener(l))
1202 			p->state = PR_STERROR;
1203 	}
1204 
1205 	if (p->state == PR_STERROR) {
1206 		ha_warning("%s %s failed to enter pause mode.\n", proxy_cap_str(p->cap), p->id);
1207 		send_log(p, LOG_WARNING, "%s %s failed to enter pause mode.\n", proxy_cap_str(p->cap), p->id);
1208 		return 0;
1209 	}
1210 
1211 	p->state = PR_STPAUSED;
1212 	return 1;
1213 }
1214 
1215 /* This function makes the proxy unusable, but keeps the listening sockets
1216  * opened, so that if any process requests them, we are able to serve them.
1217  * This should only be called early, before we started accepting requests.
1218  */
zombify_proxy(struct proxy * p)1219 void zombify_proxy(struct proxy *p)
1220 {
1221 	struct listener *l;
1222 	struct listener *first_to_listen = NULL;
1223 
1224 	list_for_each_entry(l, &p->conf.listeners, by_fe) {
1225 		enum li_state oldstate = l->state;
1226 
1227 		unbind_listener_no_close(l);
1228 		if (l->state >= LI_ASSIGNED) {
1229 			delete_listener(l);
1230 		}
1231 		/*
1232 		 * Pretend we're still up and running so that the fd
1233 		 * will be sent if asked.
1234 		 */
1235 		l->state = LI_ZOMBIE;
1236 		if (!first_to_listen && oldstate >= LI_LISTEN)
1237 			first_to_listen = l;
1238 	}
1239 	/* Quick hack : at stop time, to know we have to close the sockets
1240 	 * despite the proxy being marked as stopped, make the first listener
1241 	 * of the listener list an active one, so that we don't have to
1242 	 * parse the whole list to be sure.
1243 	 */
1244 	if (first_to_listen && LIST_ELEM(p->conf.listeners.n,
1245 	    struct listener *, by_fe) != first_to_listen) {
1246 		LIST_DEL(&l->by_fe);
1247 		LIST_ADD(&p->conf.listeners, &l->by_fe);
1248 	}
1249 
1250 	p->state = PR_STSTOPPED;
1251 }
1252 
1253 /*
1254  * This function completely stops a proxy and releases its listeners. It has
1255  * to be called when going down in order to release the ports so that another
1256  * process may bind to them. It must also be called on disabled proxies at the
1257  * end of start-up. If all listeners are closed, the proxy is set to the
1258  * PR_STSTOPPED state. The function takes the proxy's lock so it's safe to
1259  * call from multiple places.
1260  */
stop_proxy(struct proxy * p)1261 void stop_proxy(struct proxy *p)
1262 {
1263 	struct listener *l;
1264 	int nostop = 0;
1265 
1266 	HA_SPIN_LOCK(PROXY_LOCK, &p->lock);
1267 
1268 	list_for_each_entry(l, &p->conf.listeners, by_fe) {
1269 		if (l->options & LI_O_NOSTOP) {
1270 			HA_ATOMIC_ADD(&unstoppable_jobs, 1);
1271 			nostop = 1;
1272 			continue;
1273 		}
1274 		/* The master should not close an inherited FD */
1275 		if (master && (l->options & LI_O_INHERITED))
1276 			unbind_listener_no_close(l);
1277 		else
1278 			unbind_listener(l);
1279 		if (l->state >= LI_ASSIGNED) {
1280 			delete_listener(l);
1281 		}
1282 	}
1283 	if (!nostop)
1284 		p->state = PR_STSTOPPED;
1285 
1286 	HA_SPIN_UNLOCK(PROXY_LOCK, &p->lock);
1287 }
1288 
1289 /* This function resumes listening on the specified proxy. It scans all of its
1290  * listeners and tries to enable them all. If any of them fails, the proxy is
1291  * put back to the paused state. It returns 1 upon success, or zero if an error
1292  * is encountered.
1293  */
resume_proxy(struct proxy * p)1294 int resume_proxy(struct proxy *p)
1295 {
1296 	struct listener *l;
1297 	int fail;
1298 
1299 	if (p->state != PR_STPAUSED)
1300 		return 1;
1301 
1302 	ha_warning("Enabling %s %s.\n", proxy_cap_str(p->cap), p->id);
1303 	send_log(p, LOG_WARNING, "Enabling %s %s.\n", proxy_cap_str(p->cap), p->id);
1304 
1305 	fail = 0;
1306 	list_for_each_entry(l, &p->conf.listeners, by_fe) {
1307 		if (!resume_listener(l)) {
1308 			int port;
1309 
1310 			port = get_host_port(&l->addr);
1311 			if (port) {
1312 				ha_warning("Port %d busy while trying to enable %s %s.\n",
1313 					   port, proxy_cap_str(p->cap), p->id);
1314 				send_log(p, LOG_WARNING, "Port %d busy while trying to enable %s %s.\n",
1315 					 port, proxy_cap_str(p->cap), p->id);
1316 			}
1317 			else {
1318 				ha_warning("Bind on socket %d busy while trying to enable %s %s.\n",
1319 					   l->luid, proxy_cap_str(p->cap), p->id);
1320 				send_log(p, LOG_WARNING, "Bind on socket %d busy while trying to enable %s %s.\n",
1321 					 l->luid, proxy_cap_str(p->cap), p->id);
1322 			}
1323 
1324 			/* Another port might have been enabled. Let's stop everything. */
1325 			fail = 1;
1326 			break;
1327 		}
1328 	}
1329 
1330 	p->state = PR_STREADY;
1331 	if (fail) {
1332 		pause_proxy(p);
1333 		return 0;
1334 	}
1335 	return 1;
1336 }
1337 
1338 /*
1339  * This function temporarily disables listening so that another new instance
1340  * can start listening. It is designed to be called upon reception of a
1341  * SIGTTOU, after which either a SIGUSR1 can be sent to completely stop
1342  * the proxy, or a SIGTTIN can be sent to listen again.
1343  */
pause_proxies(void)1344 void pause_proxies(void)
1345 {
1346 	int err;
1347 	struct proxy *p;
1348 	struct peers *prs;
1349 
1350 	err = 0;
1351 	p = proxies_list;
1352 	tv_update_date(0,1); /* else, the old time before select will be used */
1353 	while (p) {
1354 		err |= !pause_proxy(p);
1355 		p = p->next;
1356 	}
1357 
1358 	prs = cfg_peers;
1359 	while (prs) {
1360 		if (prs->peers_fe)
1361 			err |= !pause_proxy(prs->peers_fe);
1362 		prs = prs->next;
1363         }
1364 
1365 	if (err) {
1366 		ha_warning("Some proxies refused to pause, performing soft stop now.\n");
1367 		send_log(p, LOG_WARNING, "Some proxies refused to pause, performing soft stop now.\n");
1368 		soft_stop();
1369 	}
1370 }
1371 
1372 
1373 /*
1374  * This function reactivates listening. This can be used after a call to
1375  * sig_pause(), for example when a new instance has failed starting up.
1376  * It is designed to be called upon reception of a SIGTTIN.
1377  */
resume_proxies(void)1378 void resume_proxies(void)
1379 {
1380 	int err;
1381 	struct proxy *p;
1382 	struct peers *prs;
1383 
1384 	err = 0;
1385 	p = proxies_list;
1386 	tv_update_date(0,1); /* else, the old time before select will be used */
1387 	while (p) {
1388 		err |= !resume_proxy(p);
1389 		p = p->next;
1390 	}
1391 
1392 	prs = cfg_peers;
1393 	while (prs) {
1394 		if (prs->peers_fe)
1395 			err |= !resume_proxy(prs->peers_fe);
1396 		prs = prs->next;
1397         }
1398 
1399 	if (err) {
1400 		ha_warning("Some proxies refused to resume, a restart is probably needed to resume safe operations.\n");
1401 		send_log(p, LOG_WARNING, "Some proxies refused to resume, a restart is probably needed to resume safe operations.\n");
1402 	}
1403 }
1404 
1405 /* Set current stream's backend to <be>. Nothing is done if the
1406  * stream already had a backend assigned, which is indicated by
1407  * s->flags & SF_BE_ASSIGNED.
1408  * All flags, stats and counters which need be updated are updated.
1409  * Returns 1 if done, 0 in case of internal error, eg: lack of resource.
1410  */
stream_set_backend(struct stream * s,struct proxy * be)1411 int stream_set_backend(struct stream *s, struct proxy *be)
1412 {
1413 	if (s->flags & SF_BE_ASSIGNED)
1414 		return 1;
1415 
1416 	if (flt_set_stream_backend(s, be) < 0)
1417 		return 0;
1418 
1419 	s->be = be;
1420 	HA_ATOMIC_UPDATE_MAX(&be->be_counters.conn_max,
1421 			     HA_ATOMIC_ADD(&be->beconn, 1));
1422 	proxy_inc_be_ctr(be);
1423 
1424 	/* assign new parameters to the stream from the new backend */
1425 	s->si[1].flags &= ~SI_FL_INDEP_STR;
1426 	if (be->options2 & PR_O2_INDEPSTR)
1427 		s->si[1].flags |= SI_FL_INDEP_STR;
1428 
1429 	if (tick_isset(be->timeout.serverfin))
1430 		s->si[1].hcto = be->timeout.serverfin;
1431 
1432 	/* We want to enable the backend-specific analysers except those which
1433 	 * were already run as part of the frontend/listener. Note that it would
1434 	 * be more reliable to store the list of analysers that have been run,
1435 	 * but what we do here is OK for now.
1436 	 */
1437 	s->req.analysers |= be->be_req_ana & ~(strm_li(s) ? strm_li(s)->analysers : 0);
1438 
1439 	/* If the target backend requires HTTP processing, we have to allocate
1440 	 * the HTTP transaction if we did not have one.
1441 	 */
1442 	if (unlikely(!s->txn && be->http_needed)) {
1443 		if (unlikely(!http_alloc_txn(s)))
1444 			return 0; /* not enough memory */
1445 
1446 		/* and now initialize the HTTP transaction state */
1447 		http_init_txn(s);
1448 	}
1449 
1450 	/* Be sure to filter request headers if the backend is an HTTP proxy and
1451 	 * if there are filters attached to the stream. */
1452 	if (s->be->mode == PR_MODE_HTTP && HAS_FILTERS(s))
1453 		s->req.analysers |= AN_REQ_FLT_HTTP_HDRS;
1454 
1455 	if (s->txn) {
1456 		/* If we chain a TCP frontend to an HTX backend, we must upgrade
1457 		 * the client mux */
1458 		if (!IS_HTX_STRM(s) && be->mode == PR_MODE_HTTP) {
1459 			struct connection  *conn = objt_conn(strm_sess(s)->origin);
1460 			struct conn_stream *cs   = objt_cs(s->si[0].end);
1461 
1462 			if (conn && cs) {
1463 				si_rx_endp_more(&s->si[0]);
1464 				/* Make sure we're unsubscribed, the the new
1465 				 * mux will probably want to subscribe to
1466 				 * the underlying XPRT
1467 				 */
1468 				if (s->si[0].wait_event.events)
1469 					conn->mux->unsubscribe(cs, s->si[0].wait_event.events,
1470 					    &s->si[0].wait_event);
1471 				if (conn_upgrade_mux_fe(conn, cs, &s->req.buf, ist(""), PROTO_MODE_HTTP)  == -1)
1472 					return 0;
1473 				if (!strcmp(conn->mux->name, "H2")) {
1474 					/* For HTTP/2, destroy the conn_stream,
1475 					 * disable logging, and pretend that we
1476 					 * failed, to that the stream is
1477 					 * silently destroyed. The new mux
1478 					 * will create new streams.
1479 					 */
1480 					cs_free(cs);
1481 					si_detach_endpoint(&s->si[0]);
1482 					s->logs.logwait = 0;
1483 					s->logs.level = 0;
1484 					s->flags |= SF_IGNORE;
1485 					return 0;
1486 				}
1487 				s->flags |= SF_HTX;
1488 			}
1489 		}
1490 		else if (IS_HTX_STRM(s) && be->mode != PR_MODE_HTTP) {
1491 			/* If a TCP backend is assgiend to an HTX stream, return
1492 			 * an error. It may happens for a new stream on a
1493 			 * previously upgraded connnections. */
1494 			if (!(s->flags & SF_ERR_MASK))
1495 				s->flags |= SF_ERR_INTERNAL;
1496 			return 0;
1497 		}
1498 
1499 		/* we may request to parse a request body */
1500 		if (be->options & PR_O_WREQ_BODY)
1501 			s->req.analysers |= AN_REQ_HTTP_BODY;
1502 	}
1503 
1504 	s->flags |= SF_BE_ASSIGNED;
1505 	if (be->options2 & PR_O2_NODELAY) {
1506 		s->req.flags |= CF_NEVER_WAIT;
1507 		s->res.flags |= CF_NEVER_WAIT;
1508 	}
1509 
1510 	return 1;
1511 }
1512 
1513 /* Capture a bad request or response and archive it in the proxy's structure.
1514  * It is relatively protocol-agnostic so it requires that a number of elements
1515  * are passed :
1516  *  - <proxy> is the proxy where the error was detected and where the snapshot
1517  *    needs to be stored
1518  *  - <is_back> indicates that the error happened when receiving the response
1519  *  - <other_end> is a pointer to the proxy on the other side when known
1520  *  - <target> is the target of the connection, usually a server or a proxy
1521  *  - <sess> is the session which experienced the error
1522  *  - <ctx> may be NULL or should contain any info relevant to the protocol
1523  *  - <buf> is the buffer containing the offending data
1524  *  - <buf_ofs> is the position of this buffer's input data in the input
1525  *    stream, starting at zero. It may be passed as zero if unknown.
1526  *  - <buf_out> is the portion of <buf->data> which was already forwarded and
1527  *    which precedes the buffer's input. The buffer's input starts at
1528  *    buf->head + buf_out.
1529  *  - <err_pos> is the pointer to the faulty byte in the buffer's input.
1530  *  - <show> is the callback to use to display <ctx>. It may be NULL.
1531  */
proxy_capture_error(struct proxy * proxy,int is_back,struct proxy * other_end,enum obj_type * target,const struct session * sess,const struct buffer * buf,long buf_ofs,unsigned int buf_out,unsigned int err_pos,const union error_snapshot_ctx * ctx,void (* show)(struct buffer *,const struct error_snapshot *))1532 void proxy_capture_error(struct proxy *proxy, int is_back,
1533 			 struct proxy *other_end, enum obj_type *target,
1534 			 const struct session *sess,
1535 			 const struct buffer *buf, long buf_ofs,
1536 			 unsigned int buf_out, unsigned int err_pos,
1537 			 const union error_snapshot_ctx *ctx,
1538 			 void (*show)(struct buffer *, const struct error_snapshot *))
1539 {
1540 	struct error_snapshot *es;
1541 	unsigned int buf_len;
1542 	int len1, len2;
1543 	unsigned int ev_id;
1544 
1545 	ev_id = HA_ATOMIC_XADD(&error_snapshot_id, 1);
1546 
1547 	buf_len = b_data(buf) - buf_out;
1548 
1549 	es = malloc(sizeof(*es) + buf_len);
1550 	if (!es)
1551 		return;
1552 
1553 	es->buf_len = buf_len;
1554 	es->ev_id   = ev_id;
1555 
1556 	len1 = b_size(buf) - b_peek_ofs(buf, buf_out);
1557 	if (len1 > buf_len)
1558 		len1 = buf_len;
1559 
1560 	if (len1) {
1561 		memcpy(es->buf, b_peek(buf, buf_out), len1);
1562 		len2 = buf_len - len1;
1563 		if (len2)
1564 			memcpy(es->buf + len1, b_orig(buf), len2);
1565 	}
1566 
1567 	es->buf_err = err_pos;
1568 	es->when    = date; // user-visible date
1569 	es->srv     = objt_server(target);
1570 	es->oe      = other_end;
1571 	if (objt_conn(sess->origin) && conn_get_src(__objt_conn(sess->origin)))
1572 		es->src  = *__objt_conn(sess->origin)->src;
1573 	else
1574 		memset(&es->src, 0, sizeof(es->src));
1575 
1576 	es->buf_wrap = b_wrap(buf) - b_peek(buf, buf_out);
1577 	es->buf_out  = buf_out;
1578 	es->buf_ofs  = buf_ofs;
1579 
1580 	/* be sure to indicate the offset of the first IN byte */
1581 	if (es->buf_ofs >= es->buf_len)
1582 		es->buf_ofs -= es->buf_len;
1583 	else
1584 		es->buf_ofs = 0;
1585 
1586 	/* protocol-specific part now */
1587 	if (ctx)
1588 		es->ctx = *ctx;
1589 	else
1590 		memset(&es->ctx, 0, sizeof(es->ctx));
1591 	es->show = show;
1592 
1593 	/* note: we still lock since we have to be certain that nobody is
1594 	 * dumping the output while we free.
1595 	 */
1596 	HA_SPIN_LOCK(PROXY_LOCK, &proxy->lock);
1597 	if (is_back) {
1598 		es = HA_ATOMIC_XCHG(&proxy->invalid_rep, es);
1599 	} else {
1600 		es = HA_ATOMIC_XCHG(&proxy->invalid_req, es);
1601 	}
1602 	free(es);
1603 	HA_SPIN_UNLOCK(PROXY_LOCK, &proxy->lock);
1604 }
1605 
1606 /* Configure all proxies which lack a maxconn setting to use the global one by
1607  * default. This avoids the common mistake consisting in setting maxconn only
1608  * in the global section and discovering the hard way that it doesn't propagate
1609  * through the frontends. These values are also propagated through the various
1610  * targetted backends, whose fullconn is finally calculated if not yet set.
1611  */
proxy_adjust_all_maxconn()1612 void proxy_adjust_all_maxconn()
1613 {
1614 	struct proxy *curproxy;
1615 	struct switching_rule *swrule1, *swrule2;
1616 
1617 	for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
1618 		if (curproxy->state == PR_STSTOPPED)
1619 			continue;
1620 
1621 		if (!(curproxy->cap & PR_CAP_FE))
1622 			continue;
1623 
1624 		if (!curproxy->maxconn)
1625 			curproxy->maxconn = global.maxconn;
1626 
1627 		/* update the target backend's fullconn count : default_backend */
1628 		if (curproxy->defbe.be)
1629 			curproxy->defbe.be->tot_fe_maxconn += curproxy->maxconn;
1630 		else if ((curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN)
1631 			curproxy->tot_fe_maxconn += curproxy->maxconn;
1632 
1633 		list_for_each_entry(swrule1, &curproxy->switching_rules, list) {
1634 			/* For each target of switching rules, we update their
1635 			 * tot_fe_maxconn, except if a previous rule points to
1636 			 * the same backend or to the default backend.
1637 			 */
1638 			if (swrule1->be.backend != curproxy->defbe.be) {
1639 				/* note: swrule1->be.backend isn't a backend if the rule
1640 				 * is dynamic, it's an expression instead, so it must not
1641 				 * be dereferenced as a backend before being certain it is.
1642 				 */
1643 				list_for_each_entry(swrule2, &curproxy->switching_rules, list) {
1644 					if (swrule2 == swrule1) {
1645 						if (!swrule1->dynamic)
1646 							swrule1->be.backend->tot_fe_maxconn += curproxy->maxconn;
1647 						break;
1648 					}
1649 					else if (!swrule2->dynamic && swrule2->be.backend == swrule1->be.backend) {
1650 						/* there are multiple refs of this backend */
1651 						break;
1652 					}
1653 				}
1654 			}
1655 		}
1656 	}
1657 
1658 	/* automatically compute fullconn if not set. We must not do it in the
1659 	 * loop above because cross-references are not yet fully resolved.
1660 	 */
1661 	for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
1662 		if (curproxy->state == PR_STSTOPPED)
1663 			continue;
1664 
1665 		/* If <fullconn> is not set, let's set it to 10% of the sum of
1666 		 * the possible incoming frontend's maxconns.
1667 		 */
1668 		if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
1669 			/* we have the sum of the maxconns in <total>. We only
1670 			 * keep 10% of that sum to set the default fullconn, with
1671 			 * a hard minimum of 1 (to avoid a divide by zero).
1672 			 */
1673 			curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
1674 			if (!curproxy->fullconn)
1675 				curproxy->fullconn = 1;
1676 		}
1677 	}
1678 }
1679 
1680 /* Config keywords below */
1681 
1682 static struct cfg_kw_list cfg_kws = {ILH, {
1683 	{ CFG_GLOBAL, "hard-stop-after", proxy_parse_hard_stop_after },
1684 	{ CFG_LISTEN, "timeout", proxy_parse_timeout },
1685 	{ CFG_LISTEN, "clitimeout", proxy_parse_timeout }, /* This keyword actually fails to parse, this line remains for better error messages. */
1686 	{ CFG_LISTEN, "contimeout", proxy_parse_timeout }, /* This keyword actually fails to parse, this line remains for better error messages. */
1687 	{ CFG_LISTEN, "srvtimeout", proxy_parse_timeout }, /* This keyword actually fails to parse, this line remains for better error messages. */
1688 	{ CFG_LISTEN, "rate-limit", proxy_parse_rate_limit },
1689 	{ CFG_LISTEN, "max-keep-alive-queue", proxy_parse_max_ka_queue },
1690 	{ CFG_LISTEN, "declare", proxy_parse_declare },
1691 	{ CFG_LISTEN, "retry-on", proxy_parse_retry_on },
1692 	{ 0, NULL, NULL },
1693 }};
1694 
1695 INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
1696 
1697 /* Expects to find a frontend named <arg> and returns it, otherwise displays various
1698  * adequate error messages and returns NULL. This function is designed to be used by
1699  * functions requiring a frontend on the CLI.
1700  */
cli_find_frontend(struct appctx * appctx,const char * arg)1701 struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg)
1702 {
1703 	struct proxy *px;
1704 
1705 	if (!*arg) {
1706 		cli_err(appctx, "A frontend name is expected.\n");
1707 		return NULL;
1708 	}
1709 
1710 	px = proxy_fe_by_name(arg);
1711 	if (!px) {
1712 		cli_err(appctx, "No such frontend.\n");
1713 		return NULL;
1714 	}
1715 	return px;
1716 }
1717 
1718 /* Expects to find a backend named <arg> and returns it, otherwise displays various
1719  * adequate error messages and returns NULL. This function is designed to be used by
1720  * functions requiring a frontend on the CLI.
1721  */
cli_find_backend(struct appctx * appctx,const char * arg)1722 struct proxy *cli_find_backend(struct appctx *appctx, const char *arg)
1723 {
1724 	struct proxy *px;
1725 
1726 	if (!*arg) {
1727 		cli_err(appctx, "A backend name is expected.\n");
1728 		return NULL;
1729 	}
1730 
1731 	px = proxy_be_by_name(arg);
1732 	if (!px) {
1733 		cli_err(appctx, "No such backend.\n");
1734 		return NULL;
1735 	}
1736 	return px;
1737 }
1738 
1739 
1740 /* parse a "show servers" CLI line, returns 0 if it wants to start the dump or
1741  * 1 if it stops immediately. If an argument is specified, it will set the proxy
1742  * pointer into cli.p0 and its ID into cli.i0.
1743  */
cli_parse_show_servers(char ** args,char * payload,struct appctx * appctx,void * private)1744 static int cli_parse_show_servers(char **args, char *payload, struct appctx *appctx, void *private)
1745 {
1746 	struct proxy *px;
1747 
1748 	/* check if a backend name has been provided */
1749 	if (*args[3]) {
1750 		/* read server state from local file */
1751 		px = proxy_be_by_name(args[3]);
1752 
1753 		if (!px)
1754 			return cli_err(appctx, "Can't find backend.\n");
1755 
1756 		appctx->ctx.cli.p0 = px;
1757 		appctx->ctx.cli.i0 = px->uuid;
1758 	}
1759 	return 0;
1760 }
1761 
1762 /* dumps server state information for all the servers found in backend cli.p0.
1763  * These information are all the parameters which may change during HAProxy runtime.
1764  * By default, we only export to the last known server state file format.
1765  * These information can be used at next startup to recover same level of server state.
1766  * It uses the proxy pointer from cli.p0, the proxy's id from cli.i0 and the server's
1767  * pointer from cli.p1.
1768  */
dump_servers_state(struct stream_interface * si)1769 static int dump_servers_state(struct stream_interface *si)
1770 {
1771 	struct appctx *appctx = __objt_appctx(si->end);
1772 	struct proxy *px = appctx->ctx.cli.p0;
1773 	struct server *srv;
1774 	char srv_addr[INET6_ADDRSTRLEN + 1];
1775 	time_t srv_time_since_last_change;
1776 	int bk_f_forced_id, srv_f_forced_id;
1777 	char *srvrecord;
1778 
1779 	/* we don't want to report any state if the backend is not enabled on this process */
1780 	if (!(proc_mask(px->bind_proc) & pid_bit))
1781 		return 1;
1782 
1783 	if (!appctx->ctx.cli.p1)
1784 		appctx->ctx.cli.p1 = px->srv;
1785 
1786 	for (; appctx->ctx.cli.p1 != NULL; appctx->ctx.cli.p1 = srv->next) {
1787 		srv = appctx->ctx.cli.p1;
1788 		srv_addr[0] = '\0';
1789 
1790 		switch (srv->addr.ss_family) {
1791 			case AF_INET:
1792 				inet_ntop(srv->addr.ss_family, &((struct sockaddr_in *)&srv->addr)->sin_addr,
1793 					  srv_addr, INET_ADDRSTRLEN + 1);
1794 				break;
1795 			case AF_INET6:
1796 				inet_ntop(srv->addr.ss_family, &((struct sockaddr_in6 *)&srv->addr)->sin6_addr,
1797 					  srv_addr, INET6_ADDRSTRLEN + 1);
1798 				break;
1799 			default:
1800 				memcpy(srv_addr, "-\0", 2);
1801 				break;
1802 		}
1803 		srv_time_since_last_change = now.tv_sec - srv->last_change;
1804 		bk_f_forced_id = px->options & PR_O_FORCED_ID ? 1 : 0;
1805 		srv_f_forced_id = srv->flags & SRV_F_FORCED_ID ? 1 : 0;
1806 
1807 		srvrecord = NULL;
1808 		if (srv->srvrq && srv->srvrq->name)
1809 			srvrecord = srv->srvrq->name;
1810 
1811 		chunk_printf(&trash,
1812 				"%d %s "
1813 				"%d %s %s "
1814 				"%d %d %d %d %ld "
1815 				"%d %d %d %d %d "
1816 				"%d %d %s %u %s"
1817 				"\n",
1818 				px->uuid, px->id,
1819 				srv->puid, srv->id, srv_addr,
1820 				srv->cur_state, srv->cur_admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
1821 				srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
1822 				bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-", srv->svc_port,
1823 				srvrecord ? srvrecord : "-");
1824 		if (ci_putchk(si_ic(si), &trash) == -1) {
1825 			si_rx_room_blk(si);
1826 			return 0;
1827 		}
1828 	}
1829 	return 1;
1830 }
1831 
1832 /* Parses backend list or simply use backend name provided by the user to return
1833  * states of servers to stdout. It dumps proxy <cli.p0> and stops if <cli.i0> is
1834  * non-null.
1835  */
cli_io_handler_servers_state(struct appctx * appctx)1836 static int cli_io_handler_servers_state(struct appctx *appctx)
1837 {
1838 	struct stream_interface *si = appctx->owner;
1839 	struct proxy *curproxy;
1840 
1841 	chunk_reset(&trash);
1842 
1843 	if (appctx->st2 == STAT_ST_INIT) {
1844 		if (!appctx->ctx.cli.p0)
1845 			appctx->ctx.cli.p0 = proxies_list;
1846 		appctx->st2 = STAT_ST_HEAD;
1847 	}
1848 
1849 	if (appctx->st2 == STAT_ST_HEAD) {
1850 		chunk_printf(&trash, "%d\n# %s\n", SRV_STATE_FILE_VERSION, SRV_STATE_FILE_FIELD_NAMES);
1851 		if (ci_putchk(si_ic(si), &trash) == -1) {
1852 			si_rx_room_blk(si);
1853 			return 0;
1854 		}
1855 		appctx->st2 = STAT_ST_INFO;
1856 	}
1857 
1858 	/* STAT_ST_INFO */
1859 	for (; appctx->ctx.cli.p0 != NULL; appctx->ctx.cli.p0 = curproxy->next) {
1860 		curproxy = appctx->ctx.cli.p0;
1861 		/* servers are only in backends */
1862 		if (curproxy->cap & PR_CAP_BE) {
1863 			if (!dump_servers_state(si))
1864 				return 0;
1865 		}
1866 		/* only the selected proxy is dumped */
1867 		if (appctx->ctx.cli.i0)
1868 			break;
1869 	}
1870 
1871 	return 1;
1872 }
1873 
1874 /* Parses backend list and simply report backend names. It keeps the proxy
1875  * pointer in cli.p0.
1876  */
cli_io_handler_show_backend(struct appctx * appctx)1877 static int cli_io_handler_show_backend(struct appctx *appctx)
1878 {
1879 	struct stream_interface *si = appctx->owner;
1880 	struct proxy *curproxy;
1881 
1882 	chunk_reset(&trash);
1883 
1884 	if (!appctx->ctx.cli.p0) {
1885 		chunk_printf(&trash, "# name\n");
1886 		if (ci_putchk(si_ic(si), &trash) == -1) {
1887 			si_rx_room_blk(si);
1888 			return 0;
1889 		}
1890 		appctx->ctx.cli.p0 = proxies_list;
1891 	}
1892 
1893 	for (; appctx->ctx.cli.p0 != NULL; appctx->ctx.cli.p0 = curproxy->next) {
1894 		curproxy = appctx->ctx.cli.p0;
1895 
1896 		/* looking for backends only */
1897 		if (!(curproxy->cap & PR_CAP_BE))
1898 			continue;
1899 
1900 		/* we don't want to list a backend which is bound to this process */
1901 		if (!(proc_mask(curproxy->bind_proc) & pid_bit))
1902 			continue;
1903 
1904 		chunk_appendf(&trash, "%s\n", curproxy->id);
1905 		if (ci_putchk(si_ic(si), &trash) == -1) {
1906 			si_rx_room_blk(si);
1907 			return 0;
1908 		}
1909 	}
1910 
1911 	return 1;
1912 }
1913 
1914 /* Parses the "enable dynamic-cookies backend" directive, it always returns 1.
1915  *
1916  * Grabs the proxy lock and each server's lock.
1917  */
cli_parse_enable_dyncookie_backend(char ** args,char * payload,struct appctx * appctx,void * private)1918 static int cli_parse_enable_dyncookie_backend(char **args, char *payload, struct appctx *appctx, void *private)
1919 {
1920 	struct proxy *px;
1921 	struct server *s;
1922 
1923 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
1924 		return 1;
1925 
1926 	px = cli_find_backend(appctx, args[3]);
1927 	if (!px)
1928 		return 1;
1929 
1930 	/* Note: this lock is to make sure this doesn't change while another
1931 	 * thread is in srv_set_dyncookie().
1932 	 */
1933 	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
1934 	px->ck_opts |= PR_CK_DYNAMIC;
1935 	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
1936 
1937 	for (s = px->srv; s != NULL; s = s->next) {
1938 		HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
1939 		srv_set_dyncookie(s);
1940 		HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
1941 	}
1942 
1943 	return 1;
1944 }
1945 
1946 /* Parses the "disable dynamic-cookies backend" directive, it always returns 1.
1947  *
1948  * Grabs the proxy lock and each server's lock.
1949  */
cli_parse_disable_dyncookie_backend(char ** args,char * payload,struct appctx * appctx,void * private)1950 static int cli_parse_disable_dyncookie_backend(char **args, char *payload, struct appctx *appctx, void *private)
1951 {
1952 	struct proxy *px;
1953 	struct server *s;
1954 
1955 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
1956 		return 1;
1957 
1958 	px = cli_find_backend(appctx, args[3]);
1959 	if (!px)
1960 		return 1;
1961 
1962 	/* Note: this lock is to make sure this doesn't change while another
1963 	 * thread is in srv_set_dyncookie().
1964 	 */
1965 	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
1966 	px->ck_opts &= ~PR_CK_DYNAMIC;
1967 	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
1968 
1969 	for (s = px->srv; s != NULL; s = s->next) {
1970 		HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
1971 		if (!(s->flags & SRV_F_COOKIESET)) {
1972 			free(s->cookie);
1973 			s->cookie = NULL;
1974 		}
1975 		HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
1976 	}
1977 
1978 	return 1;
1979 }
1980 
1981 /* Parses the "set dynamic-cookie-key backend" directive, it always returns 1.
1982  *
1983  * Grabs the proxy lock and each server's lock.
1984  */
cli_parse_set_dyncookie_key_backend(char ** args,char * payload,struct appctx * appctx,void * private)1985 static int cli_parse_set_dyncookie_key_backend(char **args, char *payload, struct appctx *appctx, void *private)
1986 {
1987 	struct proxy *px;
1988 	struct server *s;
1989 	char *newkey;
1990 
1991 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
1992 		return 1;
1993 
1994 	px = cli_find_backend(appctx, args[3]);
1995 	if (!px)
1996 		return 1;
1997 
1998 	if (!*args[4])
1999 		return cli_err(appctx, "String value expected.\n");
2000 
2001 	newkey = strdup(args[4]);
2002 	if (!newkey)
2003 		return cli_err(appctx, "Failed to allocate memory.\n");
2004 
2005 	/* Note: this lock is to make sure this doesn't change while another
2006 	 * thread is in srv_set_dyncookie().
2007 	 */
2008 	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
2009 	free(px->dyncookie_key);
2010 	px->dyncookie_key = newkey;
2011 	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
2012 
2013 	for (s = px->srv; s != NULL; s = s->next) {
2014 		HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
2015 		srv_set_dyncookie(s);
2016 		HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
2017 	}
2018 
2019 	return 1;
2020 }
2021 
2022 /* Parses the "set maxconn frontend" directive, it always returns 1.
2023  *
2024  * Grabs the proxy lock.
2025  */
cli_parse_set_maxconn_frontend(char ** args,char * payload,struct appctx * appctx,void * private)2026 static int cli_parse_set_maxconn_frontend(char **args, char *payload, struct appctx *appctx, void *private)
2027 {
2028 	struct proxy *px;
2029 	struct listener *l;
2030 	int v;
2031 
2032 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
2033 		return 1;
2034 
2035 	px = cli_find_frontend(appctx, args[3]);
2036 	if (!px)
2037 		return 1;
2038 
2039 	if (!*args[4])
2040 		return cli_err(appctx, "Integer value expected.\n");
2041 
2042 	v = atoi(args[4]);
2043 	if (v < 0)
2044 		return cli_err(appctx, "Value out of range.\n");
2045 
2046 	/* OK, the value is fine, so we assign it to the proxy and to all of
2047 	 * its listeners. The blocked ones will be dequeued.
2048 	 */
2049 	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
2050 
2051 	px->maxconn = v;
2052 	list_for_each_entry(l, &px->conf.listeners, by_fe) {
2053 		if (l->state == LI_FULL)
2054 			resume_listener(l);
2055 	}
2056 
2057 	if (px->maxconn > px->feconn && !MT_LIST_ISEMPTY(&px->listener_queue))
2058 		dequeue_all_listeners(&px->listener_queue);
2059 
2060 	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
2061 
2062 	return 1;
2063 }
2064 
2065 /* Parses the "shutdown frontend" directive, it always returns 1.
2066  *
2067  * Grabs the proxy lock.
2068  */
cli_parse_shutdown_frontend(char ** args,char * payload,struct appctx * appctx,void * private)2069 static int cli_parse_shutdown_frontend(char **args, char *payload, struct appctx *appctx, void *private)
2070 {
2071 	struct proxy *px;
2072 
2073 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
2074 		return 1;
2075 
2076 	px = cli_find_frontend(appctx, args[2]);
2077 	if (!px)
2078 		return 1;
2079 
2080 	if (px->state == PR_STSTOPPED)
2081 		return cli_msg(appctx, LOG_NOTICE, "Frontend was already shut down.\n");
2082 
2083 	ha_warning("Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
2084 		   px->id, px->fe_counters.cum_conn, px->be_counters.cum_conn);
2085 	send_log(px, LOG_WARNING, "Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
2086 	         px->id, px->fe_counters.cum_conn, px->be_counters.cum_conn);
2087 
2088 	stop_proxy(px);
2089 	return 1;
2090 }
2091 
2092 /* Parses the "disable frontend" directive, it always returns 1.
2093  *
2094  * Grabs the proxy lock.
2095  */
cli_parse_disable_frontend(char ** args,char * payload,struct appctx * appctx,void * private)2096 static int cli_parse_disable_frontend(char **args, char *payload, struct appctx *appctx, void *private)
2097 {
2098 	struct proxy *px;
2099 	int ret;
2100 
2101 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
2102 		return 1;
2103 
2104 	px = cli_find_frontend(appctx, args[2]);
2105 	if (!px)
2106 		return 1;
2107 
2108 	if (px->state == PR_STSTOPPED)
2109 		return cli_msg(appctx, LOG_NOTICE, "Frontend was previously shut down, cannot disable.\n");
2110 
2111 	if (px->state == PR_STPAUSED)
2112 		return cli_msg(appctx, LOG_NOTICE, "Frontend is already disabled.\n");
2113 
2114 	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
2115 	ret = pause_proxy(px);
2116 	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
2117 
2118 	if (!ret)
2119 		return cli_err(appctx, "Failed to pause frontend, check logs for precise cause.\n");
2120 
2121 	return 1;
2122 }
2123 
2124 /* Parses the "enable frontend" directive, it always returns 1.
2125  *
2126  * Grabs the proxy lock.
2127  */
cli_parse_enable_frontend(char ** args,char * payload,struct appctx * appctx,void * private)2128 static int cli_parse_enable_frontend(char **args, char *payload, struct appctx *appctx, void *private)
2129 {
2130 	struct proxy *px;
2131 	int ret;
2132 
2133 	if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
2134 		return 1;
2135 
2136 	px = cli_find_frontend(appctx, args[2]);
2137 	if (!px)
2138 		return 1;
2139 
2140 	if (px->state == PR_STSTOPPED)
2141 		return cli_err(appctx, "Frontend was previously shut down, cannot enable.\n");
2142 
2143 	if (px->state != PR_STPAUSED)
2144 		return cli_msg(appctx, LOG_NOTICE, "Frontend is already enabled.\n");
2145 
2146 	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
2147 	ret = resume_proxy(px);
2148 	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
2149 
2150 	if (!ret)
2151 		return cli_err(appctx, "Failed to resume frontend, check logs for precise cause (port conflict?).\n");
2152 	return 1;
2153 }
2154 
2155 /* "show errors" handler for the CLI. Returns 0 if wants to continue, 1 to stop
2156  * now.
2157  */
cli_parse_show_errors(char ** args,char * payload,struct appctx * appctx,void * private)2158 static int cli_parse_show_errors(char **args, char *payload, struct appctx *appctx, void *private)
2159 {
2160 	if (!cli_has_level(appctx, ACCESS_LVL_OPER))
2161 		return 1;
2162 
2163 	if (*args[2]) {
2164 		struct proxy *px;
2165 
2166 		px = proxy_find_by_name(args[2], 0, 0);
2167 		if (px)
2168 			appctx->ctx.errors.iid = px->uuid;
2169 		else
2170 			appctx->ctx.errors.iid = atoi(args[2]);
2171 
2172 		if (!appctx->ctx.errors.iid)
2173 			return cli_err(appctx, "No such proxy.\n");
2174 	}
2175 	else
2176 		appctx->ctx.errors.iid	= -1; // dump all proxies
2177 
2178 	appctx->ctx.errors.flag = 0;
2179 	if (strcmp(args[3], "request") == 0)
2180 		appctx->ctx.errors.flag |= 4; // ignore response
2181 	else if (strcmp(args[3], "response") == 0)
2182 		appctx->ctx.errors.flag |= 2; // ignore request
2183 	appctx->ctx.errors.px = NULL;
2184 	return 0;
2185 }
2186 
2187 /* This function dumps all captured errors onto the stream interface's
2188  * read buffer. It returns 0 if the output buffer is full and it needs
2189  * to be called again, otherwise non-zero.
2190  */
cli_io_handler_show_errors(struct appctx * appctx)2191 static int cli_io_handler_show_errors(struct appctx *appctx)
2192 {
2193 	struct stream_interface *si = appctx->owner;
2194 	extern const char *monthname[12];
2195 
2196 	if (unlikely(si_ic(si)->flags & (CF_WRITE_ERROR|CF_SHUTW)))
2197 		return 1;
2198 
2199 	chunk_reset(&trash);
2200 
2201 	if (!appctx->ctx.errors.px) {
2202 		/* the function had not been called yet, let's prepare the
2203 		 * buffer for a response.
2204 		 */
2205 		struct tm tm;
2206 
2207 		get_localtime(date.tv_sec, &tm);
2208 		chunk_appendf(&trash, "Total events captured on [%02d/%s/%04d:%02d:%02d:%02d.%03d] : %u\n",
2209 			     tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
2210 			     tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(date.tv_usec/1000),
2211 			     error_snapshot_id);
2212 
2213 		if (ci_putchk(si_ic(si), &trash) == -1)
2214 			goto cant_send;
2215 
2216 		appctx->ctx.errors.px = proxies_list;
2217 		appctx->ctx.errors.bol = 0;
2218 		appctx->ctx.errors.ptr = -1;
2219 	}
2220 
2221 	/* we have two inner loops here, one for the proxy, the other one for
2222 	 * the buffer.
2223 	 */
2224 	while (appctx->ctx.errors.px) {
2225 		struct error_snapshot *es;
2226 
2227 		HA_SPIN_LOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
2228 
2229 		if ((appctx->ctx.errors.flag & 1) == 0) {
2230 			es = appctx->ctx.errors.px->invalid_req;
2231 			if (appctx->ctx.errors.flag & 2) // skip req
2232 				goto next;
2233 		}
2234 		else {
2235 			es = appctx->ctx.errors.px->invalid_rep;
2236 			if (appctx->ctx.errors.flag & 4) // skip resp
2237 				goto next;
2238 		}
2239 
2240 		if (!es)
2241 			goto next;
2242 
2243 		if (appctx->ctx.errors.iid >= 0 &&
2244 		    appctx->ctx.errors.px->uuid != appctx->ctx.errors.iid &&
2245 		    es->oe->uuid != appctx->ctx.errors.iid)
2246 			goto next;
2247 
2248 		if (appctx->ctx.errors.ptr < 0) {
2249 			/* just print headers now */
2250 
2251 			char pn[INET6_ADDRSTRLEN];
2252 			struct tm tm;
2253 			int port;
2254 
2255 			get_localtime(es->when.tv_sec, &tm);
2256 			chunk_appendf(&trash, " \n[%02d/%s/%04d:%02d:%02d:%02d.%03d]",
2257 				     tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
2258 				     tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(es->when.tv_usec/1000));
2259 
2260 			switch (addr_to_str(&es->src, pn, sizeof(pn))) {
2261 			case AF_INET:
2262 			case AF_INET6:
2263 				port = get_host_port(&es->src);
2264 				break;
2265 			default:
2266 				port = 0;
2267 			}
2268 
2269 			switch (appctx->ctx.errors.flag & 1) {
2270 			case 0:
2271 				chunk_appendf(&trash,
2272 					     " frontend %s (#%d): invalid request\n"
2273 					     "  backend %s (#%d)",
2274 					     appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
2275 					     (es->oe->cap & PR_CAP_BE) ? es->oe->id : "<NONE>",
2276 					     (es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1);
2277 				break;
2278 			case 1:
2279 				chunk_appendf(&trash,
2280 					     " backend %s (#%d): invalid response\n"
2281 					     "  frontend %s (#%d)",
2282 					     appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
2283 					     es->oe->id, es->oe->uuid);
2284 				break;
2285 			}
2286 
2287 			chunk_appendf(&trash,
2288 			              ", server %s (#%d), event #%u, src %s:%d\n"
2289 			              "  buffer starts at %llu (including %u out), %u free,\n"
2290 			              "  len %u, wraps at %u, error at position %u\n",
2291 			              es->srv ? es->srv->id : "<NONE>",
2292 			              es->srv ? es->srv->puid : -1,
2293 			              es->ev_id, pn, port,
2294 			              es->buf_ofs, es->buf_out,
2295 			              global.tune.bufsize - es->buf_out - es->buf_len,
2296 			              es->buf_len, es->buf_wrap, es->buf_err);
2297 
2298 			if (es->show)
2299 				es->show(&trash, es);
2300 
2301 			chunk_appendf(&trash, "  \n");
2302 
2303 			if (ci_putchk(si_ic(si), &trash) == -1)
2304 				goto cant_send_unlock;
2305 
2306 			appctx->ctx.errors.ptr = 0;
2307 			appctx->ctx.errors.ev_id = es->ev_id;
2308 		}
2309 
2310 		if (appctx->ctx.errors.ev_id != es->ev_id) {
2311 			/* the snapshot changed while we were dumping it */
2312 			chunk_appendf(&trash,
2313 				     "  WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
2314 			if (ci_putchk(si_ic(si), &trash) == -1)
2315 				goto cant_send_unlock;
2316 
2317 			goto next;
2318 		}
2319 
2320 		/* OK, ptr >= 0, so we have to dump the current line */
2321 		while (appctx->ctx.errors.ptr < es->buf_len && appctx->ctx.errors.ptr < global.tune.bufsize) {
2322 			int newptr;
2323 			int newline;
2324 
2325 			newline = appctx->ctx.errors.bol;
2326 			newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, appctx->ctx.errors.ptr);
2327 			if (newptr == appctx->ctx.errors.ptr)
2328 				goto cant_send_unlock;
2329 
2330 			if (ci_putchk(si_ic(si), &trash) == -1)
2331 				goto cant_send_unlock;
2332 
2333 			appctx->ctx.errors.ptr = newptr;
2334 			appctx->ctx.errors.bol = newline;
2335 		};
2336 	next:
2337 		HA_SPIN_UNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
2338 		appctx->ctx.errors.bol = 0;
2339 		appctx->ctx.errors.ptr = -1;
2340 		appctx->ctx.errors.flag ^= 1;
2341 		if (!(appctx->ctx.errors.flag & 1))
2342 			appctx->ctx.errors.px = appctx->ctx.errors.px->next;
2343 	}
2344 
2345 	/* dump complete */
2346 	return 1;
2347 
2348  cant_send_unlock:
2349 	HA_SPIN_UNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
2350  cant_send:
2351 	si_rx_room_blk(si);
2352 	return 0;
2353 }
2354 
2355 /* register cli keywords */
2356 static struct cli_kw_list cli_kws = {{ },{
2357 	{ { "disable", "frontend",  NULL }, "disable frontend : temporarily disable specific frontend", cli_parse_disable_frontend, NULL, NULL },
2358 	{ { "enable", "frontend",  NULL }, "enable frontend : re-enable specific frontend", cli_parse_enable_frontend, NULL, NULL },
2359 	{ { "set", "maxconn", "frontend",  NULL }, "set maxconn frontend : change a frontend's maxconn setting", cli_parse_set_maxconn_frontend, NULL },
2360 	{ { "show","servers", "state",  NULL }, "show servers state [id]: dump volatile server information (for backend <id>)", cli_parse_show_servers, cli_io_handler_servers_state },
2361 	{ { "show", "backend", NULL }, "show backend   : list backends in the current running config", NULL, cli_io_handler_show_backend },
2362 	{ { "shutdown", "frontend",  NULL }, "shutdown frontend : stop a specific frontend", cli_parse_shutdown_frontend, NULL, NULL },
2363 	{ { "set", "dynamic-cookie-key", "backend", NULL }, "set dynamic-cookie-key backend : change a backend secret key for dynamic cookies", cli_parse_set_dyncookie_key_backend, NULL },
2364 	{ { "enable", "dynamic-cookie", "backend", NULL }, "enable dynamic-cookie backend : enable dynamic cookies on a specific backend", cli_parse_enable_dyncookie_backend, NULL },
2365 	{ { "disable", "dynamic-cookie", "backend", NULL }, "disable dynamic-cookie backend : disable dynamic cookies on a specific backend", cli_parse_disable_dyncookie_backend, NULL },
2366 	{ { "show", "errors", NULL }, "show errors    : report last request and response errors for each proxy", cli_parse_show_errors, cli_io_handler_show_errors, NULL },
2367 	{{},}
2368 }};
2369 
2370 INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
2371 
2372 /*
2373  * Local variables:
2374  *  c-indent-level: 8
2375  *  c-basic-offset: 8
2376  * End:
2377  */
2378