blob: cef5e3979cd2ed9093283addfa161c5a836503e5 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Configuration parser
3 *
Willy Tarreauff011f22011-01-06 17:51:27 +01004 * Copyright 2000-2011 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
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
Cyril Bonté1a0191d2014-08-29 20:20:02 +020013#ifdef CONFIG_HAP_CRYPT
14/* This is to have crypt() defined on Linux */
15#define _GNU_SOURCE
16
17#ifdef NEED_CRYPT_H
18/* some platforms such as Solaris need this */
19#include <crypt.h>
20#endif
21#endif /* CONFIG_HAP_CRYPT */
22
Willy Tarreaubaaee002006-06-26 02:48:02 +020023#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <netdb.h>
27#include <ctype.h>
Willy Tarreau95c20ac2007-03-25 15:39:23 +020028#include <pwd.h>
29#include <grp.h>
Willy Tarreau0b4ed902007-03-26 00:18:40 +020030#include <errno.h>
Willy Tarreau3f49b302007-06-11 00:29:26 +020031#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <unistd.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035
Willy Tarreau2dd0d472006-06-29 17:53:05 +020036#include <common/cfgparse.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020037#include <common/chunk.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020038#include <common/config.h>
Willy Tarreau058e9072009-07-20 09:30:05 +020039#include <common/errors.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020040#include <common/memory.h>
41#include <common/standard.h>
42#include <common/time.h>
43#include <common/uri_auth.h>
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +010044#include <common/namespace.h>
Emeric Brunc60def82017-09-27 14:59:38 +020045#include <common/hathreads.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020046
47#include <types/capture.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020048#include <types/compression.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020049#include <types/filters.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020050#include <types/global.h>
Willy Tarreau3fdb3662012-11-12 00:42:33 +010051#include <types/obj_type.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020052#include <types/peers.h>
Simon Horman0d16a402015-01-30 11:22:58 +090053#include <types/mailers.h>
Baptiste Assmann325137d2015-04-13 23:40:55 +020054#include <types/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010055#include <types/stats.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020056
Willy Tarreaueb0c6142007-05-07 00:53:22 +020057#include <proto/acl.h>
Christopher Faulet4fce0d82017-09-18 11:57:31 +020058#include <proto/action.h>
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +010059#include <proto/auth.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020060#include <proto/backend.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020061#include <proto/channel.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020062#include <proto/checks.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020063#include <proto/compression.h>
Baptiste Assmann201c07f2017-05-22 15:17:15 +020064#include <proto/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010065#include <proto/stats.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020066#include <proto/filters.h>
Willy Tarreaueb472682010-05-28 18:46:57 +020067#include <proto/frontend.h>
Willy Tarreau34eb6712011-10-24 18:15:04 +020068#include <proto/hdr_idx.h>
Willy Tarreau61c112a2018-10-02 16:43:32 +020069#include <proto/http_rules.h>
Willy Tarreau6b2e11b2009-10-01 07:52:15 +020070#include <proto/lb_chash.h>
Willy Tarreauf09c6602012-02-13 17:12:08 +010071#include <proto/lb_fas.h>
Willy Tarreauf89c1872009-10-01 11:19:37 +020072#include <proto/lb_fwlc.h>
73#include <proto/lb_fwrr.h>
74#include <proto/lb_map.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020075#include <proto/listener.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020076#include <proto/log.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020077#include <proto/protocol.h>
Willy Tarreaue6b98942007-10-29 01:09:36 +010078#include <proto/proto_http.h>
Willy Tarreau2b5652f2006-12-31 17:46:05 +010079#include <proto/proxy.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020080#include <proto/peers.h>
Willy Tarreaucd3b0942012-04-27 21:52:18 +020081#include <proto/sample.h>
Willy Tarreau9903f0e2015-04-04 18:50:31 +020082#include <proto/session.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020083#include <proto/server.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020084#include <proto/stream.h>
Emeric Brunb982a3d2010-01-04 15:45:53 +010085#include <proto/stick_table.h>
Willy Tarreau39713102016-11-25 15:49:32 +010086#include <proto/task.h>
87#include <proto/tcp_rules.h>
Olivier Houchard673867c2018-05-25 16:58:52 +020088#include <proto/connection.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020089
90
Willy Tarreauf3c69202006-07-09 16:42:34 +020091/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
92 * ssl-hello-chk option to ensure that the remote server speaks SSL.
93 *
94 * Check RFC 2246 (TLSv1.0) sections A.3 and A.4 for details.
95 */
96const char sslv3_client_hello_pkt[] = {
97 "\x16" /* ContentType : 0x16 = Hanshake */
98 "\x03\x00" /* ProtocolVersion : 0x0300 = SSLv3 */
99 "\x00\x79" /* ContentLength : 0x79 bytes after this one */
100 "\x01" /* HanshakeType : 0x01 = CLIENT HELLO */
101 "\x00\x00\x75" /* HandshakeLength : 0x75 bytes after this one */
102 "\x03\x00" /* Hello Version : 0x0300 = v3 */
103 "\x00\x00\x00\x00" /* Unix GMT Time (s) : filled with <now> (@0x0B) */
104 "HAPROXYSSLCHK\nHAPROXYSSLCHK\n" /* Random : must be exactly 28 bytes */
105 "\x00" /* Session ID length : empty (no session ID) */
106 "\x00\x4E" /* Cipher Suite Length : 78 bytes after this one */
107 "\x00\x01" "\x00\x02" "\x00\x03" "\x00\x04" /* 39 most common ciphers : */
108 "\x00\x05" "\x00\x06" "\x00\x07" "\x00\x08" /* 0x01...0x1B, 0x2F...0x3A */
109 "\x00\x09" "\x00\x0A" "\x00\x0B" "\x00\x0C" /* This covers RSA/DH, */
110 "\x00\x0D" "\x00\x0E" "\x00\x0F" "\x00\x10" /* various bit lengths, */
111 "\x00\x11" "\x00\x12" "\x00\x13" "\x00\x14" /* SHA1/MD5, DES/3DES/AES... */
112 "\x00\x15" "\x00\x16" "\x00\x17" "\x00\x18"
113 "\x00\x19" "\x00\x1A" "\x00\x1B" "\x00\x2F"
114 "\x00\x30" "\x00\x31" "\x00\x32" "\x00\x33"
115 "\x00\x34" "\x00\x35" "\x00\x36" "\x00\x37"
116 "\x00\x38" "\x00\x39" "\x00\x3A"
117 "\x01" /* Compression Length : 0x01 = 1 byte for types */
118 "\x00" /* Compression Type : 0x00 = NULL compression */
119};
120
Willy Tarreau3842f002009-06-14 11:39:52 +0200121/* various keyword modifiers */
122enum kw_mod {
123 KWM_STD = 0, /* normal */
124 KWM_NO, /* "no" prefixed before the keyword */
125 KWM_DEF, /* "default" prefixed before the keyword */
126};
127
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100128/* permit to store configuration section */
129struct cfg_section {
130 struct list list;
131 char *section_name;
132 int (*section_parser)(const char *, int, char **, int);
William Lallemandd2ff56d2017-10-16 11:06:50 +0200133 int (*post_section_parser)();
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100134};
135
136/* Used to chain configuration sections definitions. This list
137 * stores struct cfg_section
138 */
139struct list sections = LIST_HEAD_INIT(sections);
140
William Lallemand48b4bb42017-10-23 14:36:34 +0200141/* store post configuration parsing */
142
143struct cfg_postparser {
144 struct list list;
145 char *name;
146 int (*func)();
147};
148
149struct list postparsers = LIST_HEAD_INIT(postparsers);
150
Willy Tarreau13943ab2006-12-31 00:24:10 +0100151/* some of the most common options which are also the easiest to handle */
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100152struct cfg_opt {
Willy Tarreau13943ab2006-12-31 00:24:10 +0100153 const char *name;
154 unsigned int val;
155 unsigned int cap;
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100156 unsigned int checks;
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100157 unsigned int mode;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100158};
159
160/* proxy->options */
161static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100162{
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100163 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
164 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
165 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
166 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
167 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
168 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100169 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau9fbe18e2015-05-01 22:42:08 +0200170 { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau0f228a02015-05-01 15:37:53 +0200171 { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreau9420b122013-12-15 18:58:25 +0100172 { "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100173 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
174 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
175 { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100176 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100177#ifdef TPROXY
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100178 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100179#else
180 { "transparent", 0, 0, 0, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100181#endif
182
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100183 { NULL, 0, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100184};
185
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100186/* proxy->options2 */
187static const struct cfg_opt cfg_opts2[] =
188{
189#ifdef CONFIG_HAP_LINUX_SPLICE
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100190 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
191 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
192 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100193#else
194 { "splice-request", 0, 0, 0, 0 },
195 { "splice-response", 0, 0, 0, 0 },
196 { "splice-auto", 0, 0, 0, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100197#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100198 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
199 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
200 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
201 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
202 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0, 0 },
203 { "socket-stats", PR_O2_SOCKSTAT, PR_CAP_FE, 0, 0 },
204 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0, 0 },
205 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0, 0 },
206 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Jamie Gloudon801a0a32012-08-25 00:18:33 -0400207 { "independent-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100208 { "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
Christopher Faulet98db9762018-09-21 10:25:19 +0200209 { "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau96e31212011-05-30 18:10:30 +0200210 { "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau68ad3a42018-10-22 11:49:15 +0200211 { "http-use-htx", PR_O2_USE_HTX, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100212 { NULL, 0, 0, 0 }
213};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200214
Willy Tarreau6daf3432008-01-22 16:44:08 +0100215static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200216static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
217int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100218int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100219char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200220
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200221/* List head of all known configuration keywords */
222static struct cfg_kw_list cfg_keywords = {
223 .list = LIST_HEAD_INIT(cfg_keywords.list)
224};
225
Willy Tarreaubaaee002006-06-26 02:48:02 +0200226/*
227 * converts <str> to a list of listeners which are dynamically allocated.
228 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
229 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
230 * - <port> is a numerical port from 1 to 65535 ;
231 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
232 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200233 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
234 * not NULL, it must be a valid pointer to either NULL or a freeable area that
235 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200236 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200237int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200238{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100239 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200240 int port, end;
241
242 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200243
Willy Tarreaubaaee002006-06-26 02:48:02 +0200244 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100245 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200246 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100247 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200248
249 str = next;
250 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100251 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200252 *next++ = 0;
253 }
254
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100255 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200256 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200257 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100258 if (!ss2)
259 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200260
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100261 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100262 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200263 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100264 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200265 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200266
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100267 if (!port || !end) {
268 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
269 goto fail;
270 }
271
Emeric Bruned760922010-10-22 17:59:25 +0200272 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200273 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200274 goto fail;
275 }
276
277 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200278 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200279 goto fail;
280 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200281 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100282 else if (ss2->ss_family == AF_UNSPEC) {
283 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100284 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100285
286 /* We want to attach to an already bound fd whose number
287 * is in the addr part of ss2 when cast to sockaddr_in.
288 * Note that by definition there is a single listener.
289 * We still have to determine the address family to
290 * register the correct protocol.
291 */
292 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
293 addr_len = sizeof(*ss2);
294 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
295 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
296 goto fail;
297 }
298
299 port = end = get_host_port(ss2);
William Lallemand2fe7dd02018-09-11 16:51:29 +0200300
301 } else if (ss2->ss_family == AF_CUST_SOCKPAIR) {
302 socklen_t addr_len;
303 inherited = 1;
304
305 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
306 addr_len = sizeof(*ss2);
307 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
308 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
309 goto fail;
310 }
311
312 ss2->ss_family = AF_CUST_SOCKPAIR; /* reassign AF_CUST_SOCKPAIR because of getsockname */
313 port = end = 0;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100314 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200315
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100316 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100317 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200318 memprintf(err, "%s for address '%s'.\n", *err, str);
319 goto fail;
320 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200321 } /* end while(next) */
322 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200323 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200324 fail:
325 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200326 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200327}
328
William Lallemand6e62fb62015-04-28 16:55:23 +0200329/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100330 * Report an error in <msg> when there are too many arguments. This version is
331 * intended to be used by keyword parsers so that the message will be included
332 * into the general error message. The index is the current keyword in args.
333 * Return 0 if the number of argument is correct, otherwise build a message and
334 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
335 * message may also be null, it will simply not be produced (useful to check only).
336 * <msg> and <err_code> are only affected on error.
337 */
338int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
339{
340 int i;
341
342 if (!*args[index + maxarg + 1])
343 return 0;
344
345 if (msg) {
346 *msg = NULL;
347 memprintf(msg, "%s", args[0]);
348 for (i = 1; i <= index; i++)
349 memprintf(msg, "%s %s", *msg, args[i]);
350
351 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
352 }
353 if (err_code)
354 *err_code |= ERR_ALERT | ERR_FATAL;
355
356 return 1;
357}
358
359/*
360 * same as too_many_args_idx with a 0 index
361 */
362int too_many_args(int maxarg, char **args, char **msg, int *err_code)
363{
364 return too_many_args_idx(maxarg, 0, args, msg, err_code);
365}
366
367/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200368 * Report a fatal Alert when there is too much arguments
369 * The index is the current keyword in args
370 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
371 * Fill err_code with an ERR_ALERT and an ERR_FATAL
372 */
373int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
374{
375 char *kw = NULL;
376 int i;
377
378 if (!*args[index + maxarg + 1])
379 return 0;
380
381 memprintf(&kw, "%s", args[0]);
382 for (i = 1; i <= index; i++) {
383 memprintf(&kw, "%s %s", kw, args[i]);
384 }
385
Christopher Faulet767a84b2017-11-24 16:50:31 +0100386 ha_alert("parsing [%s:%d] : '%s' cannot handle unexpected argument '%s'.\n", file, linenum, kw, args[index + maxarg + 1]);
William Lallemand6e62fb62015-04-28 16:55:23 +0200387 free(kw);
388 *err_code |= ERR_ALERT | ERR_FATAL;
389 return 1;
390}
391
392/*
393 * same as alertif_too_many_args_idx with a 0 index
394 */
395int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
396{
397 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
398}
399
Willy Tarreau620408f2016-10-21 16:37:51 +0200400/* Report a warning if a rule is placed after a 'tcp-request session' rule.
401 * Return 1 if the warning has been emitted, otherwise 0.
402 */
403int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
404{
405 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100406 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
407 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200408 return 1;
409 }
410 return 0;
411}
412
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200413/* Report a warning if a rule is placed after a 'tcp-request content' rule.
414 * Return 1 if the warning has been emitted, otherwise 0.
415 */
416int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
417{
418 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100419 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
420 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200421 return 1;
422 }
423 return 0;
424}
425
Willy Tarreau721d8e02017-12-01 18:25:08 +0100426/* Report a warning if a rule is placed after a 'monitor fail' rule.
427 * Return 1 if the warning has been emitted, otherwise 0.
428 */
429int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
430{
431 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
432 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
433 file, line, arg);
434 return 1;
435 }
436 return 0;
437}
438
Willy Tarreau61d18892009-03-31 10:49:21 +0200439/* Report a warning if a rule is placed after a 'block' rule.
440 * Return 1 if the warning has been emitted, otherwise 0.
441 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100442int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200443{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200444 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100445 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
446 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200447 return 1;
448 }
449 return 0;
450}
451
Willy Tarreau5002f572014-04-23 01:32:02 +0200452/* Report a warning if a rule is placed after an 'http_request' rule.
453 * Return 1 if the warning has been emitted, otherwise 0.
454 */
455int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
456{
457 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100458 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
459 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200460 return 1;
461 }
462 return 0;
463}
464
Willy Tarreau61d18892009-03-31 10:49:21 +0200465/* Report a warning if a rule is placed after a reqrewrite rule.
466 * Return 1 if the warning has been emitted, otherwise 0.
467 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100468int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200469{
470 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100471 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
472 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200473 return 1;
474 }
475 return 0;
476}
477
478/* Report a warning if a rule is placed after a reqadd rule.
479 * Return 1 if the warning has been emitted, otherwise 0.
480 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100481int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200482{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100483 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100484 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
485 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200486 return 1;
487 }
488 return 0;
489}
490
491/* Report a warning if a rule is placed after a redirect rule.
492 * Return 1 if the warning has been emitted, otherwise 0.
493 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100494int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200495{
496 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100497 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
498 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200499 return 1;
500 }
501 return 0;
502}
503
504/* Report a warning if a rule is placed after a 'use_backend' rule.
505 * Return 1 if the warning has been emitted, otherwise 0.
506 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100507int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200508{
509 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100510 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
511 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200512 return 1;
513 }
514 return 0;
515}
516
Willy Tarreauee445d92014-04-23 01:39:04 +0200517/* Report a warning if a rule is placed after a 'use-server' rule.
518 * Return 1 if the warning has been emitted, otherwise 0.
519 */
520int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
521{
522 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100523 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
524 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200525 return 1;
526 }
527 return 0;
528}
529
Willy Tarreaud39ad442016-11-25 15:16:12 +0100530/* report a warning if a redirect rule is dangerously placed */
531int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200532{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100533 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200534 warnif_rule_after_use_server(proxy, file, line, arg);
535}
536
Willy Tarreaud39ad442016-11-25 15:16:12 +0100537/* report a warning if a reqadd rule is dangerously placed */
538int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200539{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100540 return warnif_rule_after_redirect(proxy, file, line, arg) ||
541 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200542}
543
Willy Tarreaud39ad442016-11-25 15:16:12 +0100544/* report a warning if a reqxxx rule is dangerously placed */
545int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200546{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100547 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
548 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200549}
550
551/* report a warning if an http-request rule is dangerously placed */
552int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
553{
Willy Tarreau61d18892009-03-31 10:49:21 +0200554 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100555 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200556}
557
Willy Tarreaud39ad442016-11-25 15:16:12 +0100558/* report a warning if a block rule is dangerously placed */
559int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200560{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100561 return warnif_rule_after_http_req(proxy, file, line, arg) ||
562 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200563}
564
Willy Tarreau721d8e02017-12-01 18:25:08 +0100565/* report a warning if a block rule is dangerously placed */
566int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200567{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100568 return warnif_rule_after_block(proxy, file, line, arg) ||
569 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200570}
571
Willy Tarreau721d8e02017-12-01 18:25:08 +0100572/* report a warning if a "tcp request content" rule is dangerously placed */
573int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
574{
575 return warnif_rule_after_monitor(proxy, file, line, arg) ||
576 warnif_misplaced_monitor(proxy, file, line, arg);
577}
578
Willy Tarreaud39ad442016-11-25 15:16:12 +0100579/* report a warning if a "tcp request session" rule is dangerously placed */
580int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200581{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100582 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
583 warnif_misplaced_tcp_cont(proxy, file, line, arg);
584}
585
586/* report a warning if a "tcp request connection" rule is dangerously placed */
587int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
588{
589 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
590 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200591}
592
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100593/* Report it if a request ACL condition uses some keywords that are incompatible
594 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
595 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
596 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100597 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100598static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100599{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100600 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200601 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100602
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100603 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100604 return 0;
605
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100606 acl = acl_cond_conflicts(cond, where);
607 if (acl) {
608 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100609 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
610 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100611 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100612 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
613 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100614 return ERR_WARN;
615 }
616 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100617 return 0;
618
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100619 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100620 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
621 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100622 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100623 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
624 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100625 return ERR_WARN;
626}
627
Christopher Faulet62519022017-10-16 15:49:32 +0200628/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100629 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100630 * two such numbers delimited by a dash ('-'). On success, it returns
631 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200632 *
633 * Note: this function can also be used to parse a thread number or a set of
634 * threads.
635 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100636int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200637{
Christopher Faulet26028f62017-11-22 15:01:51 +0100638 if (autoinc) {
639 *autoinc = 0;
640 if (strncmp(arg, "auto:", 5) == 0) {
641 arg += 5;
642 *autoinc = 1;
643 }
644 }
645
Christopher Faulet62519022017-10-16 15:49:32 +0200646 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100647 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200648 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100649 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200650 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100651 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200652 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100653 char *dash;
654 unsigned int low, high;
655
Christopher Faulet5ab51772017-11-22 11:21:58 +0100656 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100657 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100658 return -1;
659 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100660
661 low = high = str2uic(arg);
662 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100663 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
664
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100665 if (high < low) {
666 unsigned int swap = low;
667 low = high;
668 high = swap;
669 }
670
Christopher Faulet5ab51772017-11-22 11:21:58 +0100671 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100672 memprintf(err, "'%s' is not a valid number/range."
673 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100674 arg, LONGBITS);
675 return 1;
676 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100677
678 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100679 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200680 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100681
Christopher Faulet5ab51772017-11-22 11:21:58 +0100682 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200683}
684
David Carlier7e351ee2017-12-01 09:14:02 +0000685#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200686/* Parse cpu sets. Each CPU set is either a unique number between 0 and
687 * <LONGBITS> or a range with two such numbers delimited by a dash
688 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
689 * returns 0. otherwise it returns 1 with an error message in <err>.
690 */
691static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
692{
693 int cur_arg = 0;
694
695 *cpu_set = 0;
696 while (*args[cur_arg]) {
697 char *dash;
698 unsigned int low, high;
699
700 if (!isdigit((int)*args[cur_arg])) {
701 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
702 return -1;
703 }
704
705 low = high = str2uic(args[cur_arg]);
706 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100707 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200708
709 if (high < low) {
710 unsigned int swap = low;
711 low = high;
712 high = swap;
713 }
714
715 if (high >= LONGBITS) {
716 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
717 return 1;
718 }
719
720 while (low <= high)
721 *cpu_set |= 1UL << low++;
722
723 cur_arg++;
724 }
725 return 0;
726}
David Carlier7e351ee2017-12-01 09:14:02 +0000727#endif
728
Willy Tarreaubaaee002006-06-26 02:48:02 +0200729/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200730 * parse a line in a <global> section. Returns the error code, 0 if OK, or
731 * any combination of :
732 * - ERR_ABORT: must abort ASAP
733 * - ERR_FATAL: we can continue parsing but not start the service
734 * - ERR_WARN: a warning has been emitted
735 * - ERR_ALERT: an alert has been emitted
736 * Only the two first ones can stop processing, the two others are just
737 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200738 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200739int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200740{
Willy Tarreau058e9072009-07-20 09:30:05 +0200741 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200742 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200743
744 if (!strcmp(args[0], "global")) { /* new section */
745 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200746 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200747 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200748 }
749 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200750 if (alertif_too_many_args(0, file, linenum, args, &err_code))
751 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200752 global.mode |= MODE_DAEMON;
753 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200754 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200755 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200756 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200757 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100758 if (!strcmp(args[1], "no-exit-on-failure")) {
759 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200760 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100761 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
William Lallemand69f9b3b2017-06-01 17:38:54 +0200762 err_code |= ERR_ALERT | ERR_FATAL;
763 goto out;
764 }
765 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200766 global.mode |= MODE_MWORKER;
767 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200768 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200769 if (alertif_too_many_args(0, file, linenum, args, &err_code))
770 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200771 global.mode |= MODE_DEBUG;
772 }
773 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200774 if (alertif_too_many_args(0, file, linenum, args, &err_code))
775 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100776 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200777 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200778 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200779 if (alertif_too_many_args(0, file, linenum, args, &err_code))
780 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100781 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200782 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200783 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200784 if (alertif_too_many_args(0, file, linenum, args, &err_code))
785 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100786 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200787 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100788 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200789 if (alertif_too_many_args(0, file, linenum, args, &err_code))
790 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100791 global.tune.options &= ~GTUNE_USE_SPLICE;
792 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200793 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200794 if (alertif_too_many_args(0, file, linenum, args, &err_code))
795 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200796 global.tune.options &= ~GTUNE_USE_GAI;
797 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000798 else if (!strcmp(args[0], "noreuseport")) {
799 if (alertif_too_many_args(0, file, linenum, args, &err_code))
800 goto out;
801 global.tune.options &= ~GTUNE_USE_REUSEPORT;
802 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200803 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200804 if (alertif_too_many_args(0, file, linenum, args, &err_code))
805 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200806 global.mode |= MODE_QUIET;
807 }
Olivier Houchard1599b802018-05-24 18:59:04 +0200808 else if (!strcmp(args[0], "tune.runqueue-depth")) {
809 if (alertif_too_many_args(1, file, linenum, args, &err_code))
810 goto out;
811 if (global.tune.runqueue_depth != 0) {
812 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
813 err_code |= ERR_ALERT;
814 goto out;
815 }
816 if (*(args[1]) == 0) {
817 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
818 err_code |= ERR_ALERT | ERR_FATAL;
819 goto out;
820 }
821 global.tune.runqueue_depth = atol(args[1]);
822
823 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200824 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200825 if (alertif_too_many_args(1, file, linenum, args, &err_code))
826 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200827 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100828 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200829 err_code |= ERR_ALERT;
830 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200831 }
832 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100833 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200834 err_code |= ERR_ALERT | ERR_FATAL;
835 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200836 }
837 global.tune.maxpollevents = atol(args[1]);
838 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100839 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200840 if (alertif_too_many_args(1, file, linenum, args, &err_code))
841 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100842 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100843 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200844 err_code |= ERR_ALERT;
845 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100846 }
847 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100848 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200849 err_code |= ERR_ALERT | ERR_FATAL;
850 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100851 }
852 global.tune.maxaccept = atol(args[1]);
853 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200854 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200855 if (alertif_too_many_args(1, file, linenum, args, &err_code))
856 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200857 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100858 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200859 err_code |= ERR_ALERT | ERR_FATAL;
860 goto out;
861 }
862 global.tune.chksize = atol(args[1]);
863 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100864 else if (!strcmp(args[0], "tune.recv_enough")) {
865 if (alertif_too_many_args(1, file, linenum, args, &err_code))
866 goto out;
867 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100868 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100869 err_code |= ERR_ALERT | ERR_FATAL;
870 goto out;
871 }
872 global.tune.recv_enough = atol(args[1]);
873 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100874 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200875 if (alertif_too_many_args(1, file, linenum, args, &err_code))
876 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100877 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100878 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100879 err_code |= ERR_ALERT | ERR_FATAL;
880 goto out;
881 }
882 global.tune.buf_limit = atol(args[1]);
883 if (global.tune.buf_limit) {
884 if (global.tune.buf_limit < 3)
885 global.tune.buf_limit = 3;
886 if (global.tune.buf_limit <= global.tune.reserved_bufs)
887 global.tune.buf_limit = global.tune.reserved_bufs + 1;
888 }
889 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100890 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200891 if (alertif_too_many_args(1, file, linenum, args, &err_code))
892 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100893 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100894 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100895 err_code |= ERR_ALERT | ERR_FATAL;
896 goto out;
897 }
898 global.tune.reserved_bufs = atol(args[1]);
899 if (global.tune.reserved_bufs < 2)
900 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100901 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
902 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100903 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200904 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200905 if (alertif_too_many_args(1, file, linenum, args, &err_code))
906 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200907 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100908 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200909 err_code |= ERR_ALERT | ERR_FATAL;
910 goto out;
911 }
912 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200913 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100914 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200915 err_code |= ERR_ALERT | ERR_FATAL;
916 goto out;
917 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200918 }
919 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200920 if (alertif_too_many_args(1, file, linenum, args, &err_code))
921 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200922 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100923 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200924 err_code |= ERR_ALERT | ERR_FATAL;
925 goto out;
926 }
927 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200928 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100929 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200930 err_code |= ERR_ALERT | ERR_FATAL;
931 goto out;
932 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200933 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100934 else if (!strcmp(args[0], "tune.idletimer")) {
935 unsigned int idle;
936 const char *res;
937
William Lallemand1a748ae2015-05-19 16:37:23 +0200938 if (alertif_too_many_args(1, file, linenum, args, &err_code))
939 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100940 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100941 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100942 err_code |= ERR_ALERT | ERR_FATAL;
943 goto out;
944 }
945
946 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
947 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100948 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100949 file, linenum, *res, args[0]);
950 err_code |= ERR_ALERT | ERR_FATAL;
951 goto out;
952 }
953
954 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100955 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100956 err_code |= ERR_ALERT | ERR_FATAL;
957 goto out;
958 }
959 global.tune.idle_timer = idle;
960 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100961 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200962 if (alertif_too_many_args(1, file, linenum, args, &err_code))
963 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100964 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100965 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100966 err_code |= ERR_ALERT;
967 goto out;
968 }
969 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100970 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100971 err_code |= ERR_ALERT | ERR_FATAL;
972 goto out;
973 }
974 global.tune.client_rcvbuf = atol(args[1]);
975 }
976 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200977 if (alertif_too_many_args(1, file, linenum, args, &err_code))
978 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100979 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100980 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100981 err_code |= ERR_ALERT;
982 goto out;
983 }
984 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100985 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100986 err_code |= ERR_ALERT | ERR_FATAL;
987 goto out;
988 }
989 global.tune.server_rcvbuf = atol(args[1]);
990 }
991 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200992 if (alertif_too_many_args(1, file, linenum, args, &err_code))
993 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100994 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100995 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100996 err_code |= ERR_ALERT;
997 goto out;
998 }
999 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001000 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001001 err_code |= ERR_ALERT | ERR_FATAL;
1002 goto out;
1003 }
1004 global.tune.client_sndbuf = atol(args[1]);
1005 }
1006 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001007 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1008 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +01001009 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001010 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001011 err_code |= ERR_ALERT;
1012 goto out;
1013 }
1014 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001015 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001016 err_code |= ERR_ALERT | ERR_FATAL;
1017 goto out;
1018 }
1019 global.tune.server_sndbuf = atol(args[1]);
1020 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001021 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001022 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1023 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001024 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001025 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001026 err_code |= ERR_ALERT | ERR_FATAL;
1027 goto out;
1028 }
1029 global.tune.pipesize = atol(args[1]);
1030 }
Willy Tarreau193b8c62012-11-22 00:17:38 +01001031 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001032 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1033 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001034 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001035 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001036 err_code |= ERR_ALERT | ERR_FATAL;
1037 goto out;
1038 }
1039 global.tune.cookie_len = atol(args[1]) + 1;
1040 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001041 else if (!strcmp(args[0], "tune.http.logurilen")) {
1042 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1043 goto out;
1044 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001045 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001046 err_code |= ERR_ALERT | ERR_FATAL;
1047 goto out;
1048 }
1049 global.tune.requri_len = atol(args[1]) + 1;
1050 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001051 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001052 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1053 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001054 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001055 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001056 err_code |= ERR_ALERT | ERR_FATAL;
1057 goto out;
1058 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001059 global.tune.max_http_hdr = atoi(args[1]);
1060 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001061 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1062 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001063 err_code |= ERR_ALERT | ERR_FATAL;
1064 goto out;
1065 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001066 }
William Lallemandf3747832012-11-09 12:33:10 +01001067 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001068 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1069 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001070 if (*args[1]) {
1071 global.tune.comp_maxlevel = atoi(args[1]);
1072 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001073 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1074 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001075 err_code |= ERR_ALERT | ERR_FATAL;
1076 goto out;
1077 }
1078 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001079 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1080 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001081 err_code |= ERR_ALERT | ERR_FATAL;
1082 goto out;
1083 }
1084 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001085 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1086 if (*args[1]) {
1087 global.tune.pattern_cache = atoi(args[1]);
1088 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001089 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1090 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001091 err_code |= ERR_ALERT | ERR_FATAL;
1092 goto out;
1093 }
1094 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001095 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1096 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001097 err_code |= ERR_ALERT | ERR_FATAL;
1098 goto out;
1099 }
1100 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001101 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001102 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1103 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001104 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001105 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001106 err_code |= ERR_ALERT;
1107 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001108 }
1109 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001110 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001111 err_code |= ERR_ALERT | ERR_FATAL;
1112 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001113 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001114 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001115 ha_warning("parsing [%s:%d] : uid: string '%s' is not a number.\n | You might want to use the 'user' parameter to use a system user name.\n", file, linenum, args[1]);
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001116 err_code |= ERR_WARN;
1117 goto out;
1118 }
1119
Willy Tarreaubaaee002006-06-26 02:48:02 +02001120 }
1121 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001122 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1123 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001124 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001125 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001126 err_code |= ERR_ALERT;
1127 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001128 }
1129 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001130 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001131 err_code |= ERR_ALERT | ERR_FATAL;
1132 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001133 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001134 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001135 ha_warning("parsing [%s:%d] : gid: string '%s' is not a number.\n | You might want to use the 'group' parameter to use a system group name.\n", file, linenum, args[1]);
Baptiste Assmann776e5182016-03-11 17:21:15 +01001136 err_code |= ERR_WARN;
1137 goto out;
1138 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001139 }
Simon Horman98637e52014-06-20 12:30:16 +09001140 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001141 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1142 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001143 global.external_check = 1;
1144 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001145 /* user/group name handling */
1146 else if (!strcmp(args[0], "user")) {
1147 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001148 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1149 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001150 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001151 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001152 err_code |= ERR_ALERT;
1153 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001154 }
1155 errno = 0;
1156 ha_user = getpwnam(args[1]);
1157 if (ha_user != NULL) {
1158 global.uid = (int)ha_user->pw_uid;
1159 }
1160 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001161 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001162 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001163 }
1164 }
1165 else if (!strcmp(args[0], "group")) {
1166 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001167 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1168 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001169 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001170 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001171 err_code |= ERR_ALERT;
1172 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001173 }
1174 errno = 0;
1175 ha_group = getgrnam(args[1]);
1176 if (ha_group != NULL) {
1177 global.gid = (int)ha_group->gr_gid;
1178 }
1179 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001180 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001181 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001182 }
1183 }
1184 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001185 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001186 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1187 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001188 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001189 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001190 err_code |= ERR_ALERT | ERR_FATAL;
1191 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001192 }
1193 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001194 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001195 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1196 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001197 err_code |= ERR_ALERT | ERR_FATAL;
1198 goto out;
1199 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001200 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001201 else if (!strcmp(args[0], "nbthread")) {
1202 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1203 goto out;
1204 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001205 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001206 err_code |= ERR_ALERT | ERR_FATAL;
1207 goto out;
1208 }
Willy Tarreau0ccd3222018-07-30 10:34:35 +02001209 global.nbthread = parse_nbthread(args[1], &errmsg);
1210 if (!global.nbthread) {
1211 ha_alert("parsing [%s:%d] : '%s' %s.\n",
1212 file, linenum, args[0], errmsg);
Willy Tarreau421f02e2018-01-20 18:19:22 +01001213 err_code |= ERR_ALERT | ERR_FATAL;
1214 goto out;
1215 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001216 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001217 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001218 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1219 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001220 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001221 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001222 err_code |= ERR_ALERT;
1223 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001224 }
1225 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001226 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001227 err_code |= ERR_ALERT | ERR_FATAL;
1228 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001229 }
1230 global.maxconn = atol(args[1]);
1231#ifdef SYSTEM_MAXCONN
1232 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001233 ha_alert("parsing [%s:%d] : maxconn value %d too high for this system.\nLimiting to %d. Please use '-n' to force the value.\n", file, linenum, global.maxconn, DEFAULT_MAXCONN);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001234 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001235 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001236 }
1237#endif /* SYSTEM_MAXCONN */
1238 }
Emeric Brun850efd52014-01-29 12:24:34 +01001239 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001240 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1241 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001242 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001243 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001244 err_code |= ERR_ALERT | ERR_FATAL;
1245 goto out;
1246 }
1247 if (strcmp(args[1],"none") == 0)
1248 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1249 else if (strcmp(args[1],"required") == 0)
1250 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1251 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001252 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001253 err_code |= ERR_ALERT | ERR_FATAL;
1254 goto out;
1255 }
1256 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001257 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001258 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1259 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001260 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001261 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001262 err_code |= ERR_ALERT;
1263 goto out;
1264 }
1265 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001266 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001267 err_code |= ERR_ALERT | ERR_FATAL;
1268 goto out;
1269 }
1270 global.cps_lim = atol(args[1]);
1271 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001272 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001273 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1274 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001275 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001276 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001277 err_code |= ERR_ALERT;
1278 goto out;
1279 }
1280 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001281 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001282 err_code |= ERR_ALERT | ERR_FATAL;
1283 goto out;
1284 }
1285 global.sps_lim = atol(args[1]);
1286 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001287 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001288 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1289 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001290 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001291 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001292 err_code |= ERR_ALERT;
1293 goto out;
1294 }
1295 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001296 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001297 err_code |= ERR_ALERT | ERR_FATAL;
1298 goto out;
1299 }
1300 global.ssl_lim = atol(args[1]);
1301 }
William Lallemandd85f9172012-11-09 17:05:39 +01001302 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001303 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1304 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001305 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001306 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
William Lallemandd85f9172012-11-09 17:05:39 +01001307 err_code |= ERR_ALERT | ERR_FATAL;
1308 goto out;
1309 }
1310 global.comp_rate_lim = atoi(args[1]) * 1024;
1311 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001312 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001313 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1314 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001315 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001316 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001317 err_code |= ERR_ALERT;
1318 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001319 }
1320 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001321 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001322 err_code |= ERR_ALERT | ERR_FATAL;
1323 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001324 }
1325 global.maxpipes = atol(args[1]);
1326 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001327 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001328 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1329 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001330 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001331 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001332 err_code |= ERR_ALERT | ERR_FATAL;
1333 goto out;
1334 }
William Lallemande3a7d992012-11-20 11:25:20 +01001335 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001336 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001337 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001338 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1339 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001340 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001341 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
William Lallemand072a2bf2012-11-20 17:01:01 +01001342 err_code |= ERR_ALERT | ERR_FATAL;
1343 goto out;
1344 }
1345 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001346 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001347 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
William Lallemand072a2bf2012-11-20 17:01:01 +01001348 err_code |= ERR_ALERT | ERR_FATAL;
1349 goto out;
1350 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001351 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001352
Willy Tarreaubaaee002006-06-26 02:48:02 +02001353 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001354 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1355 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001356 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001357 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001358 err_code |= ERR_ALERT;
1359 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001360 }
1361 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001362 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001363 err_code |= ERR_ALERT | ERR_FATAL;
1364 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001365 }
1366 global.rlimit_nofile = atol(args[1]);
1367 }
1368 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001369 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1370 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001371 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001372 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001373 err_code |= ERR_ALERT;
1374 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001375 }
1376 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001377 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001378 err_code |= ERR_ALERT | ERR_FATAL;
1379 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001380 }
1381 global.chroot = strdup(args[1]);
1382 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001383 else if (!strcmp(args[0], "description")) {
1384 int i, len=0;
1385 char *d;
1386
1387 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001388 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1389 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001390 err_code |= ERR_ALERT | ERR_FATAL;
1391 goto out;
1392 }
1393
Willy Tarreau348acfe2014-04-14 15:00:39 +02001394 for (i = 1; *args[i]; i++)
1395 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001396
1397 if (global.desc)
1398 free(global.desc);
1399
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001400 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001401
Willy Tarreau348acfe2014-04-14 15:00:39 +02001402 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1403 for (i = 2; *args[i]; i++)
1404 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001405 }
1406 else if (!strcmp(args[0], "node")) {
1407 int i;
1408 char c;
1409
William Lallemand1a748ae2015-05-19 16:37:23 +02001410 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1411 goto out;
1412
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001413 for (i=0; args[1][i]; i++) {
1414 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001415 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1416 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001417 break;
1418 }
1419
1420 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001421 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1422 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1423 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001424 err_code |= ERR_ALERT | ERR_FATAL;
1425 goto out;
1426 }
1427
1428 if (global.node)
1429 free(global.node);
1430
1431 global.node = strdup(args[1]);
1432 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001433 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001434 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1435 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001436 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001437 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001438 err_code |= ERR_ALERT;
1439 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001440 }
1441 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001442 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001443 err_code |= ERR_ALERT | ERR_FATAL;
1444 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001445 }
1446 global.pidfile = strdup(args[1]);
1447 }
Emeric Bruned760922010-10-22 17:59:25 +02001448 else if (!strcmp(args[0], "unix-bind")) {
1449 int cur_arg = 1;
1450 while (*(args[cur_arg])) {
1451 if (!strcmp(args[cur_arg], "prefix")) {
1452 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001453 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001454 err_code |= ERR_ALERT;
1455 cur_arg += 2;
1456 continue;
1457 }
1458
1459 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001460 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001461 err_code |= ERR_ALERT | ERR_FATAL;
1462 goto out;
1463 }
1464 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1465 cur_arg += 2;
1466 continue;
1467 }
1468
1469 if (!strcmp(args[cur_arg], "mode")) {
1470
1471 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1472 cur_arg += 2;
1473 continue;
1474 }
1475
1476 if (!strcmp(args[cur_arg], "uid")) {
1477
1478 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1479 cur_arg += 2;
1480 continue;
1481 }
1482
1483 if (!strcmp(args[cur_arg], "gid")) {
1484
1485 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1486 cur_arg += 2;
1487 continue;
1488 }
1489
1490 if (!strcmp(args[cur_arg], "user")) {
1491 struct passwd *user;
1492
1493 user = getpwnam(args[cur_arg + 1]);
1494 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001495 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1496 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001497 err_code |= ERR_ALERT | ERR_FATAL;
1498 goto out;
1499 }
1500
1501 global.unix_bind.ux.uid = user->pw_uid;
1502 cur_arg += 2;
1503 continue;
1504 }
1505
1506 if (!strcmp(args[cur_arg], "group")) {
1507 struct group *group;
1508
1509 group = getgrnam(args[cur_arg + 1]);
1510 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001511 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1512 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001513 err_code |= ERR_ALERT | ERR_FATAL;
1514 goto out;
1515 }
1516
1517 global.unix_bind.ux.gid = group->gr_gid;
1518 cur_arg += 2;
1519 continue;
1520 }
1521
Christopher Faulet767a84b2017-11-24 16:50:31 +01001522 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1523 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001524 err_code |= ERR_ALERT | ERR_FATAL;
1525 goto out;
1526 }
1527 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001528 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1529 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1530 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001531 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001532 goto out;
1533 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001534 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001535 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1536 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001537
1538 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001539 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001540 err_code |= ERR_ALERT;
1541 goto out;
1542 }
1543
1544 if (*(args[1]))
1545 name = args[1];
1546 else
1547 name = hostname;
1548
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001549 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001550 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001551 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001552 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1553 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001554 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001555 err_code |= ERR_ALERT;
1556 goto out;
1557 }
1558
1559 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001560 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001561 err_code |= ERR_FATAL;
1562 goto out;
1563 }
1564
1565 global.server_state_base = strdup(args[1]);
1566 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001567 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1568 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001569 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001570 err_code |= ERR_ALERT;
1571 goto out;
1572 }
1573
1574 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001575 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001576 err_code |= ERR_FATAL;
1577 goto out;
1578 }
1579
1580 global.server_state_file = strdup(args[1]);
1581 }
Kevinm48936af2010-12-22 16:08:21 +00001582 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001583 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1584 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001585 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001586 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001587 err_code |= ERR_ALERT | ERR_FATAL;
1588 goto out;
1589 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001590 chunk_destroy(&global.log_tag);
1591 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001592 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001593 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001594 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1595 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001596 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001597 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001598 err_code |= ERR_ALERT;
1599 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001600 }
1601 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001602 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001603 err_code |= ERR_ALERT | ERR_FATAL;
1604 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001605 }
1606 global.spread_checks = atol(args[1]);
1607 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001608 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001609 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001610 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001611 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001612 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1613 const char *err;
1614 unsigned int val;
1615
William Lallemand1a748ae2015-05-19 16:37:23 +02001616 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1617 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001618 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001619 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001620 err_code |= ERR_ALERT | ERR_FATAL;
1621 goto out;
1622 }
1623
1624 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1625 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001626 ha_alert("parsing [%s:%d]: unsupported character '%c' in '%s' (wants an integer delay).\n", file, linenum, *err, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001627 err_code |= ERR_ALERT | ERR_FATAL;
1628 }
1629 global.max_spread_checks = val;
1630 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001631 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001632 err_code |= ERR_ALERT | ERR_FATAL;
1633 }
1634 }
Christopher Faulet62519022017-10-16 15:49:32 +02001635 else if (strcmp(args[0], "cpu-map") == 0) {
1636 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001637#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001638 char *slash;
1639 unsigned long proc = 0, thread = 0, cpus;
1640 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001641
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001642 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001643 ha_alert("parsing [%s:%d] : %s expects a process number "
1644 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1645 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1646 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001647 err_code |= ERR_ALERT | ERR_FATAL;
1648 goto out;
1649 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001650
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001651 if ((slash = strchr(args[1], '/')) != NULL)
1652 *slash = 0;
1653
Christopher Faulet26028f62017-11-22 15:01:51 +01001654 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001655 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001656 err_code |= ERR_ALERT | ERR_FATAL;
1657 goto out;
1658 }
1659
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001660 if (slash) {
1661 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001662 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001663 err_code |= ERR_ALERT | ERR_FATAL;
1664 goto out;
1665 }
1666 *slash = '/';
1667
Willy Tarreau9504dd62018-10-15 09:37:03 +02001668 if (autoinc && atleast2(proc) && atleast2(thread)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001669 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1670 "a process range _AND_ a thread range\n",
1671 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001672 err_code |= ERR_ALERT | ERR_FATAL;
1673 goto out;
1674 }
1675 }
1676
Christopher Faulet62519022017-10-16 15:49:32 +02001677 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001678 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001679 err_code |= ERR_ALERT | ERR_FATAL;
1680 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001681 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001682
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001683 if (autoinc &&
1684 my_popcountl(proc) != my_popcountl(cpus) &&
1685 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001686 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1687 "must have the same size to be automatically bound\n",
1688 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001689 err_code |= ERR_ALERT | ERR_FATAL;
1690 goto out;
1691 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001692
Christopher Faulet26028f62017-11-22 15:01:51 +01001693 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001694 /* No mapping for this process */
1695 if (!(proc & (1UL << i)))
1696 continue;
1697
1698 /* Mapping at the process level */
1699 if (!thread) {
1700 if (!autoinc)
1701 global.cpu_map.proc[i] = cpus;
1702 else {
1703 n += my_ffsl(cpus >> n);
1704 global.cpu_map.proc[i] = (1UL << (n-1));
1705 }
1706 continue;
1707 }
1708
1709 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001710 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001711 /* Np mapping for this thread */
1712 if (!(thread & (1UL << j)))
1713 continue;
1714
1715 if (!autoinc)
1716 global.cpu_map.thread[i][j] = cpus;
1717 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001718 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001719 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001720 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001721 }
1722 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001723#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001724 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1725 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001726 err_code |= ERR_ALERT | ERR_FATAL;
1727 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001728#endif /* ! USE_CPU_AFFINITY */
1729 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001730 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1731 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1732 goto out;
1733
1734 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001735 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001736 err_code |= ERR_ALERT | ERR_FATAL;
1737 goto out;
1738 }
1739
1740 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1741 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001742 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
Willy Tarreau1d549722016-02-16 12:41:57 +01001743 err_code |= ERR_ALERT | ERR_FATAL;
1744 goto out;
1745 }
1746 }
1747 else if (!strcmp(args[0], "unsetenv")) {
1748 int arg;
1749
1750 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001751 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001752 err_code |= ERR_ALERT | ERR_FATAL;
1753 goto out;
1754 }
1755
1756 for (arg = 1; *args[arg]; arg++) {
1757 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001758 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
Willy Tarreau1d549722016-02-16 12:41:57 +01001759 err_code |= ERR_ALERT | ERR_FATAL;
1760 goto out;
1761 }
1762 }
1763 }
1764 else if (!strcmp(args[0], "resetenv")) {
1765 extern char **environ;
1766 char **env = environ;
1767
1768 /* args contain variable names to keep, one per argument */
1769 while (*env) {
1770 int arg;
1771
1772 /* look for current variable in among all those we want to keep */
1773 for (arg = 1; *args[arg]; arg++) {
1774 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1775 (*env)[strlen(args[arg])] == '=')
1776 break;
1777 }
1778
1779 /* delete this variable */
1780 if (!*args[arg]) {
1781 char *delim = strchr(*env, '=');
1782
1783 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001784 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
Willy Tarreau1d549722016-02-16 12:41:57 +01001785 err_code |= ERR_ALERT | ERR_FATAL;
1786 goto out;
1787 }
1788
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001789 memcpy(trash.area, *env, delim - *env);
1790 trash.area[delim - *env] = 0;
Willy Tarreau1d549722016-02-16 12:41:57 +01001791
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001792 if (unsetenv(trash.area) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001793 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
Willy Tarreau1d549722016-02-16 12:41:57 +01001794 err_code |= ERR_ALERT | ERR_FATAL;
1795 goto out;
1796 }
1797 }
1798 else
1799 env++;
1800 }
1801 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001802 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001803 struct cfg_kw_list *kwl;
1804 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001805 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001806
1807 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1808 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1809 if (kwl->kw[index].section != CFG_GLOBAL)
1810 continue;
1811 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001812 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001813 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001814 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001815 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001816 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001817 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001818 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001819 err_code |= ERR_WARN;
1820 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001821 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001822 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001823 }
1824 }
1825 }
1826
Christopher Faulet767a84b2017-11-24 16:50:31 +01001827 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001828 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001829 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001830
Willy Tarreau058e9072009-07-20 09:30:05 +02001831 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001832 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001833 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001834}
1835
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001836void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001837{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001838 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001839 defproxy.mode = PR_MODE_TCP;
1840 defproxy.state = PR_STNEW;
1841 defproxy.maxconn = cfg_maxpconn;
1842 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001843 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001844 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001845
Simon Horman66183002013-02-23 10:16:43 +09001846 defproxy.defsrv.check.inter = DEF_CHKINTR;
1847 defproxy.defsrv.check.fastinter = 0;
1848 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001849 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1850 defproxy.defsrv.agent.fastinter = 0;
1851 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001852 defproxy.defsrv.check.rise = DEF_RISETIME;
1853 defproxy.defsrv.check.fall = DEF_FALLTIME;
1854 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1855 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001856 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001857 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001858 defproxy.defsrv.maxqueue = 0;
1859 defproxy.defsrv.minconn = 0;
1860 defproxy.defsrv.maxconn = 0;
1861 defproxy.defsrv.slowstart = 0;
1862 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1863 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1864 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001865
1866 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001867 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001868}
1869
Willy Tarreauade5ec42010-01-28 19:33:49 +01001870
Willy Tarreau63af98d2014-05-18 08:11:41 +02001871/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1872 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1873 * ERR_FATAL in case of error.
1874 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001875static int create_cond_regex_rule(const char *file, int line,
1876 struct proxy *px, int dir, int action, int flags,
1877 const char *cmd, const char *reg, const char *repl,
1878 const char **cond_start)
1879{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001880 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001881 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001882 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001883 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001884 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001885 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001886 int cs;
1887 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001888
1889 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001890 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001891 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001892 goto err;
1893 }
1894
1895 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001896 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001897 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001898 goto err;
1899 }
1900
Christopher Faulet898566e2016-10-26 11:06:28 +02001901 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001902 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001903
Willy Tarreau5321c422010-01-28 20:35:13 +01001904 if (cond_start &&
1905 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001906 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001907 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1908 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001909 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001910 goto err;
1911 }
1912 }
1913 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001914 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1915 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001916 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001917 goto err;
1918 }
1919
Willy Tarreau63af98d2014-05-18 08:11:41 +02001920 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001921 (dir == SMP_OPT_DIR_REQ) ?
1922 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1923 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1924 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001925
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001926 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001927 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001928 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001929 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001930 goto err;
1931 }
1932
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001933 cs = !(flags & REG_ICASE);
1934 cap = !(flags & REG_NOSUB);
1935 error = NULL;
1936 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001937 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001938 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001939 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001940 goto err;
1941 }
1942
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001943 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001944 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001945 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001946 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1947 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001948 ret_code |= ERR_ALERT | ERR_FATAL;
1949 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001950 }
1951
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001952 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001953 ret_code |= ERR_WARN;
1954
1955 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001956
Willy Tarreau63af98d2014-05-18 08:11:41 +02001957 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001958 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001959 err:
1960 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001961 free(errmsg);
1962 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001963}
1964
Willy Tarreaubaaee002006-06-26 02:48:02 +02001965/*
William Lallemand51097192015-04-14 16:35:22 +02001966 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001967 * Returns the error code, 0 if OK, or any combination of :
1968 * - ERR_ABORT: must abort ASAP
1969 * - ERR_FATAL: we can continue parsing but not start the service
1970 * - ERR_WARN: a warning has been emitted
1971 * - ERR_ALERT: an alert has been emitted
1972 * Only the two first ones can stop processing, the two others are just
1973 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001974 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001975int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1976{
1977 static struct peers *curpeers = NULL;
1978 struct peer *newpeer = NULL;
1979 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001980 struct bind_conf *bind_conf;
1981 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001982 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001983 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001984
1985 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001986 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001987 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001988 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001989 goto out;
1990 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001991
William Lallemand6e62fb62015-04-28 16:55:23 +02001992 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1993 goto out;
1994
Emeric Brun32da3c42010-09-23 18:39:19 +02001995 err = invalid_char(args[1]);
1996 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001997 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1998 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001999 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002000 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002001 }
2002
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002003 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02002004 /*
2005 * If there are two proxies with the same name only following
2006 * combinations are allowed:
2007 */
2008 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002009 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2010 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002011 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002012 }
2013 }
2014
Vincent Bernat02779b62016-04-03 13:48:43 +02002015 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002016 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002017 err_code |= ERR_ALERT | ERR_ABORT;
2018 goto out;
2019 }
2020
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002021 curpeers->next = cfg_peers;
2022 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002023 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002024 curpeers->conf.line = linenum;
2025 curpeers->last_change = now.tv_sec;
2026 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002027 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002028 }
2029 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002030 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002031 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002032 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002033
2034 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002035 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2036 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002037 err_code |= ERR_ALERT | ERR_FATAL;
2038 goto out;
2039 }
2040
2041 err = invalid_char(args[1]);
2042 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002043 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2044 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002045 err_code |= ERR_ALERT | ERR_FATAL;
2046 goto out;
2047 }
2048
Vincent Bernat02779b62016-04-03 13:48:43 +02002049 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002050 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002051 err_code |= ERR_ALERT | ERR_ABORT;
2052 goto out;
2053 }
2054
2055 /* the peers are linked backwards first */
2056 curpeers->count++;
2057 newpeer->next = curpeers->remote;
2058 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002059 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002060 newpeer->conf.line = linenum;
2061
2062 newpeer->last_change = now.tv_sec;
2063 newpeer->id = strdup(args[1]);
2064
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002065 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002066 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002067 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002068 err_code |= ERR_ALERT | ERR_FATAL;
2069 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002070 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002071
2072 proto = protocol_by_family(sk->ss_family);
2073 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002074 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2075 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002076 err_code |= ERR_ALERT | ERR_FATAL;
2077 goto out;
2078 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002079
2080 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002081 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2082 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002083 err_code |= ERR_ALERT | ERR_FATAL;
2084 goto out;
2085 }
2086
Willy Tarreau2aa38802013-02-20 19:20:59 +01002087 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002088 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2089 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002090 err_code |= ERR_ALERT | ERR_FATAL;
2091 goto out;
2092 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002093
Emeric Brun32da3c42010-09-23 18:39:19 +02002094 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002095 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002096 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002097 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002098 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002099
Emeric Brun32da3c42010-09-23 18:39:19 +02002100 if (strcmp(newpeer->id, localpeer) == 0) {
2101 /* Current is local peer, it define a frontend */
2102 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002103 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002104
2105 if (!curpeers->peers_fe) {
2106 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002107 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002108 err_code |= ERR_ALERT | ERR_ABORT;
2109 goto out;
2110 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002111
Willy Tarreau237250c2011-07-29 01:49:03 +02002112 init_new_proxy(curpeers->peers_fe);
2113 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002114 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002115 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2116 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002117 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002118
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002119 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002120
Willy Tarreau902636f2013-03-10 19:44:48 +01002121 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2122 if (errmsg && *errmsg) {
2123 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002124 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002125 }
2126 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002127 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2128 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002129 err_code |= ERR_FATAL;
2130 goto out;
2131 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002132
2133 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002134 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002135 l->maxconn = curpeers->peers_fe->maxconn;
2136 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002137 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002138 l->analysers |= curpeers->peers_fe->fe_req_ana;
2139 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002140 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2141 global.maxsock += l->maxconn;
2142 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002143 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002144 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002145 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2146 file, linenum, args[0], args[1],
2147 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002148 err_code |= ERR_FATAL;
2149 goto out;
2150 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002151 }
2152 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002153 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2154 curpeers->state = PR_STSTOPPED;
2155 }
2156 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2157 curpeers->state = PR_STNEW;
2158 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002159 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002160 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002161 err_code |= ERR_ALERT | ERR_FATAL;
2162 goto out;
2163 }
2164
2165out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002166 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002167 return err_code;
2168}
2169
Baptiste Assmann325137d2015-04-13 23:40:55 +02002170/*
2171 * Parse a <resolvers> section.
2172 * Returns the error code, 0 if OK, or any combination of :
2173 * - ERR_ABORT: must abort ASAP
2174 * - ERR_FATAL: we can continue parsing but not start the service
2175 * - ERR_WARN: a warning has been emitted
2176 * - ERR_ALERT: an alert has been emitted
2177 * Only the two first ones can stop processing, the two others are just
2178 * indicators.
2179 */
2180int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2181{
2182 static struct dns_resolvers *curr_resolvers = NULL;
2183 struct dns_nameserver *newnameserver = NULL;
2184 const char *err;
2185 int err_code = 0;
2186 char *errmsg = NULL;
2187
2188 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2189 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002190 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002191 err_code |= ERR_ALERT | ERR_ABORT;
2192 goto out;
2193 }
2194
2195 err = invalid_char(args[1]);
2196 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002197 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2198 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002199 err_code |= ERR_ALERT | ERR_ABORT;
2200 goto out;
2201 }
2202
2203 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2204 /* Error if two resolvers owns the same name */
2205 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002206 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2207 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002208 err_code |= ERR_ALERT | ERR_ABORT;
2209 }
2210 }
2211
Vincent Bernat02779b62016-04-03 13:48:43 +02002212 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002213 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002214 err_code |= ERR_ALERT | ERR_ABORT;
2215 goto out;
2216 }
2217
2218 /* default values */
2219 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2220 curr_resolvers->conf.file = strdup(file);
2221 curr_resolvers->conf.line = linenum;
2222 curr_resolvers->id = strdup(args[1]);
2223 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002224 /* default maximum response size */
2225 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002226 /* default hold period for nx, other, refuse and timeout is 30s */
2227 curr_resolvers->hold.nx = 30000;
2228 curr_resolvers->hold.other = 30000;
2229 curr_resolvers->hold.refused = 30000;
2230 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002231 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002232 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002233 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002234 curr_resolvers->timeout.resolve = 1000;
2235 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002236 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002237 curr_resolvers->nb_nameservers = 0;
2238 LIST_INIT(&curr_resolvers->nameservers);
2239 LIST_INIT(&curr_resolvers->resolutions.curr);
2240 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002241 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002242 }
2243 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2244 struct sockaddr_storage *sk;
2245 int port1, port2;
2246 struct protocol *proto;
2247
2248 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002249 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2250 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002251 err_code |= ERR_ALERT | ERR_FATAL;
2252 goto out;
2253 }
2254
2255 err = invalid_char(args[1]);
2256 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002257 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2258 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002259 err_code |= ERR_ALERT | ERR_FATAL;
2260 goto out;
2261 }
2262
Christopher Faulet67957bd2017-09-27 11:00:59 +02002263 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002264 /* Error if two resolvers owns the same name */
2265 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002266 ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
Ben Draut44e609b2018-05-29 15:40:08 -06002267 file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002268 err_code |= ERR_ALERT | ERR_FATAL;
2269 }
2270 }
2271
Vincent Bernat02779b62016-04-03 13:48:43 +02002272 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002273 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002274 err_code |= ERR_ALERT | ERR_ABORT;
2275 goto out;
2276 }
2277
2278 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002279 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002280 newnameserver->resolvers = curr_resolvers;
2281 newnameserver->conf.file = strdup(file);
2282 newnameserver->conf.line = linenum;
2283 newnameserver->id = strdup(args[1]);
2284
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002285 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002286 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002287 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002288 err_code |= ERR_ALERT | ERR_FATAL;
2289 goto out;
2290 }
2291
2292 proto = protocol_by_family(sk->ss_family);
2293 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002294 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002295 file, linenum, args[0], args[1]);
2296 err_code |= ERR_ALERT | ERR_FATAL;
2297 goto out;
2298 }
2299
2300 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002301 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2302 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002303 err_code |= ERR_ALERT | ERR_FATAL;
2304 goto out;
2305 }
2306
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002307 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002308 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2309 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002310 err_code |= ERR_ALERT | ERR_FATAL;
2311 goto out;
2312 }
2313
Baptiste Assmann325137d2015-04-13 23:40:55 +02002314 newnameserver->addr = *sk;
2315 }
Ben Draut44e609b2018-05-29 15:40:08 -06002316 else if (strcmp(args[0], "parse-resolv-conf") == 0) {
2317 const char *whitespace = "\r\n\t ";
2318 char *resolv_line = NULL;
2319 int resolv_linenum = 0;
2320 FILE *f = NULL;
2321 char *address = NULL;
2322 struct sockaddr_storage *sk = NULL;
2323 struct protocol *proto;
2324 int duplicate_name = 0;
2325
2326 if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
2327 ha_alert("parsing [%s:%d] : out of memory.\n",
2328 file, linenum);
2329 err_code |= ERR_ALERT | ERR_FATAL;
2330 goto resolv_out;
2331 }
2332
2333 if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
2334 ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n",
2335 file, linenum);
2336 err_code |= ERR_ALERT | ERR_FATAL;
2337 goto resolv_out;
2338 }
2339
2340 sk = calloc(1, sizeof(*sk));
2341 if (sk == NULL) {
2342 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n",
2343 resolv_linenum);
2344 err_code |= ERR_ALERT | ERR_FATAL;
2345 goto resolv_out;
2346 }
2347
2348 while (fgets(resolv_line, LINESIZE, f) != NULL) {
2349 resolv_linenum++;
2350 if (strncmp(resolv_line, "nameserver", 10) != 0)
2351 continue;
2352
2353 address = strtok(resolv_line + 10, whitespace);
2354 if (address == resolv_line + 10)
2355 continue;
2356
2357 if (address == NULL) {
2358 ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
2359 resolv_linenum);
2360 err_code |= ERR_WARN;
2361 continue;
2362 }
2363
2364 duplicate_name = 0;
2365 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
2366 if (strcmp(newnameserver->id, address) == 0) {
2367 ha_warning("Parsing [/etc/resolv.conf:%d] : generated name for /etc/resolv.conf nameserver '%s' conflicts with another nameserver (declared at %s:%d), it appears to be a duplicate and will be excluded.\n",
2368 resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line);
2369 err_code |= ERR_WARN;
2370 duplicate_name = 1;
2371 }
2372 }
2373
2374 if (duplicate_name)
2375 continue;
2376
2377 memset(sk, 0, sizeof(*sk));
2378 sk = str2ip2(address, sk, 1);
2379 if (!sk) {
2380 ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, namerserver will be excluded.\n",
2381 resolv_linenum, address);
2382 err_code |= ERR_WARN;
2383 continue;
2384 }
2385
2386 set_host_port(sk, 53);
2387
2388 proto = protocol_by_family(sk->ss_family);
2389 if (!proto || !proto->connect) {
2390 ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
2391 resolv_linenum, address);
2392 err_code |= ERR_WARN;
2393 continue;
2394 }
2395
2396 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
2397 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2398 err_code |= ERR_ALERT | ERR_FATAL;
2399 goto resolv_out;
2400 }
2401
2402 newnameserver->conf.file = strdup("/etc/resolv.conf");
2403 if (newnameserver->conf.file == NULL) {
2404 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2405 err_code |= ERR_ALERT | ERR_FATAL;
2406 goto resolv_out;
2407 }
2408
2409 newnameserver->id = strdup(address);
2410 if (newnameserver->id == NULL) {
2411 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2412 err_code |= ERR_ALERT | ERR_FATAL;
2413 goto resolv_out;
2414 }
2415
2416 newnameserver->resolvers = curr_resolvers;
2417 newnameserver->conf.line = resolv_linenum;
2418 newnameserver->addr = *sk;
2419
2420 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
2421 }
2422
2423resolv_out:
2424 free(sk);
2425 free(resolv_line);
2426 if (f != NULL)
2427 fclose(f);
2428 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002429 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2430 const char *res;
2431 unsigned int time;
2432
2433 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002434 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2435 file, linenum, args[0]);
2436 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002437 err_code |= ERR_ALERT | ERR_FATAL;
2438 goto out;
2439 }
2440 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2441 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002442 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2443 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002444 err_code |= ERR_ALERT | ERR_FATAL;
2445 goto out;
2446 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002447 if (strcmp(args[1], "nx") == 0)
2448 curr_resolvers->hold.nx = time;
2449 else if (strcmp(args[1], "other") == 0)
2450 curr_resolvers->hold.other = time;
2451 else if (strcmp(args[1], "refused") == 0)
2452 curr_resolvers->hold.refused = time;
2453 else if (strcmp(args[1], "timeout") == 0)
2454 curr_resolvers->hold.timeout = time;
2455 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002456 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002457 else if (strcmp(args[1], "obsolete") == 0)
2458 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002459 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002460 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2461 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002462 err_code |= ERR_ALERT | ERR_FATAL;
2463 goto out;
2464 }
2465
2466 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002467 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002468 int i = 0;
2469
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002470 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002471 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2472 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002473 err_code |= ERR_ALERT | ERR_FATAL;
2474 goto out;
2475 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002476
2477 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002478 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002479 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2480 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002481 err_code |= ERR_ALERT | ERR_FATAL;
2482 goto out;
2483 }
2484
2485 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002486 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002487 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002488 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2489 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002490 err_code |= ERR_WARN;
2491 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002492 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002493 else if (strcmp(args[0], "resolve_retries") == 0) {
2494 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002495 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2496 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002497 err_code |= ERR_ALERT | ERR_FATAL;
2498 goto out;
2499 }
2500 curr_resolvers->resolve_retries = atoi(args[1]);
2501 }
2502 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002503 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002504 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2505 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002506 err_code |= ERR_ALERT | ERR_FATAL;
2507 goto out;
2508 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002509 else if (strcmp(args[1], "retry") == 0 ||
2510 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002511 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002512 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002513
2514 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002515 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2516 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002517 err_code |= ERR_ALERT | ERR_FATAL;
2518 goto out;
2519 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002520 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002521 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002522 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2523 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002524 err_code |= ERR_ALERT | ERR_FATAL;
2525 goto out;
2526 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002527 if (args[1][2] == 't')
2528 curr_resolvers->timeout.retry = tout;
2529 else
2530 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002531 }
2532 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002533 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2534 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002535 err_code |= ERR_ALERT | ERR_FATAL;
2536 goto out;
2537 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002538 } /* neither "nameserver" nor "resolvers" */
2539 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002540 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002541 err_code |= ERR_ALERT | ERR_FATAL;
2542 goto out;
2543 }
2544
2545 out:
2546 free(errmsg);
2547 return err_code;
2548}
Simon Horman0d16a402015-01-30 11:22:58 +09002549
2550/*
William Lallemand51097192015-04-14 16:35:22 +02002551 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002552 * Returns the error code, 0 if OK, or any combination of :
2553 * - ERR_ABORT: must abort ASAP
2554 * - ERR_FATAL: we can continue parsing but not start the service
2555 * - ERR_WARN: a warning has been emitted
2556 * - ERR_ALERT: an alert has been emitted
2557 * Only the two first ones can stop processing, the two others are just
2558 * indicators.
2559 */
2560int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2561{
2562 static struct mailers *curmailers = NULL;
2563 struct mailer *newmailer = NULL;
2564 const char *err;
2565 int err_code = 0;
2566 char *errmsg = NULL;
2567
2568 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2569 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002570 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002571 err_code |= ERR_ALERT | ERR_ABORT;
2572 goto out;
2573 }
2574
2575 err = invalid_char(args[1]);
2576 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002577 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2578 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002579 err_code |= ERR_ALERT | ERR_ABORT;
2580 goto out;
2581 }
2582
2583 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2584 /*
2585 * If there are two proxies with the same name only following
2586 * combinations are allowed:
2587 */
2588 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002589 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2590 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002591 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002592 }
2593 }
2594
Vincent Bernat02779b62016-04-03 13:48:43 +02002595 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002596 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002597 err_code |= ERR_ALERT | ERR_ABORT;
2598 goto out;
2599 }
2600
2601 curmailers->next = mailers;
2602 mailers = curmailers;
2603 curmailers->conf.file = strdup(file);
2604 curmailers->conf.line = linenum;
2605 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002606 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2607 * But need enough time so that timeouts don't occur
2608 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002609 }
2610 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2611 struct sockaddr_storage *sk;
2612 int port1, port2;
2613 struct protocol *proto;
2614
2615 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002616 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2617 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002618 err_code |= ERR_ALERT | ERR_FATAL;
2619 goto out;
2620 }
2621
2622 err = invalid_char(args[1]);
2623 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002624 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2625 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002626 err_code |= ERR_ALERT | ERR_FATAL;
2627 goto out;
2628 }
2629
Vincent Bernat02779b62016-04-03 13:48:43 +02002630 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002631 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002632 err_code |= ERR_ALERT | ERR_ABORT;
2633 goto out;
2634 }
2635
2636 /* the mailers are linked backwards first */
2637 curmailers->count++;
2638 newmailer->next = curmailers->mailer_list;
2639 curmailers->mailer_list = newmailer;
2640 newmailer->mailers = curmailers;
2641 newmailer->conf.file = strdup(file);
2642 newmailer->conf.line = linenum;
2643
2644 newmailer->id = strdup(args[1]);
2645
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002646 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002647 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002648 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002649 err_code |= ERR_ALERT | ERR_FATAL;
2650 goto out;
2651 }
2652
2653 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002654 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002655 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2656 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002657 err_code |= ERR_ALERT | ERR_FATAL;
2658 goto out;
2659 }
2660
2661 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002662 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2663 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002664 err_code |= ERR_ALERT | ERR_FATAL;
2665 goto out;
2666 }
2667
2668 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002669 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2670 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002671 err_code |= ERR_ALERT | ERR_FATAL;
2672 goto out;
2673 }
2674
2675 newmailer->addr = *sk;
2676 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002677 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002678 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002679 }
2680 else if (strcmp(args[0], "timeout") == 0) {
2681 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002682 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2683 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002684 err_code |= ERR_ALERT | ERR_FATAL;
2685 goto out;
2686 }
2687 else if (strcmp(args[1], "mail") == 0) {
2688 const char *res;
2689 unsigned int timeout_mail;
2690 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002691 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2692 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002693 err_code |= ERR_ALERT | ERR_FATAL;
2694 goto out;
2695 }
2696 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2697 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002698 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2699 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002700 err_code |= ERR_ALERT | ERR_FATAL;
2701 goto out;
2702 }
2703 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002704 ha_alert("parsing [%s:%d] : '%s %s' expects a positive <time> argument.\n", file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002705 err_code |= ERR_ALERT | ERR_FATAL;
2706 goto out;
2707 }
2708 curmailers->timeout.mail = timeout_mail;
2709 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002710 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002711 file, linenum, args[0], args[1]);
2712 err_code |= ERR_ALERT | ERR_FATAL;
2713 goto out;
2714 }
2715 }
Simon Horman0d16a402015-01-30 11:22:58 +09002716 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002717 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002718 err_code |= ERR_ALERT | ERR_FATAL;
2719 goto out;
2720 }
2721
2722out:
2723 free(errmsg);
2724 return err_code;
2725}
2726
Simon Horman9dc49962015-01-30 11:22:59 +09002727static void free_email_alert(struct proxy *p)
2728{
2729 free(p->email_alert.mailers.name);
2730 p->email_alert.mailers.name = NULL;
2731 free(p->email_alert.from);
2732 p->email_alert.from = NULL;
2733 free(p->email_alert.to);
2734 p->email_alert.to = NULL;
2735 free(p->email_alert.myhostname);
2736 p->email_alert.myhostname = NULL;
2737}
2738
Willy Tarreau3842f002009-06-14 11:39:52 +02002739int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002740{
2741 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002742 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002743 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002744 int rc;
2745 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002746 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002747 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002748 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002749 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002750 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002751
Willy Tarreau977b8e42006-12-29 14:19:17 +01002752 if (!strcmp(args[0], "listen"))
2753 rc = PR_CAP_LISTEN;
2754 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002755 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002756 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002757 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002758 else
2759 rc = PR_CAP_NONE;
2760
2761 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002762 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002763 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2764 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2765 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002766 err_code |= ERR_ALERT | ERR_ABORT;
2767 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002768 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002769
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002770 err = invalid_char(args[1]);
2771 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002772 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2773 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002774 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002775 }
2776
Willy Tarreau8f50b682015-05-26 11:45:02 +02002777 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2778 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002779 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2780 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2781 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002782 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002783 }
2784
Vincent Bernat02779b62016-04-03 13:48:43 +02002785 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002786 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002787 err_code |= ERR_ALERT | ERR_ABORT;
2788 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002789 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002790
Willy Tarreau97cb7802010-01-03 20:23:58 +01002791 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002792 curproxy->next = proxies_list;
2793 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002794 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2795 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002796 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002797 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002798 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002799 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002800
William Lallemand6e62fb62015-04-28 16:55:23 +02002801 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2802 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002803 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002804 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002805 }
2806
2807 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002808 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002809 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002810
Willy Tarreaubaaee002006-06-26 02:48:02 +02002811 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002812 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002813 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002814 curproxy->no_options = defproxy.no_options;
2815 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002816 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002817 curproxy->except_net = defproxy.except_net;
2818 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002819 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002820 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002821
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002822 if (defproxy.fwdfor_hdr_len) {
2823 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2824 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2825 }
2826
Willy Tarreaub86db342009-11-30 11:50:16 +01002827 if (defproxy.orgto_hdr_len) {
2828 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2829 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2830 }
2831
Mark Lamourinec2247f02012-01-04 13:02:01 -05002832 if (defproxy.server_id_hdr_len) {
2833 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2834 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2835 }
2836
Willy Tarreau977b8e42006-12-29 14:19:17 +01002837 if (curproxy->cap & PR_CAP_FE) {
2838 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002839 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002840 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002841
2842 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002843 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2844 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002845
2846 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2847 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002848
Willy Tarreau977b8e42006-12-29 14:19:17 +01002849 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002850 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002851 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002852 curproxy->fullconn = defproxy.fullconn;
2853 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002854 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002855 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002856
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002857 if (defproxy.check_req) {
2858 curproxy->check_req = calloc(1, defproxy.check_len);
2859 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2860 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002861 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002862
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002863 if (defproxy.expect_str) {
2864 curproxy->expect_str = strdup(defproxy.expect_str);
2865 if (defproxy.expect_regex) {
2866 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002867 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2868 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002869 }
2870 }
2871
Willy Tarreau67402132012-05-31 20:40:20 +02002872 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002873 if (defproxy.cookie_name)
2874 curproxy->cookie_name = strdup(defproxy.cookie_name);
2875 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002876
2877 if (defproxy.dyncookie_key)
2878 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002879 if (defproxy.cookie_domain)
2880 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002881
Willy Tarreau31936852010-10-06 16:59:56 +02002882 if (defproxy.cookie_maxidle)
2883 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2884
2885 if (defproxy.cookie_maxlife)
2886 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2887
Emeric Brun647caf12009-06-30 17:57:00 +02002888 if (defproxy.rdp_cookie_name)
2889 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2890 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2891
Willy Tarreau01732802007-11-01 22:48:15 +01002892 if (defproxy.url_param_name)
2893 curproxy->url_param_name = strdup(defproxy.url_param_name);
2894 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002895
Benoitaffb4812009-03-25 13:02:10 +01002896 if (defproxy.hh_name)
2897 curproxy->hh_name = strdup(defproxy.hh_name);
2898 curproxy->hh_len = defproxy.hh_len;
2899 curproxy->hh_match_domain = defproxy.hh_match_domain;
2900
Willy Tarreauef9a3602012-12-08 22:29:20 +01002901 if (defproxy.conn_src.iface_name)
2902 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2903 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002904 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002905#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002906 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002907#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002908 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002909 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002910
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002911 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002912 if (defproxy.capture_name)
2913 curproxy->capture_name = strdup(defproxy.capture_name);
2914 curproxy->capture_namelen = defproxy.capture_namelen;
2915 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002916 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002917
Willy Tarreau977b8e42006-12-29 14:19:17 +01002918 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002919 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002920 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002921 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002922 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002923 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002924 curproxy->mon_net = defproxy.mon_net;
2925 curproxy->mon_mask = defproxy.mon_mask;
2926 if (defproxy.monitor_uri)
2927 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2928 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002929 if (defproxy.defbe.name)
2930 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002931
2932 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002933 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2934 if (curproxy->conf.logformat_string &&
2935 curproxy->conf.logformat_string != default_http_log_format &&
2936 curproxy->conf.logformat_string != default_tcp_log_format &&
2937 curproxy->conf.logformat_string != clf_http_log_format)
2938 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2939
2940 if (defproxy.conf.lfs_file) {
2941 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2942 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2943 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002944
2945 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2946 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2947 if (curproxy->conf.logformat_sd_string &&
2948 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2949 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2950
2951 if (defproxy.conf.lfsd_file) {
2952 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2953 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2954 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002955 }
2956
2957 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002958 curproxy->timeout.connect = defproxy.timeout.connect;
2959 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002960 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002961 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002962 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002963 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002964 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002965 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002966 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002967 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002968 }
2969
Willy Tarreaubaaee002006-06-26 02:48:02 +02002970 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002971 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002972
2973 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002974 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002975 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002976 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002977 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002978 LIST_INIT(&node->list);
2979 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2980 }
2981
Willy Tarreau62a61232013-04-12 18:13:46 +02002982 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2983 if (curproxy->conf.uniqueid_format_string)
2984 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2985
Dragan Dosen43885c72015-10-01 13:18:13 +02002986 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002987
Willy Tarreau62a61232013-04-12 18:13:46 +02002988 if (defproxy.conf.uif_file) {
2989 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2990 curproxy->conf.uif_line = defproxy.conf.uif_line;
2991 }
William Lallemanda73203e2012-03-12 12:48:57 +01002992
2993 /* copy default header unique id */
2994 if (defproxy.header_unique_id)
2995 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2996
William Lallemand82fe75c2012-10-23 10:25:10 +02002997 /* default compression options */
2998 if (defproxy.comp != NULL) {
2999 curproxy->comp = calloc(1, sizeof(struct comp));
3000 curproxy->comp->algos = defproxy.comp->algos;
3001 curproxy->comp->types = defproxy.comp->types;
3002 }
3003
Willy Tarreaubaaee002006-06-26 02:48:02 +02003004 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003005 curproxy->conf.used_listener_id = EB_ROOT;
3006 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003007
Simon Horman98637e52014-06-20 12:30:16 +09003008 if (defproxy.check_path)
3009 curproxy->check_path = strdup(defproxy.check_path);
3010 if (defproxy.check_command)
3011 curproxy->check_command = strdup(defproxy.check_command);
3012
Simon Horman9dc49962015-01-30 11:22:59 +09003013 if (defproxy.email_alert.mailers.name)
3014 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
3015 if (defproxy.email_alert.from)
3016 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
3017 if (defproxy.email_alert.to)
3018 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
3019 if (defproxy.email_alert.myhostname)
3020 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003021 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003022 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003023
Willy Tarreau93893792009-07-23 13:19:11 +02003024 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003025 }
3026 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3027 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003028 /* FIXME-20070101: we should do this too at the end of the
3029 * config parsing to free all default values.
3030 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003031 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3032 err_code |= ERR_ABORT;
3033 goto out;
3034 }
3035
Willy Tarreaua534fea2008-08-03 12:19:50 +02003036 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003037 free(defproxy.check_command);
3038 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003039 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003040 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003041 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003042 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003043 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003044 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003045 free(defproxy.capture_name);
3046 free(defproxy.monitor_uri);
3047 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003048 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003049 free(defproxy.fwdfor_hdr_name);
3050 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003051 free(defproxy.orgto_hdr_name);
3052 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003053 free(defproxy.server_id_hdr_name);
3054 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003055 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003056 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003057 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003058 free(defproxy.expect_regex);
3059 defproxy.expect_regex = NULL;
3060 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003061
Willy Tarreau62a61232013-04-12 18:13:46 +02003062 if (defproxy.conf.logformat_string != default_http_log_format &&
3063 defproxy.conf.logformat_string != default_tcp_log_format &&
3064 defproxy.conf.logformat_string != clf_http_log_format)
3065 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003066
Willy Tarreau62a61232013-04-12 18:13:46 +02003067 free(defproxy.conf.uniqueid_format_string);
3068 free(defproxy.conf.lfs_file);
3069 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003070 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003071 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003072
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003073 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3074 free(defproxy.conf.logformat_sd_string);
3075 free(defproxy.conf.lfsd_file);
3076
Willy Tarreaua534fea2008-08-03 12:19:50 +02003077 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003078 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003079
Willy Tarreaubaaee002006-06-26 02:48:02 +02003080 /* we cannot free uri_auth because it might already be used */
3081 init_default_instance();
3082 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003083 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3084 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003085 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003086 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003087 }
3088 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003089 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003090 err_code |= ERR_ALERT | ERR_FATAL;
3091 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003092 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003093
3094 /* update the current file and line being parsed */
3095 curproxy->conf.args.file = curproxy->conf.file;
3096 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003097
3098 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003099 if (!strcmp(args[0], "server") ||
3100 !strcmp(args[0], "default-server") ||
3101 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003102 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3103 if (err_code & ERR_FATAL)
3104 goto out;
3105 }
3106 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003107 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003108 int cur_arg;
3109
Willy Tarreaubaaee002006-06-26 02:48:02 +02003110 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003111 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003112 err_code |= ERR_ALERT | ERR_FATAL;
3113 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003114 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003115 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003116 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003117
Willy Tarreau24709282013-03-10 21:32:12 +01003118 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003119 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3120 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003121 err_code |= ERR_ALERT | ERR_FATAL;
3122 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003123 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003124
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003125 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003126
3127 /* use default settings for unix sockets */
3128 bind_conf->ux.uid = global.unix_bind.ux.uid;
3129 bind_conf->ux.gid = global.unix_bind.ux.gid;
3130 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003131
3132 /* NOTE: the following line might create several listeners if there
3133 * are comma-separated IPs or port ranges. So all further processing
3134 * will have to be applied to all listeners created after last_listen.
3135 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003136 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3137 if (errmsg && *errmsg) {
3138 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003139 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003140 }
3141 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003142 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3143 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003144 err_code |= ERR_ALERT | ERR_FATAL;
3145 goto out;
3146 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003147
Willy Tarreau4348fad2012-09-20 16:48:07 +02003148 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3149 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003150 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003151 }
3152
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003153 cur_arg = 2;
3154 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003155 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003156 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003157 char *err;
3158
Willy Tarreau26982662012-09-12 23:17:10 +02003159 kw = bind_find_kw(args[cur_arg]);
3160 if (kw) {
3161 char *err = NULL;
3162 int code;
3163
3164 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003165 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3166 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003167 cur_arg += 1 + kw->skip ;
3168 err_code |= ERR_ALERT | ERR_FATAL;
3169 goto out;
3170 }
3171
Willy Tarreau4348fad2012-09-20 16:48:07 +02003172 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003173 err_code |= code;
3174
3175 if (code) {
3176 if (err && *err) {
3177 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003178 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003179 }
3180 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003181 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3182 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003183 if (code & ERR_FATAL) {
3184 free(err);
3185 cur_arg += 1 + kw->skip;
3186 goto out;
3187 }
3188 }
3189 free(err);
3190 cur_arg += 1 + kw->skip;
3191 continue;
3192 }
3193
Willy Tarreau8638f482012-09-18 18:01:17 +02003194 err = NULL;
3195 if (!bind_dumped) {
3196 bind_dump_kws(&err);
3197 indent_msg(&err, 4);
3198 bind_dumped = 1;
3199 }
3200
Christopher Faulet767a84b2017-11-24 16:50:31 +01003201 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3202 file, linenum, args[0], args[1], args[cur_arg],
3203 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003204 free(err);
3205
Willy Tarreau93893792009-07-23 13:19:11 +02003206 err_code |= ERR_ALERT | ERR_FATAL;
3207 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003208 }
Willy Tarreau93893792009-07-23 13:19:11 +02003209 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003210 }
3211 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003212 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003213 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3214 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003215 err_code |= ERR_ALERT | ERR_FATAL;
3216 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003217 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003218 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003219 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003220
Willy Tarreaubaaee002006-06-26 02:48:02 +02003221 /* flush useless bits */
3222 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003223 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003224 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003225 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003226 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003227 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003228
William Lallemanddf1425a2015-04-28 20:17:49 +02003229 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3230 goto out;
3231
Willy Tarreau1c47f852006-07-09 08:22:27 +02003232 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003233 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3234 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003235 err_code |= ERR_ALERT | ERR_FATAL;
3236 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003237 }
3238
Willy Tarreaua534fea2008-08-03 12:19:50 +02003239 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003240 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003241 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003242 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003243 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3244
Willy Tarreau93893792009-07-23 13:19:11 +02003245 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003246 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003247 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003248 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3249 goto out;
3250
Willy Tarreaubaaee002006-06-26 02:48:02 +02003251 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3252 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3253 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3254 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003255 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003256 err_code |= ERR_ALERT | ERR_FATAL;
3257 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003258 }
3259 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003260 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003261 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003262
3263 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003264 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003265 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003266 err_code |= ERR_ALERT | ERR_FATAL;
3267 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003268 }
3269
William Lallemanddf1425a2015-04-28 20:17:49 +02003270 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3271 goto out;
3272
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003273 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003274 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3275 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003276 err_code |= ERR_ALERT | ERR_FATAL;
3277 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003278 }
3279
3280 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003281 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003282 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003283
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003284 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003285 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3286 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003287 err_code |= ERR_ALERT | ERR_FATAL;
3288 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003289 }
3290
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003291 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3292 if (node) {
3293 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003294 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3295 file, linenum, proxy_type_str(curproxy), curproxy->id,
3296 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003297 err_code |= ERR_ALERT | ERR_FATAL;
3298 goto out;
3299 }
3300 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003301 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003302 else if (!strcmp(args[0], "description")) {
3303 int i, len=0;
3304 char *d;
3305
Cyril Bonté99ed3272010-01-24 23:29:44 +01003306 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003307 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003308 file, linenum, args[0]);
3309 err_code |= ERR_ALERT | ERR_FATAL;
3310 goto out;
3311 }
3312
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003313 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003314 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3315 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003316 return -1;
3317 }
3318
Willy Tarreau348acfe2014-04-14 15:00:39 +02003319 for (i = 1; *args[i]; i++)
3320 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003321
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003322 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003323 curproxy->desc = d;
3324
Willy Tarreau348acfe2014-04-14 15:00:39 +02003325 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3326 for (i = 2; *args[i]; i++)
3327 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003328
3329 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003330 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003331 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3332 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003333 curproxy->state = PR_STSTOPPED;
3334 }
3335 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003336 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3337 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003338 curproxy->state = PR_STNEW;
3339 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003340 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3341 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003342 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003343
3344 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003345 if (strcmp(args[cur_arg], "all") == 0) {
3346 set = 0;
3347 break;
3348 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003349 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003350 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003351 err_code |= ERR_ALERT | ERR_FATAL;
3352 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003353 }
3354 cur_arg++;
3355 }
3356 curproxy->bind_proc = set;
3357 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003358 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003359 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003360 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003361 err_code |= ERR_ALERT | ERR_FATAL;
3362 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003363 }
3364
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003365 err = invalid_char(args[1]);
3366 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003367 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3368 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003369 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003370 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003371 }
3372
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003373 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003374 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3375 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003376 err_code |= ERR_ALERT | ERR_FATAL;
3377 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003378 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003379 }
3380 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3381
3382 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3383 err_code |= ERR_WARN;
3384
3385 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003386 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3387 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003388 err_code |= ERR_ALERT | ERR_FATAL;
3389 goto out;
3390 }
3391 free(curproxy->dyncookie_key);
3392 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003393 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003394 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3395 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003396
Willy Tarreau977b8e42006-12-29 14:19:17 +01003397 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003398 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003399
Willy Tarreaubaaee002006-06-26 02:48:02 +02003400 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003401 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3402 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003403 err_code |= ERR_ALERT | ERR_FATAL;
3404 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003405 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003406
Willy Tarreau67402132012-05-31 20:40:20 +02003407 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003408 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003409 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003410 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003411 curproxy->cookie_name = strdup(args[1]);
3412 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003413
Willy Tarreaubaaee002006-06-26 02:48:02 +02003414 cur_arg = 2;
3415 while (*(args[cur_arg])) {
3416 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003417 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003418 }
3419 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003420 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003421 }
3422 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003423 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003424 }
3425 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003426 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003427 }
3428 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003429 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003430 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003431 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003432 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003433 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003434 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003435 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003436 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003437 else if (!strcmp(args[cur_arg], "httponly")) {
3438 curproxy->ck_opts |= PR_CK_HTTPONLY;
3439 }
3440 else if (!strcmp(args[cur_arg], "secure")) {
3441 curproxy->ck_opts |= PR_CK_SECURE;
3442 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003443 else if (!strcmp(args[cur_arg], "domain")) {
3444 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003445 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3446 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003447 err_code |= ERR_ALERT | ERR_FATAL;
3448 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003449 }
3450
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003451 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003452 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003453 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3454 " dots nor does not start with a dot."
3455 " RFC forbids it, this configuration may not work properly.\n",
3456 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003457 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003458 }
3459
3460 err = invalid_domainchar(args[cur_arg + 1]);
3461 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003462 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3463 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003464 err_code |= ERR_ALERT | ERR_FATAL;
3465 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003466 }
3467
Willy Tarreau68a897b2009-12-03 23:28:34 +01003468 if (!curproxy->cookie_domain) {
3469 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3470 } else {
3471 /* one domain was already specified, add another one by
3472 * building the string which will be returned along with
3473 * the cookie.
3474 */
3475 char *new_ptr;
3476 int new_len = strlen(curproxy->cookie_domain) +
3477 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3478 new_ptr = malloc(new_len);
3479 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3480 free(curproxy->cookie_domain);
3481 curproxy->cookie_domain = new_ptr;
3482 }
Willy Tarreau31936852010-10-06 16:59:56 +02003483 cur_arg++;
3484 }
3485 else if (!strcmp(args[cur_arg], "maxidle")) {
3486 unsigned int maxidle;
3487 const char *res;
3488
3489 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003490 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3491 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003492 err_code |= ERR_ALERT | ERR_FATAL;
3493 goto out;
3494 }
3495
3496 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3497 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003498 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3499 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003500 err_code |= ERR_ALERT | ERR_FATAL;
3501 goto out;
3502 }
3503 curproxy->cookie_maxidle = maxidle;
3504 cur_arg++;
3505 }
3506 else if (!strcmp(args[cur_arg], "maxlife")) {
3507 unsigned int maxlife;
3508 const char *res;
3509
3510 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003511 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3512 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003513 err_code |= ERR_ALERT | ERR_FATAL;
3514 goto out;
3515 }
3516
3517 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3518 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003519 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3520 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003521 err_code |= ERR_ALERT | ERR_FATAL;
3522 goto out;
3523 }
3524 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003525 cur_arg++;
3526 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003527 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003528
3529 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3530 err_code |= ERR_WARN;
3531 curproxy->ck_opts |= PR_CK_DYNAMIC;
3532 }
3533
Willy Tarreaubaaee002006-06-26 02:48:02 +02003534 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003535 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3536 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003537 err_code |= ERR_ALERT | ERR_FATAL;
3538 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003539 }
3540 cur_arg++;
3541 }
Willy Tarreau67402132012-05-31 20:40:20 +02003542 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003543 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3544 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003545 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003546 }
3547
Willy Tarreau67402132012-05-31 20:40:20 +02003548 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003549 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3550 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003551 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003552 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003553
Willy Tarreau67402132012-05-31 20:40:20 +02003554 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003555 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3556 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003557 err_code |= ERR_ALERT | ERR_FATAL;
3558 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003559 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003560 else if (!strcmp(args[0], "email-alert")) {
3561 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003562 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3563 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003564 err_code |= ERR_ALERT | ERR_FATAL;
3565 goto out;
3566 }
3567
3568 if (!strcmp(args[1], "from")) {
3569 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003570 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3571 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003572 err_code |= ERR_ALERT | ERR_FATAL;
3573 goto out;
3574 }
3575 free(curproxy->email_alert.from);
3576 curproxy->email_alert.from = strdup(args[2]);
3577 }
3578 else if (!strcmp(args[1], "mailers")) {
3579 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003580 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3581 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003582 err_code |= ERR_ALERT | ERR_FATAL;
3583 goto out;
3584 }
3585 free(curproxy->email_alert.mailers.name);
3586 curproxy->email_alert.mailers.name = strdup(args[2]);
3587 }
3588 else if (!strcmp(args[1], "myhostname")) {
3589 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003590 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3591 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003592 err_code |= ERR_ALERT | ERR_FATAL;
3593 goto out;
3594 }
3595 free(curproxy->email_alert.myhostname);
3596 curproxy->email_alert.myhostname = strdup(args[2]);
3597 }
Simon Horman64e34162015-02-06 11:11:57 +09003598 else if (!strcmp(args[1], "level")) {
3599 curproxy->email_alert.level = get_log_level(args[2]);
3600 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003601 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3602 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003603 err_code |= ERR_ALERT | ERR_FATAL;
3604 goto out;
3605 }
3606 }
Simon Horman9dc49962015-01-30 11:22:59 +09003607 else if (!strcmp(args[1], "to")) {
3608 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003609 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3610 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003611 err_code |= ERR_ALERT | ERR_FATAL;
3612 goto out;
3613 }
3614 free(curproxy->email_alert.to);
3615 curproxy->email_alert.to = strdup(args[2]);
3616 }
3617 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003618 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3619 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003620 err_code |= ERR_ALERT | ERR_FATAL;
3621 goto out;
3622 }
Simon Horman64e34162015-02-06 11:11:57 +09003623 /* Indicate that the email_alert is at least partially configured */
3624 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003625 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003626 else if (!strcmp(args[0], "external-check")) {
3627 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003628 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3629 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003630 err_code |= ERR_ALERT | ERR_FATAL;
3631 goto out;
3632 }
3633
3634 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003635 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003636 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003637 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003638 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3639 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003640 err_code |= ERR_ALERT | ERR_FATAL;
3641 goto out;
3642 }
3643 free(curproxy->check_command);
3644 curproxy->check_command = strdup(args[2]);
3645 }
3646 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003647 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003648 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003649 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003650 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3651 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003652 err_code |= ERR_ALERT | ERR_FATAL;
3653 goto out;
3654 }
3655 free(curproxy->check_path);
3656 curproxy->check_path = strdup(args[2]);
3657 }
3658 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003659 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3660 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003661 err_code |= ERR_ALERT | ERR_FATAL;
3662 goto out;
3663 }
3664 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003665 else if (!strcmp(args[0], "persist")) { /* persist */
3666 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003667 ha_alert("parsing [%s:%d] : missing persist method.\n",
3668 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003669 err_code |= ERR_ALERT | ERR_FATAL;
3670 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003671 }
3672
3673 if (!strncmp(args[1], "rdp-cookie", 10)) {
3674 curproxy->options2 |= PR_O2_RDPC_PRST;
3675
Emeric Brunb982a3d2010-01-04 15:45:53 +01003676 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003677 const char *beg, *end;
3678
3679 beg = args[1] + 11;
3680 end = strchr(beg, ')');
3681
William Lallemanddf1425a2015-04-28 20:17:49 +02003682 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3683 goto out;
3684
Emeric Brun647caf12009-06-30 17:57:00 +02003685 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003686 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3687 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003688 err_code |= ERR_ALERT | ERR_FATAL;
3689 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003690 }
3691
3692 free(curproxy->rdp_cookie_name);
3693 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3694 curproxy->rdp_cookie_len = end-beg;
3695 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003696 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003697 free(curproxy->rdp_cookie_name);
3698 curproxy->rdp_cookie_name = strdup("msts");
3699 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3700 }
3701 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003702 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3703 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003704 err_code |= ERR_ALERT | ERR_FATAL;
3705 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003706 }
3707 }
3708 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003709 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3710 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003711 err_code |= ERR_ALERT | ERR_FATAL;
3712 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003713 }
3714 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003715 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003716 ha_alert("parsing [%s:%d] : '%s' is not supported anymore, please check the documentation.\n", file, linenum, args[0]);
Willy Tarreau6db62c52015-08-10 19:04:29 +02003717 err_code |= ERR_ALERT | ERR_FATAL;
3718 goto out;
3719 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003720 else if (!strcmp(args[0], "load-server-state-from-file")) {
3721 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3722 err_code |= ERR_WARN;
3723 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3724 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3725 }
3726 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3727 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3728 }
3729 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3730 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3731 }
3732 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003733 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3734 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003735 err_code |= ERR_ALERT | ERR_FATAL;
3736 goto out;
3737 }
3738 }
3739 else if (!strcmp(args[0], "server-state-file-name")) {
3740 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3741 err_code |= ERR_WARN;
3742 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003743 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3744 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003745 err_code |= ERR_ALERT | ERR_FATAL;
3746 goto out;
3747 }
3748 else if (!strcmp(args[1], "use-backend-name"))
3749 curproxy->server_state_file_name = strdup(curproxy->id);
3750 else
3751 curproxy->server_state_file_name = strdup(args[1]);
3752 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003753 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003754 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003755 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003756
Willy Tarreaubaaee002006-06-26 02:48:02 +02003757 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003758 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003759 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n", file, linenum, args[0], args[1]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003760 err_code |= ERR_ALERT | ERR_FATAL;
3761 goto out;
3762 }
3763
William Lallemand1a748ae2015-05-19 16:37:23 +02003764 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3765 goto out;
3766
Willy Tarreaubaaee002006-06-26 02:48:02 +02003767 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003768 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3769 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003770 err_code |= ERR_ALERT | ERR_FATAL;
3771 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003772 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003773 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003774 curproxy->capture_name = strdup(args[2]);
3775 curproxy->capture_namelen = strlen(curproxy->capture_name);
3776 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003777 curproxy->to_log |= LW_COOKIE;
3778 }
3779 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3780 struct cap_hdr *hdr;
3781
3782 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003783 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n", file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003784 err_code |= ERR_ALERT | ERR_FATAL;
3785 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003786 }
3787
William Lallemand1a748ae2015-05-19 16:37:23 +02003788 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3789 goto out;
3790
Willy Tarreaubaaee002006-06-26 02:48:02 +02003791 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003792 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3793 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003794 err_code |= ERR_ALERT | ERR_FATAL;
3795 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003796 }
3797
Vincent Bernat02779b62016-04-03 13:48:43 +02003798 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003799 hdr->next = curproxy->req_cap;
3800 hdr->name = strdup(args[3]);
3801 hdr->namelen = strlen(args[3]);
3802 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003803 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003804 hdr->index = curproxy->nb_req_cap++;
3805 curproxy->req_cap = hdr;
3806 curproxy->to_log |= LW_REQHDR;
3807 }
3808 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3809 struct cap_hdr *hdr;
3810
3811 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003812 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n", file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003813 err_code |= ERR_ALERT | ERR_FATAL;
3814 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003815 }
3816
William Lallemand1a748ae2015-05-19 16:37:23 +02003817 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3818 goto out;
3819
Willy Tarreaubaaee002006-06-26 02:48:02 +02003820 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003821 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3822 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003823 err_code |= ERR_ALERT | ERR_FATAL;
3824 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003825 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003826 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003827 hdr->next = curproxy->rsp_cap;
3828 hdr->name = strdup(args[3]);
3829 hdr->namelen = strlen(args[3]);
3830 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003831 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003832 hdr->index = curproxy->nb_rsp_cap++;
3833 curproxy->rsp_cap = hdr;
3834 curproxy->to_log |= LW_RSPHDR;
3835 }
3836 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003837 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3838 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003839 err_code |= ERR_ALERT | ERR_FATAL;
3840 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003841 }
3842 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003843 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003844 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003845 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003846
William Lallemanddf1425a2015-04-28 20:17:49 +02003847 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3848 goto out;
3849
Willy Tarreaubaaee002006-06-26 02:48:02 +02003850 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003851 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3852 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003853 err_code |= ERR_ALERT | ERR_FATAL;
3854 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003855 }
3856 curproxy->conn_retries = atol(args[1]);
3857 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003858 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003859 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003860
3861 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003862 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003863 err_code |= ERR_ALERT | ERR_FATAL;
3864 goto out;
3865 }
3866
Willy Tarreau20b0de52012-12-24 15:45:22 +01003867 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003868 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003869 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3870 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3871 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3872 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003873 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3874 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003875 err_code |= ERR_WARN;
3876 }
3877
Willy Tarreauff011f22011-01-06 17:51:27 +01003878 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003879
Willy Tarreauff011f22011-01-06 17:51:27 +01003880 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003881 err_code |= ERR_ALERT | ERR_ABORT;
3882 goto out;
3883 }
3884
Willy Tarreau5002f572014-04-23 01:32:02 +02003885 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003886 err_code |= warnif_cond_conflicts(rule->cond,
3887 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3888 file, linenum);
3889
Willy Tarreauff011f22011-01-06 17:51:27 +01003890 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003891 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003892 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003893 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003894
3895 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003896 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003897 err_code |= ERR_ALERT | ERR_FATAL;
3898 goto out;
3899 }
3900
3901 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003902 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003903 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3904 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003905 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3906 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003907 err_code |= ERR_WARN;
3908 }
3909
3910 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3911
3912 if (!rule) {
3913 err_code |= ERR_ALERT | ERR_ABORT;
3914 goto out;
3915 }
3916
3917 err_code |= warnif_cond_conflicts(rule->cond,
3918 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3919 file, linenum);
3920
3921 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3922 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003923 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3924 /* set the header name and length into the proxy structure */
3925 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3926 err_code |= ERR_WARN;
3927
3928 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003929 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3930 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003931 err_code |= ERR_ALERT | ERR_FATAL;
3932 goto out;
3933 }
3934
3935 /* set the desired header name */
3936 free(curproxy->server_id_hdr_name);
3937 curproxy->server_id_hdr_name = strdup(args[1]);
3938 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3939 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003940 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003941 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003942
Willy Tarreaub099aca2008-10-12 17:26:37 +02003943 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003944 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003945 err_code |= ERR_ALERT | ERR_FATAL;
3946 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003947 }
3948
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003949 /* emulate "block" using "http-request block". Since these rules are supposed to
3950 * be processed before all http-request rules, we put them into their own list
3951 * and will insert them at the end.
3952 */
3953 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3954 if (!rule) {
3955 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003956 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003957 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003958 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3959 err_code |= warnif_cond_conflicts(rule->cond,
3960 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3961 file, linenum);
3962 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003963
3964 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003965 ha_warning("parsing [%s:%d] : The '%s' directive is now deprecated in favor of 'http-request deny' which uses the exact same syntax. The rules are translated but support might disappear in a future version.\n", file, linenum, args[0]);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003966
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003967 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003968 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003969 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003970
Cyril Bonté99ed3272010-01-24 23:29:44 +01003971 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003972 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003973 err_code |= ERR_ALERT | ERR_FATAL;
3974 goto out;
3975 }
3976
Willy Tarreaube4653b2015-05-28 15:26:58 +02003977 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003978 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3979 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003980 err_code |= ERR_ALERT | ERR_FATAL;
3981 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003982 }
3983
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003984 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003985 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003986 err_code |= warnif_cond_conflicts(rule->cond,
3987 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3988 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003989 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003990 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003991 struct switching_rule *rule;
3992
Willy Tarreaub099aca2008-10-12 17:26:37 +02003993 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003994 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003995 err_code |= ERR_ALERT | ERR_FATAL;
3996 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003997 }
3998
Willy Tarreau55ea7572007-06-17 19:56:27 +02003999 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004000 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02004001
4002 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004003 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004004 err_code |= ERR_ALERT | ERR_FATAL;
4005 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02004006 }
4007
Willy Tarreauf51658d2014-04-23 01:21:56 +02004008 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004009 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004010 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4011 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02004012 err_code |= ERR_ALERT | ERR_FATAL;
4013 goto out;
4014 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004015
Willy Tarreauf51658d2014-04-23 01:21:56 +02004016 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004017 }
Willy Tarreau4f862642017-02-28 09:34:39 +01004018 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004019 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
4020 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004021 err_code |= ERR_ALERT | ERR_FATAL;
4022 goto out;
4023 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004024
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004025 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004026 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004027 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004028 goto out;
4029 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004030 rule->cond = cond;
4031 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004032 rule->line = linenum;
4033 rule->file = strdup(file);
4034 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004035 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004036 goto out;
4037 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004038 LIST_INIT(&rule->list);
4039 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4040 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004041 else if (strcmp(args[0], "use-server") == 0) {
4042 struct server_rule *rule;
4043
4044 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004045 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004046 err_code |= ERR_ALERT | ERR_FATAL;
4047 goto out;
4048 }
4049
4050 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4051 err_code |= ERR_WARN;
4052
4053 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004054 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004055 err_code |= ERR_ALERT | ERR_FATAL;
4056 goto out;
4057 }
4058
4059 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004060 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4061 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004062 err_code |= ERR_ALERT | ERR_FATAL;
4063 goto out;
4064 }
4065
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004066 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004067 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4068 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004069 err_code |= ERR_ALERT | ERR_FATAL;
4070 goto out;
4071 }
4072
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004073 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004074
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004075 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004076 rule->cond = cond;
4077 rule->srv.name = strdup(args[1]);
4078 LIST_INIT(&rule->list);
4079 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4080 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4081 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004082 else if ((!strcmp(args[0], "force-persist")) ||
4083 (!strcmp(args[0], "ignore-persist"))) {
4084 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004085
4086 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004087 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004088 err_code |= ERR_ALERT | ERR_FATAL;
4089 goto out;
4090 }
4091
Cyril Bonté4288c5a2018-03-12 22:02:59 +01004092 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01004093 err_code |= ERR_WARN;
4094
Willy Tarreauef6494c2010-01-28 17:12:36 +01004095 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004096 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4097 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004098 err_code |= ERR_ALERT | ERR_FATAL;
4099 goto out;
4100 }
4101
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004102 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004103 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4104 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004105 err_code |= ERR_ALERT | ERR_FATAL;
4106 goto out;
4107 }
4108
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004109 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4110 * where force-persist is applied.
4111 */
4112 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004113
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004114 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004115 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004116 if (!strcmp(args[0], "force-persist")) {
4117 rule->type = PERSIST_TYPE_FORCE;
4118 } else {
4119 rule->type = PERSIST_TYPE_IGNORE;
4120 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004121 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004122 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004123 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004124 else if (!strcmp(args[0], "stick-table")) {
4125 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004126 struct proxy *other;
4127
Willy Tarreauc7867682018-07-27 10:26:22 +02004128 if (curproxy == &defproxy) {
4129 ha_alert("parsing [%s:%d] : 'stick-table' is not supported in 'defaults' section.\n",
4130 file, linenum);
4131 err_code |= ERR_ALERT | ERR_FATAL;
4132 goto out;
4133 }
4134
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004135 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004136 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004137 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4138 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004139 err_code |= ERR_ALERT | ERR_FATAL;
4140 goto out;
4141 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004142
Emeric Brun32da3c42010-09-23 18:39:19 +02004143 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004144 curproxy->table.type = (unsigned int)-1;
4145 while (*args[myidx]) {
4146 const char *err;
4147
4148 if (strcmp(args[myidx], "size") == 0) {
4149 myidx++;
4150 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004151 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4152 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004153 err_code |= ERR_ALERT | ERR_FATAL;
4154 goto out;
4155 }
4156 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004157 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4158 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004159 err_code |= ERR_ALERT | ERR_FATAL;
4160 goto out;
4161 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004162 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004163 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004164 else if (strcmp(args[myidx], "peers") == 0) {
4165 myidx++;
Godbach50523162013-12-11 19:48:57 +08004166 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004167 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4168 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004169 err_code |= ERR_ALERT | ERR_FATAL;
4170 goto out;
Godbach50523162013-12-11 19:48:57 +08004171 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004172 curproxy->table.peers.name = strdup(args[myidx++]);
4173 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004174 else if (strcmp(args[myidx], "expire") == 0) {
4175 myidx++;
4176 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004177 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4178 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004179 err_code |= ERR_ALERT | ERR_FATAL;
4180 goto out;
4181 }
4182 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4183 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004184 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4185 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004186 err_code |= ERR_ALERT | ERR_FATAL;
4187 goto out;
4188 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004189 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004190 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4191 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004192 err_code |= ERR_ALERT | ERR_FATAL;
4193 goto out;
4194 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004195 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004196 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004197 }
4198 else if (strcmp(args[myidx], "nopurge") == 0) {
4199 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004200 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004201 }
4202 else if (strcmp(args[myidx], "type") == 0) {
4203 myidx++;
4204 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004205 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4206 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004207 err_code |= ERR_ALERT | ERR_FATAL;
4208 goto out;
4209 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004210 /* myidx already points to next arg */
4211 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004212 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004213 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004214 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004215
4216 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004217 nw = args[myidx];
4218 while (*nw) {
4219 /* the "store" keyword supports a comma-separated list */
4220 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004221 sa = NULL; /* store arg */
4222 while (*nw && *nw != ',') {
4223 if (*nw == '(') {
4224 *nw = 0;
4225 sa = ++nw;
4226 while (*nw != ')') {
4227 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004228 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4229 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004230 err_code |= ERR_ALERT | ERR_FATAL;
4231 goto out;
4232 }
4233 nw++;
4234 }
4235 *nw = '\0';
4236 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004237 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004238 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004239 if (*nw)
4240 *nw++ = '\0';
4241 type = stktable_get_data_type(cw);
4242 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004243 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4244 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004245 err_code |= ERR_ALERT | ERR_FATAL;
4246 goto out;
4247 }
Willy Tarreauac782882010-06-20 10:41:54 +02004248
4249 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4250 switch (err) {
4251 case PE_NONE: break;
4252 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004253 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4254 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004255 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004256 break;
4257
4258 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004259 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4260 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004261 err_code |= ERR_ALERT | ERR_FATAL;
4262 goto out;
4263
4264 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004265 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4266 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004267 err_code |= ERR_ALERT | ERR_FATAL;
4268 goto out;
4269
4270 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004271 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4272 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004273 err_code |= ERR_ALERT | ERR_FATAL;
4274 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004275 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004276 }
4277 myidx++;
4278 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004279 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004280 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4281 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004282 err_code |= ERR_ALERT | ERR_FATAL;
4283 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004284 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004285 }
4286
4287 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004288 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4289 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004290 err_code |= ERR_ALERT | ERR_FATAL;
4291 goto out;
4292 }
4293
4294 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004295 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4296 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004297 err_code |= ERR_ALERT | ERR_FATAL;
4298 goto out;
4299 }
4300 }
4301 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004302 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004303 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004304 int myidx = 0;
4305 const char *name = NULL;
4306 int flags;
4307
4308 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004309 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004310 err_code |= ERR_ALERT | ERR_FATAL;
4311 goto out;
4312 }
4313
4314 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4315 err_code |= ERR_WARN;
4316 goto out;
4317 }
4318
4319 myidx++;
4320 if ((strcmp(args[myidx], "store") == 0) ||
4321 (strcmp(args[myidx], "store-request") == 0)) {
4322 myidx++;
4323 flags = STK_IS_STORE;
4324 }
4325 else if (strcmp(args[myidx], "store-response") == 0) {
4326 myidx++;
4327 flags = STK_IS_STORE | STK_ON_RSP;
4328 }
4329 else if (strcmp(args[myidx], "match") == 0) {
4330 myidx++;
4331 flags = STK_IS_MATCH;
4332 }
4333 else if (strcmp(args[myidx], "on") == 0) {
4334 myidx++;
4335 flags = STK_IS_MATCH | STK_IS_STORE;
4336 }
4337 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004338 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004339 err_code |= ERR_ALERT | ERR_FATAL;
4340 goto out;
4341 }
4342
4343 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004344 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004345 err_code |= ERR_ALERT | ERR_FATAL;
4346 goto out;
4347 }
4348
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004349 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004350 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004351 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004352 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004353 err_code |= ERR_ALERT | ERR_FATAL;
4354 goto out;
4355 }
4356
4357 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004358 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004359 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4360 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004361 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004362 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004363 goto out;
4364 }
4365 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004366 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004367 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4368 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004369 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004370 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004371 goto out;
4372 }
4373 }
4374
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004375 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004376 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004377
Emeric Brunb982a3d2010-01-04 15:45:53 +01004378 if (strcmp(args[myidx], "table") == 0) {
4379 myidx++;
4380 name = args[myidx++];
4381 }
4382
Willy Tarreauef6494c2010-01-28 17:12:36 +01004383 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004384 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004385 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4386 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004387 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004388 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004389 goto out;
4390 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004391 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004392 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004393 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4394 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004395 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004396 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004397 goto out;
4398 }
Emeric Brun97679e72010-09-23 17:56:44 +02004399 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004400 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004401 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004402 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004403
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004404 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004405 rule->cond = cond;
4406 rule->expr = expr;
4407 rule->flags = flags;
4408 rule->table.name = name ? strdup(name) : NULL;
4409 LIST_INIT(&rule->list);
4410 if (flags & STK_ON_RSP)
4411 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4412 else
4413 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4414 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004415 else if (!strcmp(args[0], "stats")) {
4416 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4417 curproxy->uri_auth = NULL; /* we must detach from the default config */
4418
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004419 if (!*args[1]) {
4420 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004421 } else if (!strcmp(args[1], "admin")) {
4422 struct stats_admin_rule *rule;
4423
4424 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004425 ha_alert("parsing [%s:%d]: '%s %s' not allowed in 'defaults' section.\n", file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004426 err_code |= ERR_ALERT | ERR_FATAL;
4427 goto out;
4428 }
4429
4430 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004431 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004432 err_code |= ERR_ALERT | ERR_ABORT;
4433 goto out;
4434 }
4435
4436 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004437 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4438 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004439 err_code |= ERR_ALERT | ERR_FATAL;
4440 goto out;
4441 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004442 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004443 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4444 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004445 err_code |= ERR_ALERT | ERR_FATAL;
4446 goto out;
4447 }
4448
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004449 err_code |= warnif_cond_conflicts(cond,
4450 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4451 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004452
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004453 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004454 rule->cond = cond;
4455 LIST_INIT(&rule->list);
4456 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004457 } else if (!strcmp(args[1], "uri")) {
4458 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004459 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004460 err_code |= ERR_ALERT | ERR_FATAL;
4461 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004462 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004463 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004464 err_code |= ERR_ALERT | ERR_ABORT;
4465 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004466 }
4467 } else if (!strcmp(args[1], "realm")) {
4468 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004469 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004470 err_code |= ERR_ALERT | ERR_FATAL;
4471 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004472 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004473 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004474 err_code |= ERR_ALERT | ERR_ABORT;
4475 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004476 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004477 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004478 unsigned interval;
4479
4480 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4481 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004482 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4483 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004484 err_code |= ERR_ALERT | ERR_FATAL;
4485 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004486 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004487 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004488 err_code |= ERR_ALERT | ERR_ABORT;
4489 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004490 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004491 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004492 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004493
4494 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004495 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004496 err_code |= ERR_ALERT | ERR_FATAL;
4497 goto out;
4498 }
4499
4500 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004501 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004502 err_code |= ERR_ALERT | ERR_ABORT;
4503 goto out;
4504 }
4505
Willy Tarreauff011f22011-01-06 17:51:27 +01004506 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004507 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004508 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4509 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004510 err_code |= ERR_WARN;
4511 }
4512
Willy Tarreauff011f22011-01-06 17:51:27 +01004513 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004514
Willy Tarreauff011f22011-01-06 17:51:27 +01004515 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004516 err_code |= ERR_ALERT | ERR_ABORT;
4517 goto out;
4518 }
4519
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004520 err_code |= warnif_cond_conflicts(rule->cond,
4521 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4522 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004523 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004524
Willy Tarreaubaaee002006-06-26 02:48:02 +02004525 } else if (!strcmp(args[1], "auth")) {
4526 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004527 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004528 err_code |= ERR_ALERT | ERR_FATAL;
4529 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004530 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004531 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004532 err_code |= ERR_ALERT | ERR_ABORT;
4533 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004534 }
4535 } else if (!strcmp(args[1], "scope")) {
4536 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004537 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004538 err_code |= ERR_ALERT | ERR_FATAL;
4539 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004540 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004541 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004542 err_code |= ERR_ALERT | ERR_ABORT;
4543 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004544 }
4545 } else if (!strcmp(args[1], "enable")) {
4546 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004547 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004548 err_code |= ERR_ALERT | ERR_ABORT;
4549 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004550 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004551 } else if (!strcmp(args[1], "hide-version")) {
4552 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004553 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004554 err_code |= ERR_ALERT | ERR_ABORT;
4555 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004556 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004557 } else if (!strcmp(args[1], "show-legends")) {
4558 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004559 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004560 err_code |= ERR_ALERT | ERR_ABORT;
4561 goto out;
4562 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004563 } else if (!strcmp(args[1], "show-node")) {
4564
4565 if (*args[2]) {
4566 int i;
4567 char c;
4568
4569 for (i=0; args[2][i]; i++) {
4570 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004571 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4572 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004573 break;
4574 }
4575
4576 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004577 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4578 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4579 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004580 err_code |= ERR_ALERT | ERR_FATAL;
4581 goto out;
4582 }
4583 }
4584
4585 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004586 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004587 err_code |= ERR_ALERT | ERR_ABORT;
4588 goto out;
4589 }
4590 } else if (!strcmp(args[1], "show-desc")) {
4591 char *desc = NULL;
4592
4593 if (*args[2]) {
4594 int i, len=0;
4595 char *d;
4596
Willy Tarreau348acfe2014-04-14 15:00:39 +02004597 for (i = 2; *args[i]; i++)
4598 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004599
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004600 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004601
Willy Tarreau348acfe2014-04-14 15:00:39 +02004602 d += snprintf(d, desc + len - d, "%s", args[2]);
4603 for (i = 3; *args[i]; i++)
4604 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004605 }
4606
4607 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004608 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4609 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004610 else {
4611 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4612 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004613 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004614 err_code |= ERR_ALERT | ERR_ABORT;
4615 goto out;
4616 }
4617 free(desc);
4618 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004619 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004620stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004621 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4622 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004623 err_code |= ERR_ALERT | ERR_FATAL;
4624 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004625 }
4626 }
4627 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004628 int optnum;
4629
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004630 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004631 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4632 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004633 err_code |= ERR_ALERT | ERR_FATAL;
4634 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004635 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004636
4637 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4638 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004639 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004640 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4641 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004642 err_code |= ERR_ALERT | ERR_FATAL;
4643 goto out;
4644 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004645 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4646 goto out;
4647
Willy Tarreau93893792009-07-23 13:19:11 +02004648 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4649 err_code |= ERR_WARN;
4650 goto out;
4651 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004652
Willy Tarreau3842f002009-06-14 11:39:52 +02004653 curproxy->no_options &= ~cfg_opts[optnum].val;
4654 curproxy->options &= ~cfg_opts[optnum].val;
4655
4656 switch (kwm) {
4657 case KWM_STD:
4658 curproxy->options |= cfg_opts[optnum].val;
4659 break;
4660 case KWM_NO:
4661 curproxy->no_options |= cfg_opts[optnum].val;
4662 break;
4663 case KWM_DEF: /* already cleared */
4664 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004665 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004666
Willy Tarreau93893792009-07-23 13:19:11 +02004667 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004668 }
4669 }
4670
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004671 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4672 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004673 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004674 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4675 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004676 err_code |= ERR_ALERT | ERR_FATAL;
4677 goto out;
4678 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004679 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4680 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004681 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4682 err_code |= ERR_WARN;
4683 goto out;
4684 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004685
Willy Tarreau3842f002009-06-14 11:39:52 +02004686 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4687 curproxy->options2 &= ~cfg_opts2[optnum].val;
4688
4689 switch (kwm) {
4690 case KWM_STD:
4691 curproxy->options2 |= cfg_opts2[optnum].val;
4692 break;
4693 case KWM_NO:
4694 curproxy->no_options2 |= cfg_opts2[optnum].val;
4695 break;
4696 case KWM_DEF: /* already cleared */
4697 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004698 }
Willy Tarreau93893792009-07-23 13:19:11 +02004699 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004700 }
4701 }
4702
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004703 /* HTTP options override each other. They can be cancelled using
4704 * "no option xxx" which only switches to default mode if the mode
4705 * was this one (useful for cancelling options set in defaults
4706 * sections).
4707 */
Christopher Faulet315b39c2018-09-21 16:26:19 +02004708 if (strcmp(args[1], "httpclose") == 0 || strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004709 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4710 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004711 if (kwm == KWM_STD) {
4712 curproxy->options &= ~PR_O_HTTP_MODE;
Christopher Faulet315b39c2018-09-21 16:26:19 +02004713 curproxy->options |= PR_O_HTTP_CLO;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004714 goto out;
4715 }
4716 else if (kwm == KWM_NO) {
Christopher Faulet315b39c2018-09-21 16:26:19 +02004717 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_CLO)
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004718 curproxy->options &= ~PR_O_HTTP_MODE;
4719 goto out;
4720 }
4721 }
4722 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004723 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4724 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004725 if (kwm == KWM_STD) {
4726 curproxy->options &= ~PR_O_HTTP_MODE;
4727 curproxy->options |= PR_O_HTTP_SCL;
4728 goto out;
4729 }
4730 else if (kwm == KWM_NO) {
4731 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4732 curproxy->options &= ~PR_O_HTTP_MODE;
4733 goto out;
4734 }
4735 }
4736 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004737 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4738 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004739 if (kwm == KWM_STD) {
4740 curproxy->options &= ~PR_O_HTTP_MODE;
4741 curproxy->options |= PR_O_HTTP_KAL;
4742 goto out;
4743 }
4744 else if (kwm == KWM_NO) {
4745 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4746 curproxy->options &= ~PR_O_HTTP_MODE;
4747 goto out;
4748 }
4749 }
4750 else if (strcmp(args[1], "http-tunnel") == 0) {
Christopher Faulet4212a302018-09-21 10:42:19 +02004751 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[1], NULL)) {
4752 err_code |= ERR_WARN;
4753 goto out;
4754 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004755 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4756 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004757 if (kwm == KWM_STD) {
4758 curproxy->options &= ~PR_O_HTTP_MODE;
4759 curproxy->options |= PR_O_HTTP_TUN;
4760 goto out;
4761 }
4762 else if (kwm == KWM_NO) {
4763 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4764 curproxy->options &= ~PR_O_HTTP_MODE;
4765 goto out;
4766 }
4767 }
4768
Joseph Lynch726ab712015-05-11 23:25:34 -07004769 /* Redispatch can take an integer argument that control when the
4770 * resispatch occurs. All values are relative to the retries option.
4771 * This can be cancelled using "no option xxx".
4772 */
4773 if (strcmp(args[1], "redispatch") == 0) {
4774 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4775 err_code |= ERR_WARN;
4776 goto out;
4777 }
4778
4779 curproxy->no_options &= ~PR_O_REDISP;
4780 curproxy->options &= ~PR_O_REDISP;
4781
4782 switch (kwm) {
4783 case KWM_STD:
4784 curproxy->options |= PR_O_REDISP;
4785 curproxy->redispatch_after = -1;
4786 if(*args[2]) {
4787 curproxy->redispatch_after = atol(args[2]);
4788 }
4789 break;
4790 case KWM_NO:
4791 curproxy->no_options |= PR_O_REDISP;
4792 curproxy->redispatch_after = 0;
4793 break;
4794 case KWM_DEF: /* already cleared */
4795 break;
4796 }
4797 goto out;
4798 }
4799
Willy Tarreau3842f002009-06-14 11:39:52 +02004800 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004801 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4802 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004803 err_code |= ERR_ALERT | ERR_FATAL;
4804 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004805 }
4806
Emeric Brun3a058f32009-06-30 18:26:00 +02004807 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004808 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004809 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004810 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004811 if (*(args[2]) != '\0') {
4812 if (!strcmp(args[2], "clf")) {
4813 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004814 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004815 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004816 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004817 err_code |= ERR_ALERT | ERR_FATAL;
4818 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004819 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004820 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4821 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004822 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004823 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4824 char *oldlogformat = "log-format";
4825 char *clflogformat = "";
4826
4827 if (curproxy->conf.logformat_string == default_http_log_format)
4828 oldlogformat = "option httplog";
4829 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4830 oldlogformat = "option tcplog";
4831 else if (curproxy->conf.logformat_string == clf_http_log_format)
4832 oldlogformat = "option httplog clf";
4833 if (logformat == clf_http_log_format)
4834 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004835 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4836 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004837 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004838 if (curproxy->conf.logformat_string != default_http_log_format &&
4839 curproxy->conf.logformat_string != default_tcp_log_format &&
4840 curproxy->conf.logformat_string != clf_http_log_format)
4841 free(curproxy->conf.logformat_string);
4842 curproxy->conf.logformat_string = logformat;
4843
4844 free(curproxy->conf.lfs_file);
4845 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4846 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004847
4848 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4849 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4850 file, linenum, curproxy->id);
4851 err_code |= ERR_WARN;
4852 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004853 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004854 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004855 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4856 char *oldlogformat = "log-format";
4857
4858 if (curproxy->conf.logformat_string == default_http_log_format)
4859 oldlogformat = "option httplog";
4860 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4861 oldlogformat = "option tcplog";
4862 else if (curproxy->conf.logformat_string == clf_http_log_format)
4863 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004864 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4865 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004866 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004867 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004868 if (curproxy->conf.logformat_string != default_http_log_format &&
4869 curproxy->conf.logformat_string != default_tcp_log_format &&
4870 curproxy->conf.logformat_string != clf_http_log_format)
4871 free(curproxy->conf.logformat_string);
4872 curproxy->conf.logformat_string = default_tcp_log_format;
4873
4874 free(curproxy->conf.lfs_file);
4875 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4876 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004877
4878 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4879 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004880
4881 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4882 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4883 file, linenum, curproxy->id);
4884 err_code |= ERR_WARN;
4885 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004886 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004887 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004888 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004889 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004890 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004891
William Lallemanddf1425a2015-04-28 20:17:49 +02004892 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4893 goto out;
4894
Willy Tarreau13943ab2006-12-31 00:24:10 +01004895 if (curproxy->cap & PR_CAP_FE)
4896 curproxy->options |= PR_O_TCP_CLI_KA;
4897 if (curproxy->cap & PR_CAP_BE)
4898 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004899 }
4900 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004901 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004902 err_code |= ERR_WARN;
4903
Willy Tarreaubaaee002006-06-26 02:48:02 +02004904 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004905 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004906 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004907 curproxy->options2 &= ~PR_O2_CHK_ANY;
4908 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004909 if (!*args[2]) { /* no argument */
4910 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4911 curproxy->check_len = strlen(DEF_CHECK_REQ);
4912 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004913 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004914 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004915 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004916 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004917 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004918 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004919 if (*args[4])
4920 reqlen += strlen(args[4]);
4921 else
4922 reqlen += strlen("HTTP/1.0");
4923
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004924 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004925 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004926 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004927 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004928 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4929 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004930 }
4931 else if (!strcmp(args[1], "ssl-hello-chk")) {
4932 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004933 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004934 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004935
Willy Tarreaua534fea2008-08-03 12:19:50 +02004936 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004937 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004938 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004939 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004940
4941 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4942 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004943 }
Willy Tarreau23677902007-05-08 23:50:35 +02004944 else if (!strcmp(args[1], "smtpchk")) {
4945 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004946 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004947 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004948 curproxy->options2 &= ~PR_O2_CHK_ANY;
4949 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004950
4951 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4952 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4953 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4954 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4955 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4956 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004957 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004958 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4959 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4960 } else {
4961 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4962 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4963 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4964 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4965 }
4966 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004967 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4968 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004969 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004970 else if (!strcmp(args[1], "pgsql-check")) {
4971 /* use PostgreSQL request to check servers' health */
4972 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4973 err_code |= ERR_WARN;
4974
4975 free(curproxy->check_req);
4976 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004977 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004978 curproxy->options2 |= PR_O2_PGSQL_CHK;
4979
4980 if (*(args[2])) {
4981 int cur_arg = 2;
4982
4983 while (*(args[cur_arg])) {
4984 if (strcmp(args[cur_arg], "user") == 0) {
4985 char * packet;
4986 uint32_t packet_len;
4987 uint32_t pv;
4988
4989 /* suboption header - needs additional argument for it */
4990 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004991 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4992 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004993 err_code |= ERR_ALERT | ERR_FATAL;
4994 goto out;
4995 }
4996
4997 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4998 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4999 pv = htonl(0x30000); /* protocol version 3.0 */
5000
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005001 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005002
5003 memcpy(packet + 4, &pv, 4);
5004
5005 /* copy "user" */
5006 memcpy(packet + 8, "user", 4);
5007
5008 /* copy username */
5009 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
5010
5011 free(curproxy->check_req);
5012 curproxy->check_req = packet;
5013 curproxy->check_len = packet_len;
5014
5015 packet_len = htonl(packet_len);
5016 memcpy(packet, &packet_len, 4);
5017 cur_arg += 2;
5018 } else {
5019 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005020 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5021 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005022 err_code |= ERR_ALERT | ERR_FATAL;
5023 goto out;
5024 }
5025 } /* end while loop */
5026 }
William Lallemanddf1425a2015-04-28 20:17:49 +02005027 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
5028 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005029 }
5030
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005031 else if (!strcmp(args[1], "redis-check")) {
5032 /* use REDIS PING request to check servers' health */
5033 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5034 err_code |= ERR_WARN;
5035
5036 free(curproxy->check_req);
5037 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005038 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005039 curproxy->options2 |= PR_O2_REDIS_CHK;
5040
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005041 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005042 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5043 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005044
5045 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5046 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005047 }
5048
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005049 else if (!strcmp(args[1], "mysql-check")) {
5050 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005051 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5052 err_code |= ERR_WARN;
5053
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005054 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005055 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005056 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005057 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005058
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005059 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005060 * const char mysql40_client_auth_pkt[] = {
5061 * "\x0e\x00\x00" // packet length
5062 * "\x01" // packet number
5063 * "\x00\x00" // client capabilities
5064 * "\x00\x00\x01" // max packet
5065 * "haproxy\x00" // username (null terminated string)
5066 * "\x00" // filler (always 0x00)
5067 * "\x01\x00\x00" // packet length
5068 * "\x00" // packet number
5069 * "\x01" // COM_QUIT command
5070 * };
5071 */
5072
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005073 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5074 * const char mysql41_client_auth_pkt[] = {
5075 * "\x0e\x00\x00\" // packet length
5076 * "\x01" // packet number
5077 * "\x00\x00\x00\x00" // client capabilities
5078 * "\x00\x00\x00\x01" // max packet
5079 * "\x21" // character set (UTF-8)
5080 * char[23] // All zeroes
5081 * "haproxy\x00" // username (null terminated string)
5082 * "\x00" // filler (always 0x00)
5083 * "\x01\x00\x00" // packet length
5084 * "\x00" // packet number
5085 * "\x01" // COM_QUIT command
5086 * };
5087 */
5088
5089
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005090 if (*(args[2])) {
5091 int cur_arg = 2;
5092
5093 while (*(args[cur_arg])) {
5094 if (strcmp(args[cur_arg], "user") == 0) {
5095 char *mysqluser;
5096 int packetlen, reqlen, userlen;
5097
5098 /* suboption header - needs additional argument for it */
5099 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005100 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5101 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005102 err_code |= ERR_ALERT | ERR_FATAL;
5103 goto out;
5104 }
5105 mysqluser = args[cur_arg + 1];
5106 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005107
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005108 if (*(args[cur_arg+2])) {
5109 if (!strcmp(args[cur_arg+2], "post-41")) {
5110 packetlen = userlen + 7 + 27;
5111 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005112
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005113 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005114 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005115 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005116
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005117 snprintf(curproxy->check_req, 4, "%c%c%c",
5118 ((unsigned char) packetlen & 0xff),
5119 ((unsigned char) (packetlen >> 8) & 0xff),
5120 ((unsigned char) (packetlen >> 16) & 0xff));
5121
5122 curproxy->check_req[3] = 1;
Olivier Houchard33320902018-10-16 18:39:38 +02005123 curproxy->check_req[5] = 0x82; // 130
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005124 curproxy->check_req[11] = 1;
5125 curproxy->check_req[12] = 33;
5126 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5127 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5128 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5129 cur_arg += 3;
5130 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005131 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'post-41'.\n", file, linenum, args[cur_arg+2]);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005132 err_code |= ERR_ALERT | ERR_FATAL;
5133 goto out;
5134 }
5135 } else {
5136 packetlen = userlen + 7;
5137 reqlen = packetlen + 9;
5138
5139 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005140 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005141 curproxy->check_len = reqlen;
5142
5143 snprintf(curproxy->check_req, 4, "%c%c%c",
5144 ((unsigned char) packetlen & 0xff),
5145 ((unsigned char) (packetlen >> 8) & 0xff),
5146 ((unsigned char) (packetlen >> 16) & 0xff));
5147
5148 curproxy->check_req[3] = 1;
Olivier Houchard33320902018-10-16 18:39:38 +02005149 curproxy->check_req[5] = 0x80;
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005150 curproxy->check_req[8] = 1;
5151 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5152 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5153 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5154 cur_arg += 2;
5155 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005156 } else {
5157 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005158 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5159 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005160 err_code |= ERR_ALERT | ERR_FATAL;
5161 goto out;
5162 }
5163 } /* end while loop */
5164 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005165 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005166 else if (!strcmp(args[1], "ldap-check")) {
5167 /* use LDAP request to check servers' health */
5168 free(curproxy->check_req);
5169 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005170 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005171 curproxy->options2 |= PR_O2_LDAP_CHK;
5172
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005173 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005174 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5175 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005176 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5177 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005178 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005179 else if (!strcmp(args[1], "spop-check")) {
5180 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005181 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5182 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005183 err_code |= ERR_ALERT | ERR_FATAL;
5184 goto out;
5185 }
5186 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005187 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5188 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005189 err_code |= ERR_ALERT | ERR_FATAL;
5190 goto out;
5191 }
5192
5193 /* use SPOE request to check servers' health */
5194 free(curproxy->check_req);
5195 curproxy->check_req = NULL;
5196 curproxy->options2 &= ~PR_O2_CHK_ANY;
5197 curproxy->options2 |= PR_O2_SPOP_CHK;
5198
Christopher Faulet8ef75252017-02-20 22:56:03 +01005199 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005200 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005201 err_code |= ERR_ALERT | ERR_FATAL;
5202 goto out;
5203 }
5204 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5205 goto out;
5206 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005207 else if (!strcmp(args[1], "tcp-check")) {
5208 /* use raw TCPCHK send/expect to check servers' health */
5209 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5210 err_code |= ERR_WARN;
5211
5212 free(curproxy->check_req);
5213 curproxy->check_req = NULL;
5214 curproxy->options2 &= ~PR_O2_CHK_ANY;
5215 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005216 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5217 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005218 }
Simon Horman98637e52014-06-20 12:30:16 +09005219 else if (!strcmp(args[1], "external-check")) {
5220 /* excute an external command to check servers' health */
5221 free(curproxy->check_req);
5222 curproxy->check_req = NULL;
5223 curproxy->options2 &= ~PR_O2_CHK_ANY;
5224 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005225 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5226 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005227 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005228 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005229 int cur_arg;
5230
5231 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5232 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005233 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005234
Willy Tarreau87cf5142011-08-19 22:57:24 +02005235 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005236
5237 free(curproxy->fwdfor_hdr_name);
5238 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5239 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5240
5241 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5242 cur_arg = 2;
5243 while (*(args[cur_arg])) {
5244 if (!strcmp(args[cur_arg], "except")) {
5245 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005246 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005247 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5248 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005249 err_code |= ERR_ALERT | ERR_FATAL;
5250 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005251 }
5252 /* flush useless bits */
5253 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005254 cur_arg += 2;
5255 } else if (!strcmp(args[cur_arg], "header")) {
5256 /* suboption header - needs additional argument for it */
5257 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005258 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5259 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005260 err_code |= ERR_ALERT | ERR_FATAL;
5261 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005262 }
5263 free(curproxy->fwdfor_hdr_name);
5264 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5265 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5266 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005267 } else if (!strcmp(args[cur_arg], "if-none")) {
5268 curproxy->options &= ~PR_O_FF_ALWAYS;
5269 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005270 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005271 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005272 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5273 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005274 err_code |= ERR_ALERT | ERR_FATAL;
5275 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005276 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005277 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005278 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005279 else if (!strcmp(args[1], "originalto")) {
5280 int cur_arg;
5281
5282 /* insert x-original-to field, but not for the IP address listed as an except.
5283 * set default options (ie: bitfield, header name, etc)
5284 */
5285
5286 curproxy->options |= PR_O_ORGTO;
5287
5288 free(curproxy->orgto_hdr_name);
5289 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5290 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5291
Willy Tarreau87cf5142011-08-19 22:57:24 +02005292 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005293 cur_arg = 2;
5294 while (*(args[cur_arg])) {
5295 if (!strcmp(args[cur_arg], "except")) {
5296 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005297 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_to, &curproxy->except_mask_to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005298 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5299 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005300 err_code |= ERR_ALERT | ERR_FATAL;
5301 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005302 }
5303 /* flush useless bits */
5304 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5305 cur_arg += 2;
5306 } else if (!strcmp(args[cur_arg], "header")) {
5307 /* suboption header - needs additional argument for it */
5308 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005309 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5310 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005311 err_code |= ERR_ALERT | ERR_FATAL;
5312 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005313 }
5314 free(curproxy->orgto_hdr_name);
5315 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5316 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5317 cur_arg += 2;
5318 } else {
5319 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005320 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5321 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005322 err_code |= ERR_ALERT | ERR_FATAL;
5323 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005324 }
5325 } /* end while loop */
5326 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005327 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005328 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005329 err_code |= ERR_ALERT | ERR_FATAL;
5330 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005331 }
Willy Tarreau93893792009-07-23 13:19:11 +02005332 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005333 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005334 else if (!strcmp(args[0], "default_backend")) {
5335 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005336 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005337
5338 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005339 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005340 err_code |= ERR_ALERT | ERR_FATAL;
5341 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005342 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005343 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005344 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005345
5346 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5347 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005348 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005349 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005350 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005351 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005352
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005353 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005354 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5355 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005356 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005357 /* enable reconnections to dispatch */
5358 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005359
5360 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5361 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005362 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005363 else if (!strcmp(args[0], "http-reuse")) {
5364 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5365 err_code |= ERR_WARN;
5366
5367 if (strcmp(args[1], "never") == 0) {
5368 /* enable a graceful server shutdown on an HTTP 404 response */
5369 curproxy->options &= ~PR_O_REUSE_MASK;
5370 curproxy->options |= PR_O_REUSE_NEVR;
5371 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5372 goto out;
5373 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005374 else if (strcmp(args[1], "safe") == 0) {
5375 /* enable a graceful server shutdown on an HTTP 404 response */
5376 curproxy->options &= ~PR_O_REUSE_MASK;
5377 curproxy->options |= PR_O_REUSE_SAFE;
5378 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5379 goto out;
5380 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005381 else if (strcmp(args[1], "aggressive") == 0) {
5382 curproxy->options &= ~PR_O_REUSE_MASK;
5383 curproxy->options |= PR_O_REUSE_AGGR;
5384 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5385 goto out;
5386 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005387 else if (strcmp(args[1], "always") == 0) {
5388 /* enable a graceful server shutdown on an HTTP 404 response */
5389 curproxy->options &= ~PR_O_REUSE_MASK;
5390 curproxy->options |= PR_O_REUSE_ALWS;
5391 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5392 goto out;
5393 }
5394 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005395 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005396 err_code |= ERR_ALERT | ERR_FATAL;
5397 goto out;
5398 }
5399 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005400 else if (!strcmp(args[0], "http-check")) {
5401 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005402 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005403
5404 if (strcmp(args[1], "disable-on-404") == 0) {
5405 /* enable a graceful server shutdown on an HTTP 404 response */
5406 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005407 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5408 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005409 }
Willy Tarreauef781042010-01-27 11:53:01 +01005410 else if (strcmp(args[1], "send-state") == 0) {
5411 /* enable emission of the apparent state of a server in HTTP checks */
5412 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005413 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5414 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005415 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005416 else if (strcmp(args[1], "expect") == 0) {
5417 const char *ptr_arg;
5418 int cur_arg;
5419
5420 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005421 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005422 err_code |= ERR_ALERT | ERR_FATAL;
5423 goto out;
5424 }
5425
5426 cur_arg = 2;
5427 /* consider exclamation marks, sole or at the beginning of a word */
5428 while (*(ptr_arg = args[cur_arg])) {
5429 while (*ptr_arg == '!') {
5430 curproxy->options2 ^= PR_O2_EXP_INV;
5431 ptr_arg++;
5432 }
5433 if (*ptr_arg)
5434 break;
5435 cur_arg++;
5436 }
5437 /* now ptr_arg points to the beginning of a word past any possible
5438 * exclamation mark, and cur_arg is the argument which holds this word.
5439 */
5440 if (strcmp(ptr_arg, "status") == 0) {
5441 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005442 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5443 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005444 err_code |= ERR_ALERT | ERR_FATAL;
5445 goto out;
5446 }
5447 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005448 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005449 curproxy->expect_str = strdup(args[cur_arg + 1]);
5450 }
5451 else if (strcmp(ptr_arg, "string") == 0) {
5452 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005453 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5454 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005455 err_code |= ERR_ALERT | ERR_FATAL;
5456 goto out;
5457 }
5458 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005459 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005460 curproxy->expect_str = strdup(args[cur_arg + 1]);
5461 }
5462 else if (strcmp(ptr_arg, "rstatus") == 0) {
5463 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005464 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5465 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005466 err_code |= ERR_ALERT | ERR_FATAL;
5467 goto out;
5468 }
5469 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005470 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005471 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005472 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005473 free(curproxy->expect_regex);
5474 curproxy->expect_regex = NULL;
5475 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005476 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005477 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5478 error = NULL;
5479 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005480 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5481 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005482 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005483 err_code |= ERR_ALERT | ERR_FATAL;
5484 goto out;
5485 }
5486 }
5487 else if (strcmp(ptr_arg, "rstring") == 0) {
5488 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005489 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5490 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005491 err_code |= ERR_ALERT | ERR_FATAL;
5492 goto out;
5493 }
5494 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005495 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005496 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005497 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005498 free(curproxy->expect_regex);
5499 curproxy->expect_regex = NULL;
5500 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005501 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005502 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5503 error = NULL;
5504 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005505 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5506 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005507 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005508 err_code |= ERR_ALERT | ERR_FATAL;
5509 goto out;
5510 }
5511 }
5512 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005513 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5514 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005515 err_code |= ERR_ALERT | ERR_FATAL;
5516 goto out;
5517 }
5518 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005519 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005520 ha_alert("parsing [%s:%d] : '%s' only supports 'disable-on-404', 'send-state', 'expect'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005521 err_code |= ERR_ALERT | ERR_FATAL;
5522 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005523 }
5524 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005525 else if (!strcmp(args[0], "tcp-check")) {
5526 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5527 err_code |= ERR_WARN;
5528
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005529 if (strcmp(args[1], "comment") == 0) {
5530 int cur_arg;
5531 struct tcpcheck_rule *tcpcheck;
5532
5533 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005534 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005535 tcpcheck->action = TCPCHK_ACT_COMMENT;
5536
5537 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005538 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5539 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005540 err_code |= ERR_ALERT | ERR_FATAL;
5541 goto out;
5542 }
5543
5544 tcpcheck->comment = strdup(args[cur_arg + 1]);
5545
5546 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005547 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5548 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005549 }
5550 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005551 const char *ptr_arg;
5552 int cur_arg;
5553 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005554
5555 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005556 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5557 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5558 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5559 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5560 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005561
Willy Tarreau5581c272015-05-13 12:24:53 +02005562 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5563 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005564 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5565 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005566 err_code |= ERR_ALERT | ERR_FATAL;
5567 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005568 }
5569
5570 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005571 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005572 tcpcheck->action = TCPCHK_ACT_CONNECT;
5573
5574 /* parsing each parameters to fill up the rule */
5575 while (*(ptr_arg = args[cur_arg])) {
5576 /* tcp port */
5577 if (strcmp(args[cur_arg], "port") == 0) {
5578 if ( (atol(args[cur_arg + 1]) > 65535) ||
5579 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005580 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5581 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005582 err_code |= ERR_ALERT | ERR_FATAL;
5583 goto out;
5584 }
5585 tcpcheck->port = atol(args[cur_arg + 1]);
5586 cur_arg += 2;
5587 }
5588 /* send proxy protocol */
5589 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5590 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5591 cur_arg++;
5592 }
5593#ifdef USE_OPENSSL
5594 else if (strcmp(args[cur_arg], "ssl") == 0) {
5595 curproxy->options |= PR_O_TCPCHK_SSL;
5596 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5597 cur_arg++;
5598 }
5599#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005600 /* comment for this tcpcheck line */
5601 else if (strcmp(args[cur_arg], "comment") == 0) {
5602 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005603 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5604 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005605 err_code |= ERR_ALERT | ERR_FATAL;
5606 goto out;
5607 }
5608 tcpcheck->comment = strdup(args[cur_arg + 1]);
5609 cur_arg += 2;
5610 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005611 else {
5612#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005613 ha_alert("parsing [%s:%d] : '%s %s' expects 'comment', 'port', 'send-proxy' or 'ssl' but got '%s' as argument.\n",
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005614#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005615 ha_alert("parsing [%s:%d] : '%s %s' expects 'comment', 'port', 'send-proxy' or but got '%s' as argument.\n",
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005616#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005617 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005618 err_code |= ERR_ALERT | ERR_FATAL;
5619 goto out;
5620 }
5621
5622 }
5623
5624 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5625 }
5626 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005627 if (! *(args[2]) ) {
5628 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005629 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5630 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005631 err_code |= ERR_ALERT | ERR_FATAL;
5632 goto out;
5633 } else {
5634 struct tcpcheck_rule *tcpcheck;
5635
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005636 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005637
5638 tcpcheck->action = TCPCHK_ACT_SEND;
5639 tcpcheck->string_len = strlen(args[2]);
5640 tcpcheck->string = strdup(args[2]);
5641 tcpcheck->expect_regex = NULL;
5642
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005643 /* comment for this tcpcheck line */
5644 if (strcmp(args[3], "comment") == 0) {
5645 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005646 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5647 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005648 err_code |= ERR_ALERT | ERR_FATAL;
5649 goto out;
5650 }
5651 tcpcheck->comment = strdup(args[4]);
5652 }
5653
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005654 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5655 }
5656 }
5657 else if (strcmp(args[1], "send-binary") == 0) {
5658 if (! *(args[2]) ) {
5659 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005660 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5661 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005662 err_code |= ERR_ALERT | ERR_FATAL;
5663 goto out;
5664 } else {
5665 struct tcpcheck_rule *tcpcheck;
5666 char *err = NULL;
5667
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005668 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005669
5670 tcpcheck->action = TCPCHK_ACT_SEND;
5671 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005672 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5673 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005674 err_code |= ERR_ALERT | ERR_FATAL;
5675 goto out;
5676 }
5677 tcpcheck->expect_regex = NULL;
5678
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005679 /* comment for this tcpcheck line */
5680 if (strcmp(args[3], "comment") == 0) {
5681 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005682 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5683 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005684 err_code |= ERR_ALERT | ERR_FATAL;
5685 goto out;
5686 }
5687 tcpcheck->comment = strdup(args[4]);
5688 }
5689
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005690 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5691 }
5692 }
5693 else if (strcmp(args[1], "expect") == 0) {
5694 const char *ptr_arg;
5695 int cur_arg;
5696 int inverse = 0;
5697
5698 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005699 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005700 err_code |= ERR_ALERT | ERR_FATAL;
5701 goto out;
5702 }
5703
5704 cur_arg = 2;
5705 /* consider exclamation marks, sole or at the beginning of a word */
5706 while (*(ptr_arg = args[cur_arg])) {
5707 while (*ptr_arg == '!') {
5708 inverse = !inverse;
5709 ptr_arg++;
5710 }
5711 if (*ptr_arg)
5712 break;
5713 cur_arg++;
5714 }
5715 /* now ptr_arg points to the beginning of a word past any possible
5716 * exclamation mark, and cur_arg is the argument which holds this word.
5717 */
5718 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005719 struct tcpcheck_rule *tcpcheck;
5720 char *err = NULL;
5721
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005722 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005723 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5724 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005725 err_code |= ERR_ALERT | ERR_FATAL;
5726 goto out;
5727 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005728
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005729 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005730
5731 tcpcheck->action = TCPCHK_ACT_EXPECT;
5732 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005733 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5734 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005735 err_code |= ERR_ALERT | ERR_FATAL;
5736 goto out;
5737 }
5738 tcpcheck->expect_regex = NULL;
5739 tcpcheck->inverse = inverse;
5740
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005741 /* tcpcheck comment */
5742 cur_arg += 2;
5743 if (strcmp(args[cur_arg], "comment") == 0) {
5744 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005745 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5746 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005747 err_code |= ERR_ALERT | ERR_FATAL;
5748 goto out;
5749 }
5750 tcpcheck->comment = strdup(args[cur_arg + 1]);
5751 }
5752
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005753 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5754 }
5755 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005756 struct tcpcheck_rule *tcpcheck;
5757
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005758 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005759 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5760 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005761 err_code |= ERR_ALERT | ERR_FATAL;
5762 goto out;
5763 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005764
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005765 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005766
5767 tcpcheck->action = TCPCHK_ACT_EXPECT;
5768 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5769 tcpcheck->string = strdup(args[cur_arg + 1]);
5770 tcpcheck->expect_regex = NULL;
5771 tcpcheck->inverse = inverse;
5772
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005773 /* tcpcheck comment */
5774 cur_arg += 2;
5775 if (strcmp(args[cur_arg], "comment") == 0) {
5776 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005777 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5778 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005779 err_code |= ERR_ALERT | ERR_FATAL;
5780 goto out;
5781 }
5782 tcpcheck->comment = strdup(args[cur_arg + 1]);
5783 }
5784
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005785 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5786 }
5787 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005788 struct tcpcheck_rule *tcpcheck;
5789
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005790 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005791 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5792 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005793 err_code |= ERR_ALERT | ERR_FATAL;
5794 goto out;
5795 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005796
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005797 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005798
5799 tcpcheck->action = TCPCHK_ACT_EXPECT;
5800 tcpcheck->string_len = 0;
5801 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005802 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5803 error = NULL;
5804 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005805 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5806 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005807 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005808 err_code |= ERR_ALERT | ERR_FATAL;
5809 goto out;
5810 }
5811 tcpcheck->inverse = inverse;
5812
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005813 /* tcpcheck comment */
5814 cur_arg += 2;
5815 if (strcmp(args[cur_arg], "comment") == 0) {
5816 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005817 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5818 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005819 err_code |= ERR_ALERT | ERR_FATAL;
5820 goto out;
5821 }
5822 tcpcheck->comment = strdup(args[cur_arg + 1]);
5823 }
5824
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005825 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5826 }
5827 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005828 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5829 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005830 err_code |= ERR_ALERT | ERR_FATAL;
5831 goto out;
5832 }
5833 }
5834 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005835 ha_alert("parsing [%s:%d] : '%s' only supports 'comment', 'connect', 'send' or 'expect'.\n", file, linenum, args[0]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005836 err_code |= ERR_ALERT | ERR_FATAL;
5837 goto out;
5838 }
5839 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005840 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005841 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005842 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005843 err_code |= ERR_ALERT | ERR_FATAL;
5844 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005845 }
5846
Willy Tarreaub80c2302007-11-30 20:51:32 +01005847 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005848 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005849
5850 if (strcmp(args[1], "fail") == 0) {
5851 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005852 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005853 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5854 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005855 err_code |= ERR_ALERT | ERR_FATAL;
5856 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005857 }
5858
Willy Tarreau721d8e02017-12-01 18:25:08 +01005859 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005860 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005861 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5862 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005863 err_code |= ERR_ALERT | ERR_FATAL;
5864 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005865 }
5866 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5867 }
5868 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005869 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005870 err_code |= ERR_ALERT | ERR_FATAL;
5871 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005872 }
5873 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005874#ifdef TPROXY
5875 else if (!strcmp(args[0], "transparent")) {
5876 /* enable transparent proxy connections */
5877 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005878 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5879 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005880 }
5881#endif
5882 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005883 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005884 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005885
Willy Tarreaubaaee002006-06-26 02:48:02 +02005886 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005887 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005888 err_code |= ERR_ALERT | ERR_FATAL;
5889 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005890 }
5891 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005892 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5893 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005894 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005895 else if (!strcmp(args[0], "backlog")) { /* backlog */
5896 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005897 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005898
5899 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005900 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005901 err_code |= ERR_ALERT | ERR_FATAL;
5902 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005903 }
5904 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005905 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5906 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005907 }
Willy Tarreau86034312006-12-29 00:10:33 +01005908 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005909 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005910 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005911
Willy Tarreau86034312006-12-29 00:10:33 +01005912 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005913 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005914 err_code |= ERR_ALERT | ERR_FATAL;
5915 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005916 }
5917 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005918 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5919 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005920 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005921 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5922 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005923 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005924 err_code |= ERR_ALERT | ERR_FATAL;
5925 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005926 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005927 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5928 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005929 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5930 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005931 err_code |= ERR_ALERT | ERR_FATAL;
5932 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005933 }
5934 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005935 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5936 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005937 }
5938 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005939 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005940 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005941 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005942
Willy Tarreaubaaee002006-06-26 02:48:02 +02005943 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005944 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005945 err_code |= ERR_ALERT | ERR_FATAL;
5946 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005947 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005948 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005949 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005950
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005951 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005952 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005953 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005954 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005955 goto out;
5956 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005957
5958 proto = protocol_by_family(sk->ss_family);
5959 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005960 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5961 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005962 err_code |= ERR_ALERT | ERR_FATAL;
5963 goto out;
5964 }
5965
5966 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005967 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5968 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005969 err_code |= ERR_ALERT | ERR_FATAL;
5970 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005971 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005972
5973 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005974 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5975 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005976 err_code |= ERR_ALERT | ERR_FATAL;
5977 goto out;
5978 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005979
William Lallemanddf1425a2015-04-28 20:17:49 +02005980 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5981 goto out;
5982
Willy Tarreaud5191e72010-02-09 20:50:45 +01005983 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005984 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005985 }
5986 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005987 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005988 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005989
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005990 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005991 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005992 err_code |= ERR_ALERT | ERR_FATAL;
5993 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005994 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005995 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005996 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005997 /**
5998 * The syntax for hash-type config element is
5999 * hash-type {map-based|consistent} [[<algo>] avalanche]
6000 *
6001 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
6002 */
6003 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04006004
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006005 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
6006 err_code |= ERR_WARN;
6007
6008 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006009 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
6010 }
6011 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006012 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
6013 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006014 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006015 ha_alert("parsing [%s:%d] : experimental feature '%s %s' is not supported anymore, please use '%s map-based sdbm avalanche' instead.\n", file, linenum, args[0], args[1], args[0]);
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006016 err_code |= ERR_ALERT | ERR_FATAL;
6017 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01006018 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006019 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006020 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006021 err_code |= ERR_ALERT | ERR_FATAL;
6022 goto out;
6023 }
Bhaskar98634f02013-10-29 23:30:51 -04006024
6025 /* set the hash function to use */
6026 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006027 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04006028 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006029
6030 /* if consistent with no argument, then avalanche modifier is also applied */
6031 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6032 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006033 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006034 /* set the hash function */
6035 if (!strcmp(args[2], "sdbm")) {
6036 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6037 }
6038 else if (!strcmp(args[2], "djb2")) {
6039 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006040 }
6041 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006042 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006043 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006044 else if (!strcmp(args[2], "crc32")) {
6045 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6046 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006047 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006048 ha_alert("parsing [%s:%d] : '%s' only supports 'sdbm', 'djb2', 'crc32', or 'wt6' hash functions.\n", file, linenum, args[0]);
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006049 err_code |= ERR_ALERT | ERR_FATAL;
6050 goto out;
6051 }
6052
6053 /* set the hash modifier */
6054 if (!strcmp(args[3], "avalanche")) {
6055 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6056 }
6057 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006058 ha_alert("parsing [%s:%d] : '%s' only supports 'avalanche' as a modifier for hash functions.\n", file, linenum, args[0]);
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006059 err_code |= ERR_ALERT | ERR_FATAL;
6060 goto out;
6061 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006062 }
William Lallemanda73203e2012-03-12 12:48:57 +01006063 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006064 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6065 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006066 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006067 err_code |= ERR_ALERT | ERR_FATAL;
6068 goto out;
6069 }
6070 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6071 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006072 ha_alert("parsing [%s:%d] : '%s' must be 0 or greater than 100.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006073 err_code |= ERR_ALERT | ERR_FATAL;
6074 goto out;
6075 }
6076 }
William Lallemanda73203e2012-03-12 12:48:57 +01006077 else if (strcmp(args[0], "unique-id-format") == 0) {
6078 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006079 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006080 err_code |= ERR_ALERT | ERR_FATAL;
6081 goto out;
6082 }
William Lallemand3203ff42012-11-11 17:30:56 +01006083 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006084 ha_alert("parsing [%s:%d] : %s expects only one argument, don't forget to escape spaces!\n", file, linenum, args[0]);
William Lallemand3203ff42012-11-11 17:30:56 +01006085 err_code |= ERR_ALERT | ERR_FATAL;
6086 goto out;
6087 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006088 free(curproxy->conf.uniqueid_format_string);
6089 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006090
Willy Tarreau62a61232013-04-12 18:13:46 +02006091 free(curproxy->conf.uif_file);
6092 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6093 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006094 }
William Lallemanda73203e2012-03-12 12:48:57 +01006095
6096 else if (strcmp(args[0], "unique-id-header") == 0) {
6097 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006098 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006099 err_code |= ERR_ALERT | ERR_FATAL;
6100 goto out;
6101 }
6102 free(curproxy->header_unique_id);
6103 curproxy->header_unique_id = strdup(args[1]);
6104 }
6105
William Lallemand723b73a2012-02-08 16:37:49 +01006106 else if (strcmp(args[0], "log-format") == 0) {
6107 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006108 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006109 err_code |= ERR_ALERT | ERR_FATAL;
6110 goto out;
6111 }
William Lallemand3203ff42012-11-11 17:30:56 +01006112 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006113 ha_alert("parsing [%s:%d] : %s expects only one argument, don't forget to escape spaces!\n", file, linenum, args[0]);
William Lallemand3203ff42012-11-11 17:30:56 +01006114 err_code |= ERR_ALERT | ERR_FATAL;
6115 goto out;
6116 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006117 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6118 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006119
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006120 if (curproxy->conf.logformat_string == default_http_log_format)
6121 oldlogformat = "option httplog";
6122 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6123 oldlogformat = "option tcplog";
6124 else if (curproxy->conf.logformat_string == clf_http_log_format)
6125 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006126 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6127 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006128 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006129 if (curproxy->conf.logformat_string != default_http_log_format &&
6130 curproxy->conf.logformat_string != default_tcp_log_format &&
6131 curproxy->conf.logformat_string != clf_http_log_format)
6132 free(curproxy->conf.logformat_string);
6133 curproxy->conf.logformat_string = strdup(args[1]);
6134
6135 free(curproxy->conf.lfs_file);
6136 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6137 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006138
6139 /* get a chance to improve log-format error reporting by
6140 * reporting the correct line-number when possible.
6141 */
6142 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006143 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6144 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006145 err_code |= ERR_WARN;
6146 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006147 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006148 else if (!strcmp(args[0], "log-format-sd")) {
6149 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006150 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006151 err_code |= ERR_ALERT | ERR_FATAL;
6152 goto out;
6153 }
6154 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006155 ha_alert("parsing [%s:%d] : %s expects only one argument, don't forget to escape spaces!\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006156 err_code |= ERR_ALERT | ERR_FATAL;
6157 goto out;
6158 }
6159
6160 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6161 free(curproxy->conf.logformat_sd_string);
6162 curproxy->conf.logformat_sd_string = strdup(args[1]);
6163
6164 free(curproxy->conf.lfsd_file);
6165 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6166 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6167
6168 /* get a chance to improve log-format-sd error reporting by
6169 * reporting the correct line-number when possible.
6170 */
6171 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006172 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6173 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006174 err_code |= ERR_WARN;
6175 }
6176 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006177 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6178 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006179 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Willy Tarreau094af4e2015-01-07 15:03:42 +01006180 err_code |= ERR_ALERT | ERR_FATAL;
6181 goto out;
6182 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006183 chunk_destroy(&curproxy->log_tag);
6184 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006185 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006186 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6187 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6188 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006189 err_code |= ERR_ALERT | ERR_FATAL;
6190 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006191 }
6192 }
6193 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006194 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006195 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006196 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006197 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006198
Willy Tarreau977b8e42006-12-29 14:19:17 +01006199 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006200 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006201
Willy Tarreaubaaee002006-06-26 02:48:02 +02006202 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006203 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6204 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006205 err_code |= ERR_ALERT | ERR_FATAL;
6206 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006207 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006208
6209 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006210 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6211 free(curproxy->conn_src.iface_name);
6212 curproxy->conn_src.iface_name = NULL;
6213 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006214
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006215 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006216 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006217 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6218 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006219 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006220 goto out;
6221 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006222
6223 proto = protocol_by_family(sk->ss_family);
6224 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006225 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6226 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006227 err_code |= ERR_ALERT | ERR_FATAL;
6228 goto out;
6229 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006230
6231 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006232 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6233 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006234 err_code |= ERR_ALERT | ERR_FATAL;
6235 goto out;
6236 }
6237
Willy Tarreauef9a3602012-12-08 22:29:20 +01006238 curproxy->conn_src.source_addr = *sk;
6239 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006240
6241 cur_arg = 2;
6242 while (*(args[cur_arg])) {
6243 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006244#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006245 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006246 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6247 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006248 err_code |= ERR_ALERT | ERR_FATAL;
6249 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006250 }
6251
6252 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006253 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6254 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006255 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006256 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6257 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006258 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6259 char *name, *end;
6260
6261 name = args[cur_arg+1] + 7;
6262 while (isspace(*name))
6263 name++;
6264
6265 end = name;
6266 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6267 end++;
6268
Willy Tarreauef9a3602012-12-08 22:29:20 +01006269 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6270 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6271 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6272 curproxy->conn_src.bind_hdr_len = end - name;
6273 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6274 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6275 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006276
6277 /* now look for an occurrence number */
6278 while (isspace(*end))
6279 end++;
6280 if (*end == ',') {
6281 end++;
6282 name = end;
6283 if (*end == '-')
6284 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006285 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006286 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006287 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006288 }
6289
Willy Tarreauef9a3602012-12-08 22:29:20 +01006290 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006291 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6292 " occurrences values smaller than %d.\n",
6293 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006294 err_code |= ERR_ALERT | ERR_FATAL;
6295 goto out;
6296 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006297 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006298 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006299
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006300 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006301 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006302 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6303 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006304 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006305 goto out;
6306 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006307
6308 proto = protocol_by_family(sk->ss_family);
6309 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006310 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6311 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006312 err_code |= ERR_ALERT | ERR_FATAL;
6313 goto out;
6314 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006315
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006316 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006317 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6318 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006319 err_code |= ERR_ALERT | ERR_FATAL;
6320 goto out;
6321 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006322 curproxy->conn_src.tproxy_addr = *sk;
6323 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006324 }
6325 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006326#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006327 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6328 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006329 err_code |= ERR_ALERT | ERR_FATAL;
6330 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006331#endif
6332 cur_arg += 2;
6333 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006334 }
6335
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006336 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6337#ifdef SO_BINDTODEVICE
6338 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006339 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6340 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006341 err_code |= ERR_ALERT | ERR_FATAL;
6342 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006343 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006344 free(curproxy->conn_src.iface_name);
6345 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6346 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006347 global.last_checks |= LSTCHK_NETADM;
6348#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006349 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6350 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006351 err_code |= ERR_ALERT | ERR_FATAL;
6352 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006353#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006354 cur_arg += 2;
6355 continue;
6356 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006357 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6358 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006359 err_code |= ERR_ALERT | ERR_FATAL;
6360 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006361 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006362 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006363 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006364 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6365 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006366 err_code |= ERR_ALERT | ERR_FATAL;
6367 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006368 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006369 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006370 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006371 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6372 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006373 err_code |= ERR_ALERT | ERR_FATAL;
6374 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006375 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006376
6377 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006378 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006379 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006380 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006381 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006382 }
6383 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006384 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006385 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006386 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006387 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006388 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006389 }
6390 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006391 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006392 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006393 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006394 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006395 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006396 }
6397 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006398 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006399 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006400 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006401 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006402 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006403 }
6404 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006405 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006406 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006407 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006408 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006409 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006410 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006411 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006412 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006413 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006414 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006415 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006416 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006417 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006418 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006419 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006420 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6421 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006422 err_code |= ERR_ALERT | ERR_FATAL;
6423 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006424 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006425
6426 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006427 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006428 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006429 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006430 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006431 }
6432 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006433 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006434 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006435 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006436 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006437 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006438 }
6439 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006440 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006441 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006442 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006443 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006444 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006445 }
6446 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006447 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006448 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006449 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006450 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006451 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006452 }
6453 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006454 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006455 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006456 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006457 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006458 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006459 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006460 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006461 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006462 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006463 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006464 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006465 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006466 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006467 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006468 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006469
Willy Tarreaubaaee002006-06-26 02:48:02 +02006470 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006471 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006472 err_code |= ERR_ALERT | ERR_FATAL;
6473 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006474 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006475 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006476 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006477
Willy Tarreaubaaee002006-06-26 02:48:02 +02006478 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006479 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006480 err_code |= ERR_ALERT | ERR_FATAL;
6481 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006482 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006483
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006484 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006485 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006486 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6487 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006488 err_code |= ERR_ALERT | ERR_FATAL;
6489 goto out;
6490 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006491 err_code |= warnif_cond_conflicts(cond,
6492 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6493 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006494 }
6495 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006496 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6497 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006498 err_code |= ERR_ALERT | ERR_FATAL;
6499 goto out;
6500 }
6501
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006502 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006503 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006504 wl->s = strdup(args[1]);
6505 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006506 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006507 }
6508 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006509 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006510 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6511 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006512 err_code |= ERR_ALERT | ERR_FATAL;
6513 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006514 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006515
Willy Tarreauade5ec42010-01-28 19:33:49 +01006516 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006517 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006518 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006519 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006520 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006521 }
6522 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006523 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006524 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006525 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006526 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006527 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006528 }
6529 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006530 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006531 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006532 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006533 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006534 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006535 }
6536 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006537 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006538 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6539 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006540 err_code |= ERR_ALERT | ERR_FATAL;
6541 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006542 }
6543
Willy Tarreauade5ec42010-01-28 19:33:49 +01006544 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006545 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006546 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006547 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006548 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006549 }
6550 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006551 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006552 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006553 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006554 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006555 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006556 }
6557 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006558 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006559 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006560 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006561 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006562 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006563 }
6564 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006565 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006566
Willy Tarreaubaaee002006-06-26 02:48:02 +02006567 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006568 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006569 err_code |= ERR_ALERT | ERR_FATAL;
6570 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006571 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006572 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006573 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006574
Willy Tarreaubaaee002006-06-26 02:48:02 +02006575 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006576 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006577 err_code |= ERR_ALERT | ERR_FATAL;
6578 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006579 }
6580
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006581 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006582 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006583 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6584 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006585 err_code |= ERR_ALERT | ERR_FATAL;
6586 goto out;
6587 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006588 err_code |= warnif_cond_conflicts(cond,
6589 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6590 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006591 }
6592 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006593 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6594 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006595 err_code |= ERR_ALERT | ERR_FATAL;
6596 goto out;
6597 }
6598
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006599 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006600 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006601 wl->s = strdup(args[1]);
6602 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006603 }
6604 else if (!strcmp(args[0], "errorloc") ||
6605 !strcmp(args[0], "errorloc302") ||
6606 !strcmp(args[0], "errorloc303")) { /* error location */
6607 int errnum, errlen;
6608 char *err;
6609
Willy Tarreau977b8e42006-12-29 14:19:17 +01006610 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006611 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006612
Willy Tarreaubaaee002006-06-26 02:48:02 +02006613 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006614 ha_alert("parsing [%s:%d] : <%s> expects <status_code> and <url> as arguments.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006615 err_code |= ERR_ALERT | ERR_FATAL;
6616 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006617 }
6618
6619 errnum = atol(args[1]);
6620 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006621 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6622 err = malloc(errlen);
6623 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006624 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006625 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6626 err = malloc(errlen);
6627 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006628 }
6629
Willy Tarreau0f772532006-12-23 20:51:41 +01006630 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6631 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006632 chunk_destroy(&curproxy->errmsg[rc]);
6633 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006634 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006635 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006636 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006637
6638 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006639 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6640 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006641 free(err);
6642 }
6643 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006644 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6645 int errnum, errlen, fd;
6646 char *err;
6647 struct stat stat;
6648
6649 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006650 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006651
6652 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006653 ha_alert("parsing [%s:%d] : <%s> expects <status_code> and <file> as arguments.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006654 err_code |= ERR_ALERT | ERR_FATAL;
6655 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006656 }
6657
6658 fd = open(args[2], O_RDONLY);
6659 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006660 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6661 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006662 if (fd >= 0)
6663 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006664 err_code |= ERR_ALERT | ERR_FATAL;
6665 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006666 }
6667
Willy Tarreau27a674e2009-08-17 07:23:33 +02006668 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006669 errlen = stat.st_size;
6670 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006671 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6672 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006673 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006674 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006675 }
6676
6677 err = malloc(errlen); /* malloc() must succeed during parsing */
6678 errnum = read(fd, err, errlen);
6679 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006680 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6681 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006682 close(fd);
6683 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006684 err_code |= ERR_ALERT | ERR_FATAL;
6685 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006686 }
6687 close(fd);
6688
6689 errnum = atol(args[1]);
6690 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6691 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006692 chunk_destroy(&curproxy->errmsg[rc]);
6693 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006694 break;
6695 }
6696 }
6697
6698 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006699 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6700 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006701 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006702 free(err);
6703 }
6704 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006705 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006706 struct cfg_kw_list *kwl;
6707 int index;
6708
6709 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6710 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6711 if (kwl->kw[index].section != CFG_LISTEN)
6712 continue;
6713 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6714 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006715 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006716 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006717 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006718 err_code |= ERR_ALERT | ERR_FATAL;
6719 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006720 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006721 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006722 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006723 err_code |= ERR_WARN;
6724 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006725 }
Willy Tarreau93893792009-07-23 13:19:11 +02006726 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006727 }
6728 }
6729 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006730
Christopher Faulet767a84b2017-11-24 16:50:31 +01006731 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006732 err_code |= ERR_ALERT | ERR_FATAL;
6733 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006734 }
Willy Tarreau93893792009-07-23 13:19:11 +02006735 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006736 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006737 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006738}
6739
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006740int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006741cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6742{
6743#ifdef CONFIG_HAP_NS
6744 const char *err;
6745 const char *item = args[0];
6746
6747 if (!strcmp(item, "namespace_list")) {
6748 return 0;
6749 }
6750 else if (!strcmp(item, "namespace")) {
6751 size_t idx = 1;
6752 const char *current;
6753 while (*(current = args[idx++])) {
6754 err = invalid_char(current);
6755 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006756 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6757 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006758 return ERR_ALERT | ERR_FATAL;
6759 }
6760
6761 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006762 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6763 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006764 return ERR_ALERT | ERR_FATAL;
6765 }
6766 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006767 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6768 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006769 return ERR_ALERT | ERR_FATAL;
6770 }
6771 }
6772 }
6773
6774 return 0;
6775#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006776 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6777 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006778 return ERR_ALERT | ERR_FATAL;
6779#endif
6780}
6781
6782int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006783cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6784{
6785
6786 int err_code = 0;
6787 const char *err;
6788
6789 if (!strcmp(args[0], "userlist")) { /* new userlist */
6790 struct userlist *newul;
6791
6792 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006793 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6794 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006795 err_code |= ERR_ALERT | ERR_FATAL;
6796 goto out;
6797 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006798 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6799 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006800
6801 err = invalid_char(args[1]);
6802 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006803 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6804 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006805 err_code |= ERR_ALERT | ERR_FATAL;
6806 goto out;
6807 }
6808
6809 for (newul = userlist; newul; newul = newul->next)
6810 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006811 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6812 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006813 err_code |= ERR_WARN;
6814 goto out;
6815 }
6816
Vincent Bernat02779b62016-04-03 13:48:43 +02006817 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006818 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006819 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006820 err_code |= ERR_ALERT | ERR_ABORT;
6821 goto out;
6822 }
6823
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006824 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006825 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006826 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006827 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006828 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006829 goto out;
6830 }
6831
6832 newul->next = userlist;
6833 userlist = newul;
6834
6835 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006836 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006837 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006838 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006839
6840 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006841 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6842 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006843 err_code |= ERR_ALERT | ERR_FATAL;
6844 goto out;
6845 }
6846
6847 err = invalid_char(args[1]);
6848 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006849 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6850 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006851 err_code |= ERR_ALERT | ERR_FATAL;
6852 goto out;
6853 }
6854
William Lallemand4ac9f542015-05-28 18:03:51 +02006855 if (!userlist)
6856 goto out;
6857
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006858 for (ag = userlist->groups; ag; ag = ag->next)
6859 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006860 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6861 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006862 err_code |= ERR_ALERT;
6863 goto out;
6864 }
6865
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006866 ag = calloc(1, sizeof(*ag));
6867 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006868 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006869 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006870 goto out;
6871 }
6872
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006873 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006874 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006875 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006876 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006877 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006878 goto out;
6879 }
6880
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006881 cur_arg = 2;
6882
6883 while (*args[cur_arg]) {
6884 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006885 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006886 cur_arg += 2;
6887 continue;
6888 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006889 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6890 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006891 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006892 free(ag->groupusers);
6893 free(ag->name);
6894 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006895 goto out;
6896 }
6897 }
6898
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006899 ag->next = userlist->groups;
6900 userlist->groups = ag;
6901
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006902 } else if (!strcmp(args[0], "user")) { /* new user */
6903 struct auth_users *newuser;
6904 int cur_arg;
6905
6906 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006907 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6908 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006909 err_code |= ERR_ALERT | ERR_FATAL;
6910 goto out;
6911 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006912 if (!userlist)
6913 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006914
6915 for (newuser = userlist->users; newuser; newuser = newuser->next)
6916 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006917 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6918 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006919 err_code |= ERR_ALERT;
6920 goto out;
6921 }
6922
Vincent Bernat02779b62016-04-03 13:48:43 +02006923 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006924 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006925 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006926 err_code |= ERR_ALERT | ERR_ABORT;
6927 goto out;
6928 }
6929
6930 newuser->user = strdup(args[1]);
6931
6932 newuser->next = userlist->users;
6933 userlist->users = newuser;
6934
6935 cur_arg = 2;
6936
6937 while (*args[cur_arg]) {
6938 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006939#ifdef CONFIG_HAP_CRYPT
6940 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006941 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6942 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006943 err_code |= ERR_ALERT | ERR_FATAL;
6944 goto out;
6945 }
6946#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006947 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6948 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006949 err_code |= ERR_ALERT;
6950#endif
6951 newuser->pass = strdup(args[cur_arg + 1]);
6952 cur_arg += 2;
6953 continue;
6954 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6955 newuser->pass = strdup(args[cur_arg + 1]);
6956 newuser->flags |= AU_O_INSECURE;
6957 cur_arg += 2;
6958 continue;
6959 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006960 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006961 cur_arg += 2;
6962 continue;
6963 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006964 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6965 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006966 err_code |= ERR_ALERT | ERR_FATAL;
6967 goto out;
6968 }
6969 }
6970 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006971 ha_alert("parsing [%s:%d]: unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "users");
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006972 err_code |= ERR_ALERT | ERR_FATAL;
6973 }
6974
6975out:
6976 return err_code;
6977}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006978
Christopher Faulet79bdef32016-11-04 22:36:15 +01006979int
6980cfg_parse_scope(const char *file, int linenum, char *line)
6981{
6982 char *beg, *end, *scope = NULL;
6983 int err_code = 0;
6984 const char *err;
6985
6986 beg = line + 1;
6987 end = strchr(beg, ']');
6988
6989 /* Detect end of scope declaration */
6990 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006991 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
6992 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006993 err_code |= ERR_ALERT | ERR_FATAL;
6994 goto out;
6995 }
6996
6997 /* Get scope name and check its validity */
6998 scope = my_strndup(beg, end-beg);
6999 err = invalid_char(scope);
7000 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007001 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
7002 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007003 err_code |= ERR_ALERT | ERR_ABORT;
7004 goto out;
7005 }
7006
7007 /* Be sure to have a scope declaration alone on its line */
7008 line = end+1;
7009 while (isspace((unsigned char)*line))
7010 line++;
7011 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007012 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7013 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007014 err_code |= ERR_ALERT | ERR_ABORT;
7015 goto out;
7016 }
7017
7018 /* We have a valid scope declaration, save it */
7019 free(cfg_scope);
7020 cfg_scope = scope;
7021 scope = NULL;
7022
7023 out:
7024 free(scope);
7025 return err_code;
7026}
7027
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01007028int
7029cfg_parse_track_sc_num(unsigned int *track_sc_num,
7030 const char *arg, const char *end, char **errmsg)
7031{
7032 const char *p;
7033 unsigned int num;
7034
7035 p = arg;
7036 num = read_uint64(&arg, end);
7037
7038 if (arg != end) {
7039 memprintf(errmsg, "Wrong track-sc number '%s'", p);
7040 return -1;
7041 }
7042
7043 if (num >= MAX_SESS_STKCTR) {
7044 memprintf(errmsg, "%u track-sc number exceeding "
7045 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
7046 return -1;
7047 }
7048
7049 *track_sc_num = num;
7050 return 0;
7051}
7052
Willy Tarreaubaaee002006-06-26 02:48:02 +02007053/*
7054 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007055 * Returns the error code, 0 if OK, or any combination of :
7056 * - ERR_ABORT: must abort ASAP
7057 * - ERR_FATAL: we can continue parsing but not start the service
7058 * - ERR_WARN: a warning has been emitted
7059 * - ERR_ALERT: an alert has been emitted
7060 * Only the two first ones can stop processing, the two others are just
7061 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007062 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007063int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007064{
William Lallemand64e84512015-05-12 14:25:37 +02007065 char *thisline;
7066 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007067 FILE *f;
7068 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007069 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007070 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007071 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007072 int readbytes = 0;
7073
7074 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007075 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007076 return -1;
7077 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007078
David Carlier97880bb2016-04-08 10:35:26 +01007079 if ((f=fopen(file,"r")) == NULL) {
7080 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007081 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007082 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007083
William Lallemandb2f07452015-05-12 14:27:13 +02007084next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007085 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007086 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007087 char *end;
7088 char *args[MAX_LINE_ARGS + 1];
7089 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007090 int dquote = 0; /* double quote */
7091 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007092
Willy Tarreaubaaee002006-06-26 02:48:02 +02007093 linenum++;
7094
7095 end = line + strlen(line);
7096
William Lallemand64e84512015-05-12 14:25:37 +02007097 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007098 /* Check if we reached the limit and the last char is not \n.
7099 * Watch out for the last line without the terminating '\n'!
7100 */
William Lallemand64e84512015-05-12 14:25:37 +02007101 char *newline;
7102 int newlinesize = linesize * 2;
7103
7104 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7105 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007106 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7107 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007108 err_code |= ERR_ALERT | ERR_FATAL;
7109 continue;
7110 }
7111
7112 readbytes = linesize - 1;
7113 linesize = newlinesize;
7114 thisline = newline;
7115 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007116 }
7117
William Lallemand64e84512015-05-12 14:25:37 +02007118 readbytes = 0;
7119
Willy Tarreaubaaee002006-06-26 02:48:02 +02007120 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007121 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007122 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007123
Christopher Faulet79bdef32016-11-04 22:36:15 +01007124
7125 if (*line == '[') {/* This is the begining if a scope */
7126 err_code |= cfg_parse_scope(file, linenum, line);
7127 goto next_line;
7128 }
7129
Willy Tarreaubaaee002006-06-26 02:48:02 +02007130 arg = 0;
7131 args[arg] = line;
7132
7133 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007134 if (*line == '"' && !squote) { /* double quote outside single quotes */
7135 if (dquote)
7136 dquote = 0;
7137 else
7138 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007139 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007140 end--;
7141 }
7142 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7143 if (squote)
7144 squote = 0;
7145 else
7146 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007147 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007148 end--;
7149 }
7150 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007151 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7152 * C equivalent value. Other combinations left unchanged (eg: \1).
7153 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007154 int skip = 0;
7155 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7156 *line = line[1];
7157 skip = 1;
7158 }
7159 else if (line[1] == 'r') {
7160 *line = '\r';
7161 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007162 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007163 else if (line[1] == 'n') {
7164 *line = '\n';
7165 skip = 1;
7166 }
7167 else if (line[1] == 't') {
7168 *line = '\t';
7169 skip = 1;
7170 }
7171 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007172 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007173 unsigned char hex1, hex2;
7174 hex1 = toupper(line[2]) - '0';
7175 hex2 = toupper(line[3]) - '0';
7176 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7177 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7178 *line = (hex1<<4) + hex2;
7179 skip = 3;
7180 }
7181 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007182 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007183 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007184 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007185 } else if (line[1] == '"') {
7186 *line = '"';
7187 skip = 1;
7188 } else if (line[1] == '\'') {
7189 *line = '\'';
7190 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007191 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7192 *line = '$';
7193 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007194 }
7195 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007196 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007197 end -= skip;
7198 }
7199 line++;
7200 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007201 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007202 /* end of string, end of loop */
7203 *line = 0;
7204 break;
7205 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007206 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007207 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007208 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007209 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007210 line++;
7211 args[++arg] = line;
7212 }
William Lallemandb2f07452015-05-12 14:27:13 +02007213 else if (dquote && *line == '$') {
7214 /* environment variables are evaluated inside double quotes */
7215 char *var_beg;
7216 char *var_end;
7217 char save_char;
7218 char *value;
7219 int val_len;
7220 int newlinesize;
7221 int braces = 0;
7222
7223 var_beg = line + 1;
7224 var_end = var_beg;
7225
7226 if (*var_beg == '{') {
7227 var_beg++;
7228 var_end++;
7229 braces = 1;
7230 }
7231
7232 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007233 ha_alert("parsing [%s:%d] : Variable expansion: Unrecognized character '%c' in variable name.\n", file, linenum, *var_beg);
William Lallemandb2f07452015-05-12 14:27:13 +02007234 err_code |= ERR_ALERT | ERR_FATAL;
7235 goto next_line; /* skip current line */
7236 }
7237
7238 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7239 var_end++;
7240
7241 save_char = *var_end;
7242 *var_end = '\0';
7243 value = getenv(var_beg);
7244 *var_end = save_char;
7245 val_len = value ? strlen(value) : 0;
7246
7247 if (braces) {
7248 if (*var_end == '}') {
7249 var_end++;
7250 braces = 0;
7251 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007252 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007253 err_code |= ERR_ALERT | ERR_FATAL;
7254 goto next_line; /* skip current line */
7255 }
7256 }
7257
7258 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7259
7260 /* if not enough space in thisline */
7261 if (newlinesize > linesize) {
7262 char *newline;
7263
7264 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7265 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007266 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007267 err_code |= ERR_ALERT | ERR_FATAL;
7268 goto next_line; /* slip current line */
7269 }
7270 /* recompute pointers if realloc returns a new pointer */
7271 if (newline != thisline) {
7272 int i;
7273 int diff;
7274
7275 for (i = 0; i <= arg; i++) {
7276 diff = args[i] - thisline;
7277 args[i] = newline + diff;
7278 }
7279
7280 diff = var_end - thisline;
7281 var_end = newline + diff;
7282 diff = end - thisline;
7283 end = newline + diff;
7284 diff = line - thisline;
7285 line = newline + diff;
7286 thisline = newline;
7287 }
7288 linesize = newlinesize;
7289 }
7290
7291 /* insert value inside the line */
7292 memmove(line + val_len, var_end, end - var_end + 1);
7293 memcpy(line, value, val_len);
7294 end += val_len - (var_end - line);
7295 line += val_len;
7296 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007297 else {
7298 line++;
7299 }
7300 }
William Lallemandb2f07452015-05-12 14:27:13 +02007301
William Lallemandf9873ba2015-05-05 17:37:14 +02007302 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007303 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007304 err_code |= ERR_ALERT | ERR_FATAL;
7305 }
7306
7307 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007308 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007309 err_code |= ERR_ALERT | ERR_FATAL;
7310 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007311
7312 /* empty line */
7313 if (!**args)
7314 continue;
7315
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007316 if (*line) {
7317 /* we had to stop due to too many args.
7318 * Let's terminate the string, print the offending part then cut the
7319 * last arg.
7320 */
7321 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7322 line++;
7323 *line = '\0';
7324
Christopher Faulet767a84b2017-11-24 16:50:31 +01007325 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7326 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007327 err_code |= ERR_ALERT | ERR_FATAL;
7328 args[arg] = line;
7329 }
7330
Willy Tarreau540abe42007-05-02 20:50:16 +02007331 /* zero out remaining args and ensure that at least one entry
7332 * is zeroed out.
7333 */
7334 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007335 args[arg] = line;
7336 }
7337
Willy Tarreau3842f002009-06-14 11:39:52 +02007338 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007339 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007340 char *tmp;
7341
Willy Tarreau3842f002009-06-14 11:39:52 +02007342 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007343 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007344 for (arg=0; *args[arg+1]; arg++)
7345 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007346 *tmp = '\0'; // fix the next arg to \0
7347 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007348 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007349 else if (!strcmp(args[0], "default")) {
7350 kwm = KWM_DEF;
7351 for (arg=0; *args[arg+1]; arg++)
7352 args[arg] = args[arg+1]; // shift args after inversion
7353 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007354
William Lallemand0f99e342011-10-12 17:50:54 +02007355 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7356 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007357 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007358 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007359 }
7360
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007361 /* detect section start */
7362 list_for_each_entry(ics, &sections, list) {
7363 if (strcmp(args[0], ics->section_name) == 0) {
7364 cursection = ics->section_name;
7365 cs = ics;
7366 break;
7367 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007368 }
7369
William Lallemandd2ff56d2017-10-16 11:06:50 +02007370 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007371 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007372 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007373 } else {
7374 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007375
William Lallemandd2ff56d2017-10-16 11:06:50 +02007376 if (pcs != cs && pcs && pcs->post_section_parser) {
7377 err_code |= pcs->post_section_parser();
7378 if (err_code & ERR_ABORT)
7379 goto err;
7380 }
7381
7382 err_code |= cs->section_parser(file, linenum, args, kwm);
7383 if (err_code & ERR_ABORT)
7384 goto err;
7385 }
7386 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007387 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007388
7389 if (pcs == cs && pcs && pcs->post_section_parser)
7390 err_code |= pcs->post_section_parser();
7391
7392err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007393 free(cfg_scope);
7394 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007395 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007396 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007397 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007398 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007399}
7400
Willy Tarreau64ab6072014-09-16 12:17:36 +02007401/* This function propagates processes from frontend <from> to backend <to> so
7402 * that it is always guaranteed that a backend pointed to by a frontend is
7403 * bound to all of its processes. After that, if the target is a "listen"
7404 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007405 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007406 * checked first to ensure that <to> is already bound to all processes of
7407 * <from>, there is no risk of looping and we ensure to follow the shortest
7408 * path to the destination.
7409 *
7410 * It is possible to set <to> to NULL for the first call so that the function
7411 * takes care of visiting the initial frontend in <from>.
7412 *
7413 * It is important to note that the function relies on the fact that all names
7414 * have already been resolved.
7415 */
7416void propagate_processes(struct proxy *from, struct proxy *to)
7417{
7418 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007419
7420 if (to) {
7421 /* check whether we need to go down */
7422 if (from->bind_proc &&
7423 (from->bind_proc & to->bind_proc) == from->bind_proc)
7424 return;
7425
7426 if (!from->bind_proc && !to->bind_proc)
7427 return;
7428
7429 to->bind_proc = from->bind_proc ?
7430 (to->bind_proc | from->bind_proc) : 0;
7431
7432 /* now propagate down */
7433 from = to;
7434 }
7435
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007436 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007437 return;
7438
Willy Tarreauf6b70012014-12-18 14:00:43 +01007439 if (from->state == PR_STSTOPPED)
7440 return;
7441
Willy Tarreau64ab6072014-09-16 12:17:36 +02007442 /* default_backend */
7443 if (from->defbe.be)
7444 propagate_processes(from, from->defbe.be);
7445
7446 /* use_backend */
7447 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007448 if (rule->dynamic)
7449 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007450 to = rule->be.backend;
7451 propagate_processes(from, to);
7452 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007453}
7454
Willy Tarreaubb925012009-07-23 13:36:36 +02007455/*
7456 * Returns the error code, 0 if OK, or any combination of :
7457 * - ERR_ABORT: must abort ASAP
7458 * - ERR_FATAL: we can continue parsing but not start the service
7459 * - ERR_WARN: a warning has been emitted
7460 * - ERR_ALERT: an alert has been emitted
7461 * Only the two first ones can stop processing, the two others are just
7462 * indicators.
7463 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007464int check_config_validity()
7465{
7466 int cfgerr = 0;
7467 struct proxy *curproxy = NULL;
7468 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007469 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007470 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007471 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007472 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007473 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06007474 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007475
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007476 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007477 /*
7478 * Now, check for the integrity of all that we have collected.
7479 */
7480
7481 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007482 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007483
Willy Tarreau193b8c62012-11-22 00:17:38 +01007484 if (!global.tune.max_http_hdr)
7485 global.tune.max_http_hdr = MAX_HTTP_HDR;
7486
7487 if (!global.tune.cookie_len)
7488 global.tune.cookie_len = CAPTURE_LEN;
7489
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007490 if (!global.tune.requri_len)
7491 global.tune.requri_len = REQURI_LEN;
7492
Willy Tarreaubafbe012017-11-24 17:34:44 +01007493 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007494
Willy Tarreaubafbe012017-11-24 17:34:44 +01007495 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007496
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007497 /* Post initialisation of the users and groups lists. */
7498 err_code = userlist_postinit();
7499 if (err_code != ERR_NONE)
7500 goto out;
7501
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007502 /* first, we will invert the proxy list order */
7503 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007504 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007505 struct proxy *next;
7506
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007507 next = proxies_list->next;
7508 proxies_list->next = curproxy;
7509 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007510 if (!next)
7511 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007512 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007513 }
7514
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007515 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007516 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007517 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007518 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007519 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007520 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007521 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007522 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007523
Willy Tarreau050536d2012-10-04 08:47:34 +02007524 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007525 /* proxy ID not set, use automatic numbering with first
7526 * spare entry starting with next_pxid.
7527 */
7528 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7529 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7530 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007531 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007532 next_pxid++;
7533
Willy Tarreau55ea7572007-06-17 19:56:27 +02007534
Willy Tarreaubaaee002006-06-26 02:48:02 +02007535 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007536 /* ensure we don't keep listeners uselessly bound */
7537 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007538 free((void *)curproxy->table.peers.name);
7539 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007540 continue;
7541 }
7542
Willy Tarreau102df612014-05-07 23:56:38 +02007543 /* Check multi-process mode compatibility for the current proxy */
7544
7545 if (curproxy->bind_proc) {
7546 /* an explicit bind-process was specified, let's check how many
7547 * processes remain.
7548 */
David Carliere6c39412015-07-02 07:00:17 +00007549 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007550
7551 curproxy->bind_proc &= nbits(global.nbproc);
7552 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007553 ha_warning("Proxy '%s': the process specified on the 'bind-process' directive refers to a process number that is higher than global.nbproc. The proxy has been forced to run on process 1 only.\n", curproxy->id);
Willy Tarreau102df612014-05-07 23:56:38 +02007554 curproxy->bind_proc = 1;
7555 }
7556 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007557 ha_warning("Proxy '%s': all processes specified on the 'bind-process' directive refer to numbers that are all higher than global.nbproc. The directive was ignored and the proxy will run on all processes.\n", curproxy->id);
Willy Tarreau102df612014-05-07 23:56:38 +02007558 curproxy->bind_proc = 0;
7559 }
7560 }
7561
Willy Tarreau3d209582014-05-09 17:06:11 +02007562 /* check and reduce the bind-proc of each listener */
7563 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7564 unsigned long mask;
7565
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007566 /* HTTP frontends with "h2" as ALPN/NPN will work in
7567 * HTTP/2 and absolutely require buffers 16kB or larger.
7568 */
7569#ifdef USE_OPENSSL
7570 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7571#ifdef OPENSSL_NPN_NEGOTIATED
7572 /* check NPN */
Willy Tarreau4db49c02018-11-11 10:36:25 +01007573 if (bind_conf->ssl_conf.npn_str && strstr(bind_conf->ssl_conf.npn_str, "\002h2")) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007574 ha_alert("config : HTTP frontend '%s' enables HTTP/2 via NPN at [%s:%d], so global.tune.bufsize must be at least 16384 bytes (%d now).\n",
7575 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007576 cfgerr++;
7577 }
7578#endif
7579#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7580 /* check ALPN */
Willy Tarreau4db49c02018-11-11 10:36:25 +01007581 if (bind_conf->ssl_conf.alpn_str && strstr(bind_conf->ssl_conf.alpn_str, "\002h2")) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007582 ha_alert("config : HTTP frontend '%s' enables HTTP/2 via ALPN at [%s:%d], so global.tune.bufsize must be at least 16384 bytes (%d now).\n",
7583 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007584 cfgerr++;
7585 }
7586#endif
7587 } /* HTTP && bufsize < 16384 */
7588#endif
7589
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007590 /* detect and address thread affinity inconsistencies */
7591 nbproc = 0;
7592 if (bind_conf->bind_proc)
7593 nbproc = my_ffsl(bind_conf->bind_proc);
7594
7595 mask = bind_conf->bind_thread[nbproc - 1];
Willy Tarreau0c026f42018-08-01 19:12:20 +02007596 if (mask && !(mask & all_threads_mask)) {
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007597 unsigned long new_mask = 0;
7598
7599 while (mask) {
Willy Tarreau0c026f42018-08-01 19:12:20 +02007600 new_mask |= mask & all_threads_mask;
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007601 mask >>= global.nbthread;
7602 }
7603
7604 for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
7605 if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
7606 bind_conf->bind_thread[nbproc] = new_mask;
7607 }
7608 ha_warning("Proxy '%s': the thread range specified on the 'process' directive of 'bind %s' at [%s:%d] only refers to thread numbers out of the range defined by the global 'nbthread' directive. The thread numbers were remapped to existing threads instead (mask 0x%lx).\n",
7609 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
7610 }
7611
7612 /* detect process and nbproc affinity inconsistencies */
Willy Tarreau3d209582014-05-09 17:06:11 +02007613 if (!bind_conf->bind_proc)
7614 continue;
7615
7616 mask = nbits(global.nbproc);
7617 if (curproxy->bind_proc)
7618 mask &= curproxy->bind_proc;
7619 /* mask cannot be null here thanks to the previous checks */
7620
David Carliere6c39412015-07-02 07:00:17 +00007621 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007622 bind_conf->bind_proc &= mask;
7623
7624 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007625 ha_warning("Proxy '%s': the process number specified on the 'process' directive of 'bind %s' at [%s:%d] refers to a process not covered by the proxy. This has been fixed by forcing it to run on the proxy's first process only.\n",
7626 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007627 bind_conf->bind_proc = mask & ~(mask - 1);
7628 }
7629 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007630 ha_warning("Proxy '%s': the process range specified on the 'process' directive of 'bind %s' at [%s:%d] only refers to processes not covered by the proxy. The directive was ignored so that all of the proxy's processes are used.\n",
7631 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007632 bind_conf->bind_proc = 0;
7633 }
7634 }
7635
Willy Tarreauff01a212009-03-15 13:46:16 +01007636 switch (curproxy->mode) {
7637 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007638 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007639 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007640 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7641 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007642 cfgerr++;
7643 }
7644
7645 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007646 ha_warning("config : servers will be ignored for %s '%s'.\n",
7647 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007648 break;
7649
7650 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007651 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007652 break;
7653
7654 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007655 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007656 break;
William Lallemandcf62f7e2018-10-26 14:47:40 +02007657
7658 case PR_MODE_CLI:
7659 cfgerr += proxy_cfg_ensure_no_http(curproxy);
7660 break;
Willy Tarreauff01a212009-03-15 13:46:16 +01007661 }
7662
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007663 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007664 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7665 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007666 err_code |= ERR_WARN;
7667 }
7668
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007669 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007670 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007671 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007672 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7673 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007674 cfgerr++;
7675 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007676#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007677 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007678 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7679 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007680 cfgerr++;
7681 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007682#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007683 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007684 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7685 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007686 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007687 }
7688 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007689 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007690 /* If no LB algo is set in a backend, and we're not in
7691 * transparent mode, dispatch mode nor proxy mode, we
7692 * want to use balance roundrobin by default.
7693 */
7694 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7695 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007696 }
7697 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007698
Willy Tarreau1620ec32011-08-06 17:05:02 +02007699 if (curproxy->options & PR_O_DISPATCH)
7700 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7701 else if (curproxy->options & PR_O_HTTP_PROXY)
7702 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7703 else if (curproxy->options & PR_O_TRANSP)
7704 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007705
Willy Tarreau1620ec32011-08-06 17:05:02 +02007706 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7707 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007708 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7709 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007710 err_code |= ERR_WARN;
7711 curproxy->options &= ~PR_O_DISABLE404;
7712 }
7713 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007714 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7715 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007716 err_code |= ERR_WARN;
7717 curproxy->options &= ~PR_O2_CHK_SNDST;
7718 }
Willy Tarreauef781042010-01-27 11:53:01 +01007719 }
7720
Simon Horman98637e52014-06-20 12:30:16 +09007721 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7722 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007723 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7724 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007725 cfgerr++;
7726 }
7727 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007728 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7729 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007730 cfgerr++;
7731 }
7732 }
7733
Simon Horman64e34162015-02-06 11:11:57 +09007734 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007735 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007736 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7737 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7738 "'email-alert myhostname', or 'email-alert to' "
7739 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7740 "to be present).\n",
7741 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007742 err_code |= ERR_WARN;
7743 free_email_alert(curproxy);
7744 }
7745 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007746 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007747 }
7748
Simon Horman98637e52014-06-20 12:30:16 +09007749 if (curproxy->check_command) {
7750 int clear = 0;
7751 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007752 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7753 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007754 err_code |= ERR_WARN;
7755 clear = 1;
7756 }
7757 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007758 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7759 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007760 cfgerr++;
7761 }
7762 if (clear) {
7763 free(curproxy->check_command);
7764 curproxy->check_command = NULL;
7765 }
7766 }
7767
7768 if (curproxy->check_path) {
7769 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007770 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7771 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007772 err_code |= ERR_WARN;
7773 free(curproxy->check_path);
7774 curproxy->check_path = NULL;
7775 }
7776 }
7777
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007778 /* if a default backend was specified, let's find it */
7779 if (curproxy->defbe.name) {
7780 struct proxy *target;
7781
Willy Tarreauafb39922015-05-26 12:04:09 +02007782 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007783 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007784 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7785 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007786 cfgerr++;
7787 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007788 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7789 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007790 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007791 } else if (target->mode != curproxy->mode &&
7792 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7793
Christopher Faulet767a84b2017-11-24 16:50:31 +01007794 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7795 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7796 curproxy->conf.file, curproxy->conf.line,
7797 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7798 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007799 cfgerr++;
Willy Tarreau68ad3a42018-10-22 11:49:15 +02007800 } else if ((curproxy->options2 ^ target->options2) & PR_O2_USE_HTX) {
7801 ha_alert("%s %s '%s' (%s:%d) tries to use %s %s '%s' (%s:%d) as its default backend, both of which disagree on 'option http-use-htx'.\n",
7802 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7803 curproxy->conf.file, curproxy->conf.line,
7804 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7805 target->conf.file, target->conf.line);
7806 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007807 } else {
7808 free(curproxy->defbe.name);
7809 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007810 /* Update tot_fe_maxconn for a further fullconn's computation */
7811 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007812 /* Emit a warning if this proxy also has some servers */
7813 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007814 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7815 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007816 err_code |= ERR_WARN;
7817 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007818 }
7819 }
7820
Emeric Brun3f783572017-01-12 11:21:28 +01007821 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7822 /* Case of listen without default backend
7823 * The curproxy will be its own default backend
7824 * so we update tot_fe_maxconn for a further
7825 * fullconn's computation */
7826 curproxy->tot_fe_maxconn += curproxy->maxconn;
7827 }
7828
Willy Tarreau55ea7572007-06-17 19:56:27 +02007829 /* find the target proxy for 'use_backend' rules */
7830 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007831 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007832 struct logformat_node *node;
7833 char *pxname;
7834
7835 /* Try to parse the string as a log format expression. If the result
7836 * of the parsing is only one entry containing a simple string, then
7837 * it's a standard string corresponding to a static rule, thus the
7838 * parsing is cancelled and be.name is restored to be resolved.
7839 */
7840 pxname = rule->be.name;
7841 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007842 curproxy->conf.args.ctx = ARGC_UBK;
7843 curproxy->conf.args.file = rule->file;
7844 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007845 err = NULL;
7846 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007847 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7848 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007849 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007850 cfgerr++;
7851 continue;
7852 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007853 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7854
7855 if (!LIST_ISEMPTY(&rule->be.expr)) {
7856 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7857 rule->dynamic = 1;
7858 free(pxname);
7859 continue;
7860 }
7861 /* simple string: free the expression and fall back to static rule */
7862 free(node->arg);
7863 free(node);
7864 }
7865
7866 rule->dynamic = 0;
7867 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007868
Willy Tarreauafb39922015-05-26 12:04:09 +02007869 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007870 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007871 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7872 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007873 cfgerr++;
7874 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007875 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7876 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007877 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007878 } else if (target->mode != curproxy->mode &&
7879 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7880
Christopher Faulet767a84b2017-11-24 16:50:31 +01007881 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7882 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7883 curproxy->conf.file, curproxy->conf.line,
7884 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7885 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007886 cfgerr++;
Willy Tarreau68ad3a42018-10-22 11:49:15 +02007887 } else if ((curproxy->options2 ^ target->options2) & PR_O2_USE_HTX) {
7888 ha_alert("%s %s '%s' (%s:%d) tries to use %s %s '%s' (%s:%d) in a 'use_backend' rule, both of which disagree on 'option http-use-htx'.\n",
7889 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7890 curproxy->conf.file, curproxy->conf.line,
7891 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7892 target->conf.file, target->conf.line);
7893 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007894 } else {
7895 free((void *)rule->be.name);
7896 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007897 /* For each target of switching rules, we update
7898 * their tot_fe_maxconn, except if a previous rule point
7899 * on the same backend or on the default backend */
7900 if (rule->be.backend != curproxy->defbe.be) {
7901 struct switching_rule *swrule;
7902
7903 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7904 if (rule == swrule) {
7905 target->tot_fe_maxconn += curproxy->maxconn;
7906 break;
7907 }
7908 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7909 /* there is multiple ref of this backend */
7910 break;
7911 }
7912 }
7913 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007914 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007915 }
7916
Willy Tarreau64ab6072014-09-16 12:17:36 +02007917 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007918 list_for_each_entry(srule, &curproxy->server_rules, list) {
7919 struct server *target = findserver(curproxy, srule->srv.name);
7920
7921 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007922 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7923 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007924 cfgerr++;
7925 continue;
7926 }
7927 free((void *)srule->srv.name);
7928 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007929 }
7930
Emeric Brunb982a3d2010-01-04 15:45:53 +01007931 /* find the target table for 'stick' rules */
7932 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7933 struct proxy *target;
7934
Emeric Brun1d33b292010-01-04 15:47:17 +01007935 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7936 if (mrule->flags & STK_IS_STORE)
7937 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7938
Emeric Brunb982a3d2010-01-04 15:45:53 +01007939 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007940 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007941 else
7942 target = curproxy;
7943
7944 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007945 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7946 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007947 cfgerr++;
7948 }
7949 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007950 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7951 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007952 cfgerr++;
7953 }
Willy Tarreau12785782012-04-27 21:37:17 +02007954 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007955 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7956 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007957 cfgerr++;
7958 }
7959 else {
7960 free((void *)mrule->table.name);
7961 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007962 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007963 }
7964 }
7965
7966 /* find the target table for 'store response' rules */
7967 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7968 struct proxy *target;
7969
Emeric Brun1d33b292010-01-04 15:47:17 +01007970 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7971
Emeric Brunb982a3d2010-01-04 15:45:53 +01007972 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007973 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007974 else
7975 target = curproxy;
7976
7977 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007978 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7979 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007980 cfgerr++;
7981 }
7982 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007983 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7984 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007985 cfgerr++;
7986 }
Willy Tarreau12785782012-04-27 21:37:17 +02007987 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007988 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7989 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007990 cfgerr++;
7991 }
7992 else {
7993 free((void *)mrule->table.name);
7994 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007995 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007996 }
7997 }
7998
Christopher Faulete4e830d2017-09-18 14:51:41 +02007999 /* check validity for 'tcp-request' layer 4 rules */
8000 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
8001 err = NULL;
8002 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008003 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008004 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01008005 cfgerr++;
8006 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02008007 }
8008
Christopher Faulete4e830d2017-09-18 14:51:41 +02008009 /* check validity for 'tcp-request' layer 5 rules */
8010 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
8011 err = NULL;
8012 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008013 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008014 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008015 cfgerr++;
8016 }
8017 }
8018
Christopher Faulete4e830d2017-09-18 14:51:41 +02008019 /* check validity for 'tcp-request' layer 6 rules */
8020 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8021 err = NULL;
8022 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008023 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008024 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008025 cfgerr++;
8026 }
8027 }
8028
Christopher Faulete4e830d2017-09-18 14:51:41 +02008029 /* check validity for 'http-request' layer 7 rules */
8030 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
8031 err = NULL;
8032 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008033 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008034 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008035 cfgerr++;
8036 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008037 }
8038
Christopher Faulete4e830d2017-09-18 14:51:41 +02008039 /* check validity for 'http-response' layer 7 rules */
8040 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
8041 err = NULL;
8042 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008043 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008044 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02008045 cfgerr++;
8046 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008047 }
8048
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008049 /* move any "block" rules at the beginning of the http-request rules */
8050 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8051 /* insert block_rules into http_req_rules at the beginning */
8052 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8053 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8054 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8055 curproxy->http_req_rules.n = curproxy->block_rules.n;
8056 LIST_INIT(&curproxy->block_rules);
8057 }
8058
Emeric Brun32da3c42010-09-23 18:39:19 +02008059 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008060 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008061
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008062 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008063 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8064 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008065 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008066 break;
8067 }
8068 }
8069
8070 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008071 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8072 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008073 free((void *)curproxy->table.peers.name);
8074 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008075 cfgerr++;
8076 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008077 else if (curpeers->state == PR_STSTOPPED) {
8078 /* silently disable this peers section */
8079 curproxy->table.peers.p = NULL;
8080 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008081 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008082 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8083 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008084 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008085 cfgerr++;
8086 }
8087 }
8088
Simon Horman9dc49962015-01-30 11:22:59 +09008089
8090 if (curproxy->email_alert.mailers.name) {
8091 struct mailers *curmailers = mailers;
8092
8093 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008094 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008095 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008096 }
Simon Horman9dc49962015-01-30 11:22:59 +09008097 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008098 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8099 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008100 free_email_alert(curproxy);
8101 cfgerr++;
8102 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008103 else {
8104 err = NULL;
8105 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008106 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008107 free(err);
8108 cfgerr++;
8109 }
8110 }
Simon Horman9dc49962015-01-30 11:22:59 +09008111 }
8112
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008113 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008114 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008115 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008116 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8117 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008118 cfgerr++;
8119 goto out_uri_auth_compat;
8120 }
8121
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008122 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008123 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008124 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008125 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008126
Willy Tarreau95fa4692010-02-01 13:05:50 +01008127 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8128 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008129
8130 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008131 uri_auth_compat_req[i++] = "realm";
8132 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8133 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008134
Willy Tarreau95fa4692010-02-01 13:05:50 +01008135 uri_auth_compat_req[i++] = "unless";
8136 uri_auth_compat_req[i++] = "{";
8137 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8138 uri_auth_compat_req[i++] = "}";
8139 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008140
Willy Tarreauff011f22011-01-06 17:51:27 +01008141 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8142 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008143 cfgerr++;
8144 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008145 }
8146
Willy Tarreauff011f22011-01-06 17:51:27 +01008147 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008148
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008149 if (curproxy->uri_auth->auth_realm) {
8150 free(curproxy->uri_auth->auth_realm);
8151 curproxy->uri_auth->auth_realm = NULL;
8152 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008153
8154 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008155 }
8156out_uri_auth_compat:
8157
Dragan Dosen43885c72015-10-01 13:18:13 +02008158 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008159 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008160 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8161 if (!curproxy->conf.logformat_sd_string) {
8162 /* set the default logformat_sd_string */
8163 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8164 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008165 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008166 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008167 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008168
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008169 /* compile the log format */
8170 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008171 if (curproxy->conf.logformat_string != default_http_log_format &&
8172 curproxy->conf.logformat_string != default_tcp_log_format &&
8173 curproxy->conf.logformat_string != clf_http_log_format)
8174 free(curproxy->conf.logformat_string);
8175 curproxy->conf.logformat_string = NULL;
8176 free(curproxy->conf.lfs_file);
8177 curproxy->conf.lfs_file = NULL;
8178 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008179
8180 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8181 free(curproxy->conf.logformat_sd_string);
8182 curproxy->conf.logformat_sd_string = NULL;
8183 free(curproxy->conf.lfsd_file);
8184 curproxy->conf.lfsd_file = NULL;
8185 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008186 }
8187
Willy Tarreau62a61232013-04-12 18:13:46 +02008188 if (curproxy->conf.logformat_string) {
8189 curproxy->conf.args.ctx = ARGC_LOG;
8190 curproxy->conf.args.file = curproxy->conf.lfs_file;
8191 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008192 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008193 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008194 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008195 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8196 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008197 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008198 cfgerr++;
8199 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008200 curproxy->conf.args.file = NULL;
8201 curproxy->conf.args.line = 0;
8202 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008203
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008204 if (curproxy->conf.logformat_sd_string) {
8205 curproxy->conf.args.ctx = ARGC_LOGSD;
8206 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8207 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008208 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008209 if (!parse_logformat_string(curproxy->conf.logformat_sd_string, curproxy, &curproxy->logformat_sd, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008210 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008211 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8212 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008213 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008214 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008215 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008216 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8217 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008218 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008219 cfgerr++;
8220 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008221 curproxy->conf.args.file = NULL;
8222 curproxy->conf.args.line = 0;
8223 }
8224
Willy Tarreau62a61232013-04-12 18:13:46 +02008225 if (curproxy->conf.uniqueid_format_string) {
8226 curproxy->conf.args.ctx = ARGC_UIF;
8227 curproxy->conf.args.file = curproxy->conf.uif_file;
8228 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008229 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008230 if (!parse_logformat_string(curproxy->conf.uniqueid_format_string, curproxy, &curproxy->format_unique_id, LOG_OPT_HTTP,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008231 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008232 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8233 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008234 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008235 cfgerr++;
8236 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008237 curproxy->conf.args.file = NULL;
8238 curproxy->conf.args.line = 0;
8239 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008240
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008241 /* only now we can check if some args remain unresolved.
8242 * This must be done after the users and groups resolution.
8243 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008244 cfgerr += smp_resolve_args(curproxy);
8245 if (!cfgerr)
8246 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008247
Willy Tarreau2738a142006-07-08 17:28:09 +02008248 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008249 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008250 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008251 (!curproxy->timeout.connect ||
8252 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008253 ha_warning("config : missing timeouts for %s '%s'.\n"
8254 " | While not properly invalid, you will certainly encounter various problems\n"
8255 " | with such a configuration. To fix this, please ensure that all following\n"
8256 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8257 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008258 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008259 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008260
Willy Tarreau1fa31262007-12-03 00:36:16 +01008261 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8262 * We must still support older configurations, so let's find out whether those
8263 * parameters have been set or must be copied from contimeouts.
8264 */
8265 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008266 if (!curproxy->timeout.tarpit ||
8267 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008268 /* tarpit timeout not set. We search in the following order:
8269 * default.tarpit, curr.connect, default.connect.
8270 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008271 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008272 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008273 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008274 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008275 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008276 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008277 }
8278 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008279 (!curproxy->timeout.queue ||
8280 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008281 /* queue timeout not set. We search in the following order:
8282 * default.queue, curr.connect, default.connect.
8283 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008284 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008285 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008286 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008287 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008288 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008289 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008290 }
8291 }
8292
Willy Tarreau1620ec32011-08-06 17:05:02 +02008293 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008294 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008295 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008296 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008297 }
8298
Willy Tarreau215663d2014-06-13 18:30:23 +02008299 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8300 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008301 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8302 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008303 err_code |= ERR_WARN;
8304 }
8305
Willy Tarreau193b8c62012-11-22 00:17:38 +01008306 /* ensure that cookie capture length is not too large */
8307 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008308 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8309 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008310 err_code |= ERR_WARN;
8311 curproxy->capture_len = global.tune.cookie_len - 1;
8312 }
8313
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008314 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008315 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008316 curproxy->req_cap_pool = create_pool("ptrcap",
8317 curproxy->nb_req_cap * sizeof(char *),
8318 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008319 }
8320
8321 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008322 curproxy->rsp_cap_pool = create_pool("ptrcap",
8323 curproxy->nb_rsp_cap * sizeof(char *),
8324 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008325 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008326
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008327 switch (curproxy->load_server_state_from_file) {
8328 case PR_SRV_STATE_FILE_UNSPEC:
8329 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8330 break;
8331 case PR_SRV_STATE_FILE_GLOBAL:
8332 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008333 ha_warning("config : backend '%s' configured to load server state file from global section 'server-state-file' directive. Unfortunately, 'server-state-file' is not set!\n",
8334 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008335 err_code |= ERR_WARN;
8336 }
8337 break;
8338 }
8339
Willy Tarreaubaaee002006-06-26 02:48:02 +02008340 /* first, we will invert the servers list order */
8341 newsrv = NULL;
8342 while (curproxy->srv) {
8343 struct server *next;
8344
8345 next = curproxy->srv->next;
8346 curproxy->srv->next = newsrv;
8347 newsrv = curproxy->srv;
8348 if (!next)
8349 break;
8350 curproxy->srv = next;
8351 }
8352
Willy Tarreau17edc812014-01-03 12:14:34 +01008353 /* Check that no server name conflicts. This causes trouble in the stats.
8354 * We only emit a warning for the first conflict affecting each server,
8355 * in order to avoid combinatory explosion if all servers have the same
8356 * name. We do that only for servers which do not have an explicit ID,
8357 * because these IDs were made also for distinguishing them and we don't
8358 * want to annoy people who correctly manage them.
8359 */
8360 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8361 struct server *other_srv;
8362
8363 if (newsrv->puid)
8364 continue;
8365
8366 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8367 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008368 ha_warning("parsing [%s:%d] : %s '%s', another server named '%s' was defined without an explicit ID at line %d, this is not recommended.\n",
8369 newsrv->conf.file, newsrv->conf.line,
8370 proxy_type_str(curproxy), curproxy->id,
8371 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008372 break;
8373 }
8374 }
8375 }
8376
Willy Tarreaudd701652010-05-25 23:03:02 +02008377 /* assign automatic UIDs to servers which don't have one yet */
8378 next_id = 1;
8379 newsrv = curproxy->srv;
8380 while (newsrv != NULL) {
8381 if (!newsrv->puid) {
8382 /* server ID not set, use automatic numbering with first
8383 * spare entry starting with next_svid.
8384 */
8385 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8386 newsrv->conf.id.key = newsrv->puid = next_id;
8387 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8388 }
8389 next_id++;
8390 newsrv = newsrv->next;
8391 }
8392
Willy Tarreau20697042007-11-15 23:26:18 +01008393 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008394 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008395
Willy Tarreau62c3be22012-01-20 13:12:32 +01008396 /*
8397 * If this server supports a maxconn parameter, it needs a dedicated
8398 * tasks to fill the emptied slots when a connection leaves.
8399 * Also, resolve deferred tracking dependency if needed.
8400 */
8401 newsrv = curproxy->srv;
8402 while (newsrv != NULL) {
8403 if (newsrv->minconn > newsrv->maxconn) {
8404 /* Only 'minconn' was specified, or it was higher than or equal
8405 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8406 * this will avoid further useless expensive computations.
8407 */
8408 newsrv->maxconn = newsrv->minconn;
8409 } else if (newsrv->maxconn && !newsrv->minconn) {
8410 /* minconn was not specified, so we set it to maxconn */
8411 newsrv->minconn = newsrv->maxconn;
8412 }
8413
Willy Tarreau17d45382016-12-22 21:16:08 +01008414 /* this will also properly set the transport layer for prod and checks */
8415 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8416 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8417 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8418 }
Emeric Brun94324a42012-10-11 14:00:19 +02008419
Willy Tarreau2f075e92013-12-03 11:11:34 +01008420 /* set the check type on the server */
8421 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8422
Willy Tarreau62c3be22012-01-20 13:12:32 +01008423 if (newsrv->trackit) {
8424 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008425 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008426 char *pname, *sname;
8427
8428 pname = newsrv->trackit;
8429 sname = strrchr(pname, '/');
8430
8431 if (sname)
8432 *sname++ = '\0';
8433 else {
8434 sname = pname;
8435 pname = NULL;
8436 }
8437
8438 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008439 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008440 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008441 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8442 proxy_type_str(curproxy), curproxy->id,
8443 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008444 cfgerr++;
8445 goto next_srv;
8446 }
8447 } else
8448 px = curproxy;
8449
8450 srv = findserver(px, sname);
8451 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008452 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8453 proxy_type_str(curproxy), curproxy->id,
8454 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008455 cfgerr++;
8456 goto next_srv;
8457 }
8458
Willy Tarreau32091232014-05-16 13:52:00 +02008459 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8460 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8461 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008462 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8463 "tracking as it does not have any check nor agent enabled.\n",
8464 proxy_type_str(curproxy), curproxy->id,
8465 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008466 cfgerr++;
8467 goto next_srv;
8468 }
8469
8470 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8471
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008472 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008473 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8474 "belongs to a tracking chain looping back to %s/%s.\n",
8475 proxy_type_str(curproxy), curproxy->id,
8476 newsrv->id, px->id, srv->id, px->id,
8477 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008478 cfgerr++;
8479 goto next_srv;
8480 }
8481
8482 if (curproxy != px &&
8483 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008484 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8485 "tracking: disable-on-404 option inconsistency.\n",
8486 proxy_type_str(curproxy), curproxy->id,
8487 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008488 cfgerr++;
8489 goto next_srv;
8490 }
8491
Willy Tarreau62c3be22012-01-20 13:12:32 +01008492 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008493 newsrv->tracknext = srv->trackers;
8494 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008495
8496 free(newsrv->trackit);
8497 newsrv->trackit = NULL;
8498 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008499
Willy Tarreau62c3be22012-01-20 13:12:32 +01008500 next_srv:
8501 newsrv = newsrv->next;
8502 }
8503
Olivier Houchard4e694042017-03-14 20:01:29 +01008504 /*
8505 * Try to generate dynamic cookies for servers now.
8506 * It couldn't be done earlier, since at the time we parsed
8507 * the server line, we may not have known yet that we
8508 * should use dynamic cookies, or the secret key may not
8509 * have been provided yet.
8510 */
8511 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8512 newsrv = curproxy->srv;
8513 while (newsrv != NULL) {
8514 srv_set_dyncookie(newsrv);
8515 newsrv = newsrv->next;
8516 }
8517
8518 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008519 /* We have to initialize the server lookup mechanism depending
8520 * on what LB algorithm was choosen.
8521 */
8522
8523 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8524 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8525 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008526 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8527 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8528 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02008529 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
8530 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8531 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02008532 } else {
8533 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8534 fwrr_init_server_groups(curproxy);
8535 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008536 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008537
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008538 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008539 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8540 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8541 fwlc_init_server_tree(curproxy);
8542 } else {
8543 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8544 fas_init_server_tree(curproxy);
8545 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008546 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008547
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008548 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008549 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8550 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8551 chash_init_server_tree(curproxy);
8552 } else {
8553 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8554 init_server_map(curproxy);
8555 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008556 break;
8557 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008558 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008559
8560 if (curproxy->options & PR_O_LOGASAP)
8561 curproxy->to_log &= ~LW_BYTES;
8562
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008563 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008564 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8565 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008566 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8567 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008568 err_code |= ERR_WARN;
8569 }
8570
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008571 if (curproxy->mode != PR_MODE_HTTP) {
8572 int optnum;
8573
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008574 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008575 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8576 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008577 err_code |= ERR_WARN;
8578 curproxy->uri_auth = NULL;
8579 }
8580
Willy Tarreaude7dc882017-03-10 11:49:21 +01008581 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008582 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8583 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008584 err_code |= ERR_WARN;
8585 }
8586
8587 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008588 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8589 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008590 err_code |= ERR_WARN;
8591 }
8592
8593 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008594 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8595 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008596 err_code |= ERR_WARN;
8597 }
8598
8599 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008600 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8601 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008602 err_code |= ERR_WARN;
8603 }
8604
8605 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008606 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8607 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008608 err_code |= ERR_WARN;
8609 }
8610
Willy Tarreau87cf5142011-08-19 22:57:24 +02008611 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008612 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8613 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008614 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008615 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008616 }
8617
8618 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008619 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8620 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008621 err_code |= ERR_WARN;
8622 curproxy->options &= ~PR_O_ORGTO;
8623 }
8624
8625 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8626 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8627 (curproxy->cap & cfg_opts[optnum].cap) &&
8628 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008629 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8630 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008631 err_code |= ERR_WARN;
8632 curproxy->options &= ~cfg_opts[optnum].val;
8633 }
8634 }
8635
8636 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8637 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8638 (curproxy->cap & cfg_opts2[optnum].cap) &&
8639 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008640 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8641 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008642 err_code |= ERR_WARN;
8643 curproxy->options2 &= ~cfg_opts2[optnum].val;
8644 }
8645 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008646
Willy Tarreau29fbe512015-08-20 19:35:14 +02008647#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008648 if (curproxy->conn_src.bind_hdr_occ) {
8649 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008650 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8651 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008652 err_code |= ERR_WARN;
8653 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008654#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008655 }
8656
Willy Tarreaubaaee002006-06-26 02:48:02 +02008657 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008658 * ensure that we're not cross-dressing a TCP server into HTTP.
8659 */
8660 newsrv = curproxy->srv;
8661 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008662 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008663 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8664 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008665 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008666 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008667
Willy Tarreau0cec3312011-10-31 13:49:26 +01008668 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008669 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8670 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008671 err_code |= ERR_WARN;
8672 }
8673
Willy Tarreauc93cd162014-05-13 15:54:22 +02008674 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008675 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8676 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008677 err_code |= ERR_WARN;
8678 }
8679
Willy Tarreau29fbe512015-08-20 19:35:14 +02008680#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008681 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8682 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008683 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8684 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008685 err_code |= ERR_WARN;
8686 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008687#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008688
Willy Tarreau46deab62018-04-28 07:18:15 +02008689 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
8690 curproxy->options &= ~PR_O_REUSE_MASK;
8691
Willy Tarreau4c183462017-01-06 12:21:38 +01008692 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8693 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8694 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8695 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8696 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008697 ha_warning("config : %s '%s' : connections to server '%s' use the client's IP address as the source while http-reuse is enabled and allows the same connection to be shared between multiple clients. It is strongly advised to disable 'usesrc' and to use the 'forwardfor' option instead.\n",
8698 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008699 err_code |= ERR_WARN;
8700 }
8701
8702
8703 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008704 ha_warning("config : %s '%s' : connections to server '%s' will have a PROXY protocol header announcing the first client's IP address while http-reuse is enabled and allows the same connection to be shared between multiple clients. It is strongly advised to disable 'send-proxy' and to use the 'forwardfor' option instead.\n",
8705 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008706 err_code |= ERR_WARN;
8707 }
8708 }
8709
Willy Tarreau21d2af32008-02-14 20:25:24 +01008710 newsrv = newsrv->next;
8711 }
8712
Willy Tarreaue42bd962014-09-16 16:21:19 +02008713 /* check if we have a frontend with "tcp-request content" looking at L7
8714 * with no inspect-delay
8715 */
8716 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008717 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8718 if (arule->action == ACT_TCP_CAPTURE &&
8719 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008720 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008721 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8722 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008723 break;
8724 }
8725
Christopher Faulete4e830d2017-09-18 14:51:41 +02008726 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008727 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8728 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8729 " This means that these rules will randomly find their contents. This can be fixed by"
8730 " setting the tcp-request inspect-delay.\n",
8731 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008732 err_code |= ERR_WARN;
8733 }
8734 }
8735
Christopher Fauletd7c91962015-04-30 11:48:27 +02008736 /* Check filter configuration, if any */
8737 cfgerr += flt_check(curproxy);
8738
Willy Tarreauc1a21672009-08-16 22:37:44 +02008739 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008740 if (!curproxy->accept)
8741 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008742
Willy Tarreauc1a21672009-08-16 22:37:44 +02008743 if (curproxy->tcp_req.inspect_delay ||
8744 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008745 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008746
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008747 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008748 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008749 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008750 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008751
William Lallemandcf62f7e2018-10-26 14:47:40 +02008752 if (curproxy->mode == PR_MODE_CLI) {
8753 curproxy->fe_req_ana |= AN_REQ_WAIT_CLI;
8754 curproxy->fe_rsp_ana |= AN_RES_WAIT_CLI;
8755 }
8756
Willy Tarreauc1a21672009-08-16 22:37:44 +02008757 /* both TCP and HTTP must check switching rules */
8758 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008759
8760 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008761 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008762 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8763 curproxy->fe_rsp_ana |= AN_RES_FLT_START_FE | AN_RES_FLT_XFER_DATA | AN_RES_FLT_END;
Christopher Faulet309c6412015-12-02 09:57:32 +01008764 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008765 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8766 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008767 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008768 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008769 }
8770
8771 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008772 if (curproxy->tcp_req.inspect_delay ||
8773 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8774 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8775
Emeric Brun97679e72010-09-23 17:56:44 +02008776 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8777 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8778
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008779 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008780 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008781 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008782 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008783
8784 /* If the backend does requires RDP cookie persistence, we have to
8785 * enable the corresponding analyser.
8786 */
8787 if (curproxy->options2 & PR_O2_RDPC_PRST)
8788 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008789
8790 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008791 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008792 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8793 curproxy->be_rsp_ana |= AN_RES_FLT_START_BE | AN_RES_FLT_XFER_DATA | AN_RES_FLT_END;
Christopher Faulet309c6412015-12-02 09:57:32 +01008794 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008795 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8796 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008797 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008798 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008799 }
Christopher Fauleta717b992018-04-10 14:43:00 +02008800
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008801 /* Check the mux protocols, if any, for each listener and server
Christopher Fauleta717b992018-04-10 14:43:00 +02008802 * attached to the current proxy */
8803 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8804 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8805
8806 if (!bind_conf->mux_proto)
8807 continue;
8808 if (!(bind_conf->mux_proto->mode & mode)) {
8809 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n",
8810 proxy_type_str(curproxy), curproxy->id,
8811 (int)bind_conf->mux_proto->token.len,
8812 bind_conf->mux_proto->token.ptr,
8813 bind_conf->arg, bind_conf->file, bind_conf->line);
8814 cfgerr++;
8815 }
8816 }
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008817 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8818 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8819
8820 if (!newsrv->mux_proto)
8821 continue;
8822 if (!(newsrv->mux_proto->mode & mode)) {
8823 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n",
8824 proxy_type_str(curproxy), curproxy->id,
8825 (int)newsrv->mux_proto->token.len,
8826 newsrv->mux_proto->token.ptr,
8827 newsrv->id, newsrv->conf.file, newsrv->conf.line);
8828 cfgerr++;
8829 }
8830 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008831 }
8832
8833 /***********************************************************/
8834 /* At this point, target names have already been resolved. */
8835 /***********************************************************/
8836
8837 /* Check multi-process mode compatibility */
8838
8839 if (global.nbproc > 1 && global.stats_fe) {
8840 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8841 unsigned long mask;
8842
8843 mask = nbits(global.nbproc);
8844 if (global.stats_fe->bind_proc)
8845 mask &= global.stats_fe->bind_proc;
8846
8847 if (bind_conf->bind_proc)
8848 mask &= bind_conf->bind_proc;
8849
8850 /* stop here if more than one process is used */
Willy Tarreau9504dd62018-10-15 09:37:03 +02008851 if (atleast2(mask))
Willy Tarreau419ead82014-09-16 13:41:21 +02008852 break;
8853 }
8854 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008855 ha_warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n");
Willy Tarreau419ead82014-09-16 13:41:21 +02008856 }
8857 }
8858
8859 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008860 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008861 if (curproxy->bind_proc)
8862 continue;
8863
8864 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8865 unsigned long mask;
8866
Willy Tarreaue428b082015-05-04 21:57:58 +02008867 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008868 curproxy->bind_proc |= mask;
8869 }
8870
8871 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008872 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008873 }
8874
8875 if (global.stats_fe) {
8876 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8877 unsigned long mask;
8878
Cyril Bonté06181952016-02-24 00:14:54 +01008879 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008880 global.stats_fe->bind_proc |= mask;
8881 }
8882 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008883 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008884 }
8885
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008886 /* propagate bindings from frontends to backends. Don't do it if there
8887 * are any fatal errors as we must not call it with unresolved proxies.
8888 */
8889 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008890 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008891 if (curproxy->cap & PR_CAP_FE)
8892 propagate_processes(curproxy, NULL);
8893 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008894 }
8895
8896 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008897 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008898 if (curproxy->bind_proc)
8899 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008900 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008901 }
8902
8903 /*******************************************************/
8904 /* At this step, all proxies have a non-null bind_proc */
8905 /*******************************************************/
8906
8907 /* perform the final checks before creating tasks */
8908
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008909 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008910 struct listener *listener;
8911 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008912
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008913 /* Configure SSL for each bind line.
8914 * Note: if configuration fails at some point, the ->ctx member
8915 * remains NULL so that listeners can later detach.
8916 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008917 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008918 if (bind_conf->xprt->prepare_bind_conf &&
8919 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008920 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008921 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008922
Willy Tarreaue6b98942007-10-29 01:09:36 +01008923 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008924 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008925 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008926 int nbproc;
8927
8928 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008929 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008930 nbits(global.nbproc));
8931
8932 if (!nbproc) /* no intersection between listener and frontend */
8933 nbproc = 1;
8934
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008935 if (!listener->luid) {
8936 /* listener ID not set, use automatic numbering with first
8937 * spare entry starting with next_luid.
8938 */
8939 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8940 listener->conf.id.key = listener->luid = next_id;
8941 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008942 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008943 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008944
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008945 /* enable separate counters */
8946 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008947 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008948 if (!listener->name)
8949 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008950 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008951
Willy Tarreaue6b98942007-10-29 01:09:36 +01008952 if (curproxy->options & PR_O_TCP_NOLING)
8953 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008954 if (!listener->maxconn)
8955 listener->maxconn = curproxy->maxconn;
8956 if (!listener->backlog)
8957 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008958 if (!listener->maxaccept)
8959 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8960
8961 /* we want to have an optimal behaviour on single process mode to
8962 * maximize the work at once, but in multi-process we want to keep
8963 * some fairness between processes, so we target half of the max
8964 * number of events to be balanced over all the processes the proxy
8965 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8966 * used to disable the limit.
8967 */
8968 if (listener->maxaccept > 0) {
8969 if (nbproc > 1)
8970 listener->maxaccept = (listener->maxaccept + 1) / 2;
8971 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8972 }
8973
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008974 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008975 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008976 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008977
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008978 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008979 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008980
Willy Tarreau620408f2016-10-21 16:37:51 +02008981 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8982 listener->options |= LI_O_TCP_L5_RULES;
8983
Willy Tarreaude3041d2010-05-31 10:56:17 +02008984 if (curproxy->mon_mask.s_addr)
8985 listener->options |= LI_O_CHK_MONNET;
8986
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008987 /* smart accept mode is automatic in HTTP mode */
8988 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008989 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008990 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8991 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008992 }
8993
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008994 /* Release unused SSL configs */
8995 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008996 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8997 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008998 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008999
Willy Tarreau9504dd62018-10-15 09:37:03 +02009000 if (atleast2(curproxy->bind_proc & nbits(global.nbproc))) {
Willy Tarreau102df612014-05-07 23:56:38 +02009001 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02009002 int count, maxproc = 0;
9003
9004 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00009005 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02009006 if (count > maxproc)
9007 maxproc = count;
9008 }
9009 /* backends have 0, frontends have 1 or more */
9010 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01009011 ha_warning("Proxy '%s': in multi-process mode, stats will be"
9012 " limited to process assigned to the current request.\n",
9013 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02009014
Willy Tarreau102df612014-05-07 23:56:38 +02009015 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009016 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
9017 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009018 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009019 }
Willy Tarreau102df612014-05-07 23:56:38 +02009020 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009021 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
9022 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009023 }
9024 }
Willy Tarreau918ff602011-07-25 16:33:49 +02009025
9026 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02009027 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02009028 if (curproxy->task) {
9029 curproxy->task->context = curproxy;
9030 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02009031 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009032 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
9033 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02009034 cfgerr++;
9035 }
Willy Tarreaub369a042014-09-16 13:21:03 +02009036 }
9037
Willy Tarreaufbb78422011-06-05 15:38:35 +02009038 /* automatically compute fullconn if not set. We must not do it in the
9039 * loop above because cross-references are not yet fully resolved.
9040 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009041 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009042 /* If <fullconn> is not set, let's set it to 10% of the sum of
9043 * the possible incoming frontend's maxconns.
9044 */
9045 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009046 /* we have the sum of the maxconns in <total>. We only
9047 * keep 10% of that sum to set the default fullconn, with
9048 * a hard minimum of 1 (to avoid a divide by zero).
9049 */
Emeric Brun3f783572017-01-12 11:21:28 +01009050 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02009051 if (!curproxy->fullconn)
9052 curproxy->fullconn = 1;
9053 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01009054 }
9055
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009056 /*
9057 * Recount currently required checks.
9058 */
9059
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009060 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009061 int optnum;
9062
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009063 for (optnum = 0; cfg_opts[optnum].name; optnum++)
9064 if (curproxy->options & cfg_opts[optnum].val)
9065 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009066
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009067 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
9068 if (curproxy->options2 & cfg_opts2[optnum].val)
9069 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009070 }
9071
Willy Tarreau0fca4832015-05-01 19:12:05 +02009072 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009073 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02009074 if (curproxy->table.peers.p)
9075 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
9076
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009077 if (cfg_peers) {
9078 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02009079 struct peer *p, *pb;
9080
Willy Tarreau1e273012015-05-01 19:15:17 +02009081 /* Remove all peers sections which don't have a valid listener,
9082 * which are not used by any table, or which are bound to more
9083 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009084 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009085 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009086 while (*last) {
9087 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009088
9089 if (curpeers->state == PR_STSTOPPED) {
9090 /* the "disabled" keyword was present */
9091 if (curpeers->peers_fe)
9092 stop_proxy(curpeers->peers_fe);
9093 curpeers->peers_fe = NULL;
9094 }
9095 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009096 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9097 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009098 }
Willy Tarreau9504dd62018-10-15 09:37:03 +02009099 else if (atleast2(curpeers->peers_fe->bind_proc)) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009100 /* either it's totally stopped or too much used */
9101 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009102 ha_alert("Peers section '%s': peers referenced by sections "
9103 "running in different processes (%d different ones). "
9104 "Check global.nbproc and all tables' bind-process "
9105 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009106 cfgerr++;
9107 }
9108 stop_proxy(curpeers->peers_fe);
9109 curpeers->peers_fe = NULL;
9110 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009111 else {
Willy Tarreaud9443442018-10-15 11:18:03 +02009112 if (!peers_init_sync(curpeers)) {
9113 ha_alert("Peers section '%s': out of memory, giving up on peers.\n",
9114 curpeers->id);
9115 cfgerr++;
9116 break;
9117 }
Willy Tarreau122541c2011-09-07 21:24:49 +02009118 last = &curpeers->next;
9119 continue;
9120 }
9121
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009122 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009123 p = curpeers->remote;
9124 while (p) {
9125 pb = p->next;
9126 free(p->id);
9127 free(p);
9128 p = pb;
9129 }
9130
9131 /* Destroy and unlink this curpeers section.
9132 * Note: curpeers is backed up into *last.
9133 */
9134 free(curpeers->id);
9135 curpeers = curpeers->next;
9136 free(*last);
9137 *last = curpeers;
9138 }
9139 }
9140
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009141 /* initialize stick-tables on backend capable proxies. This must not
9142 * be done earlier because the data size may be discovered while parsing
9143 * other proxies.
9144 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009145 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009146 if (curproxy->state == PR_STSTOPPED)
9147 continue;
9148
9149 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009150 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009151 cfgerr++;
9152 }
9153 }
9154
Simon Horman0d16a402015-01-30 11:22:58 +09009155 if (mailers) {
9156 struct mailers *curmailers = mailers, **last;
9157 struct mailer *m, *mb;
9158
9159 /* Remove all mailers sections which don't have a valid listener.
9160 * This can happen when a mailers section is never referenced.
9161 */
9162 last = &mailers;
9163 while (*last) {
9164 curmailers = *last;
9165 if (curmailers->users) {
9166 last = &curmailers->next;
9167 continue;
9168 }
9169
Christopher Faulet767a84b2017-11-24 16:50:31 +01009170 ha_warning("Removing incomplete section 'mailers %s'.\n",
9171 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009172
9173 m = curmailers->mailer_list;
9174 while (m) {
9175 mb = m->next;
9176 free(m->id);
9177 free(m);
9178 m = mb;
9179 }
9180
9181 /* Destroy and unlink this curmailers section.
9182 * Note: curmailers is backed up into *last.
9183 */
9184 free(curmailers->id);
9185 curmailers = curmailers->next;
9186 free(*last);
9187 *last = curmailers;
9188 }
9189 }
9190
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009191 /* Update server_state_file_name to backend name if backend is supposed to use
9192 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009193 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009194 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9195 curproxy->server_state_file_name == NULL)
9196 curproxy->server_state_file_name = strdup(curproxy->id);
9197 }
9198
Willy Tarreaubafbe012017-11-24 17:34:44 +01009199 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009200 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009201 MEM_F_SHARED);
9202
Ben Draut054fbee2018-04-13 15:43:04 -06009203 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
9204 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
9205 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
9206 curr_resolvers->id, curr_resolvers->conf.file,
9207 curr_resolvers->conf.line);
9208 err_code |= ERR_WARN;
9209 }
9210 }
9211
William Lallemand48b4bb42017-10-23 14:36:34 +02009212 list_for_each_entry(postparser, &postparsers, list) {
9213 if (postparser->func)
9214 cfgerr += postparser->func();
9215 }
9216
Willy Tarreaubb925012009-07-23 13:36:36 +02009217 if (cfgerr > 0)
9218 err_code |= ERR_ALERT | ERR_FATAL;
9219 out:
9220 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009221}
9222
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009223/*
9224 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9225 * parsing sessions.
9226 */
9227void cfg_register_keywords(struct cfg_kw_list *kwl)
9228{
9229 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9230}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009231
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009232/*
9233 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9234 */
9235void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9236{
9237 LIST_DEL(&kwl->list);
9238 LIST_INIT(&kwl->list);
9239}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009240
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009241/* this function register new section in the haproxy configuration file.
9242 * <section_name> is the name of this new section and <section_parser>
9243 * is the called parser. If two section declaration have the same name,
9244 * only the first declared is used.
9245 */
9246int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009247 int (*section_parser)(const char *, int, char **, int),
9248 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009249{
9250 struct cfg_section *cs;
9251
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009252 list_for_each_entry(cs, &sections, list) {
9253 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009254 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009255 return 0;
9256 }
9257 }
9258
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009259 cs = calloc(1, sizeof(*cs));
9260 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009261 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009262 return 0;
9263 }
9264
9265 cs->section_name = section_name;
9266 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009267 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009268
9269 LIST_ADDQ(&sections, &cs->list);
9270
9271 return 1;
9272}
9273
William Lallemand48b4bb42017-10-23 14:36:34 +02009274/* this function register a new function which will be called once the haproxy
9275 * configuration file has been parsed. It's useful to check dependencies
9276 * between sections or to resolve items once everything is parsed.
9277 */
9278int cfg_register_postparser(char *name, int (*func)())
9279{
9280 struct cfg_postparser *cp;
9281
9282 cp = calloc(1, sizeof(*cp));
9283 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009284 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009285 return 0;
9286 }
9287 cp->name = name;
9288 cp->func = func;
9289
9290 LIST_ADDQ(&postparsers, &cp->list);
9291
9292 return 1;
9293}
9294
Willy Tarreaubaaee002006-06-26 02:48:02 +02009295/*
David Carlier845efb52015-09-25 11:49:18 +01009296 * free all config section entries
9297 */
9298void cfg_unregister_sections(void)
9299{
9300 struct cfg_section *cs, *ics;
9301
9302 list_for_each_entry_safe(cs, ics, &sections, list) {
9303 LIST_DEL(&cs->list);
9304 free(cs);
9305 }
9306}
9307
Christopher Faulet7110b402016-10-26 11:09:44 +02009308void cfg_backup_sections(struct list *backup_sections)
9309{
9310 struct cfg_section *cs, *ics;
9311
9312 list_for_each_entry_safe(cs, ics, &sections, list) {
9313 LIST_DEL(&cs->list);
9314 LIST_ADDQ(backup_sections, &cs->list);
9315 }
9316}
9317
9318void cfg_restore_sections(struct list *backup_sections)
9319{
9320 struct cfg_section *cs, *ics;
9321
9322 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9323 LIST_DEL(&cs->list);
9324 LIST_ADDQ(&sections, &cs->list);
9325 }
9326}
9327
Willy Tarreau659fbf02016-05-26 17:55:28 +02009328__attribute__((constructor))
9329static void cfgparse_init(void)
9330{
9331 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009332 cfg_register_section("listen", cfg_parse_listen, NULL);
9333 cfg_register_section("frontend", cfg_parse_listen, NULL);
9334 cfg_register_section("backend", cfg_parse_listen, NULL);
9335 cfg_register_section("defaults", cfg_parse_listen, NULL);
9336 cfg_register_section("global", cfg_parse_global, NULL);
9337 cfg_register_section("userlist", cfg_parse_users, NULL);
9338 cfg_register_section("peers", cfg_parse_peers, NULL);
9339 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9340 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9341 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009342}
9343
David Carlier845efb52015-09-25 11:49:18 +01009344/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009345 * Local variables:
9346 * c-indent-level: 8
9347 * c-basic-offset: 8
9348 * End:
9349 */