blob: 1e73e32e1c4035c6c8d055aa9bbc1693d14f8cc7 [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 Tarreau66aa61f2009-01-18 21:44:07 +0100211 { NULL, 0, 0, 0 }
212};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200213
Willy Tarreau6daf3432008-01-22 16:44:08 +0100214static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200215static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
216int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100217int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100218char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200219
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200220/* List head of all known configuration keywords */
221static struct cfg_kw_list cfg_keywords = {
222 .list = LIST_HEAD_INIT(cfg_keywords.list)
223};
224
Willy Tarreaubaaee002006-06-26 02:48:02 +0200225/*
226 * converts <str> to a list of listeners which are dynamically allocated.
227 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
228 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
229 * - <port> is a numerical port from 1 to 65535 ;
230 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
231 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200232 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
233 * not NULL, it must be a valid pointer to either NULL or a freeable area that
234 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200235 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200236int 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 +0200237{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100238 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200239 int port, end;
240
241 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200242
Willy Tarreaubaaee002006-06-26 02:48:02 +0200243 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100244 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200245 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100246 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200247
248 str = next;
249 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100250 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200251 *next++ = 0;
252 }
253
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100254 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200255 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200256 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100257 if (!ss2)
258 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200259
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100260 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100261 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200262 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100263 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200264 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200265
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100266 if (!port || !end) {
267 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
268 goto fail;
269 }
270
Emeric Bruned760922010-10-22 17:59:25 +0200271 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200272 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200273 goto fail;
274 }
275
276 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200277 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200278 goto fail;
279 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200280 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100281 else if (ss2->ss_family == AF_UNSPEC) {
282 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100283 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100284
285 /* We want to attach to an already bound fd whose number
286 * is in the addr part of ss2 when cast to sockaddr_in.
287 * Note that by definition there is a single listener.
288 * We still have to determine the address family to
289 * register the correct protocol.
290 */
291 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
292 addr_len = sizeof(*ss2);
293 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
294 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
295 goto fail;
296 }
297
298 port = end = get_host_port(ss2);
William Lallemand2fe7dd02018-09-11 16:51:29 +0200299
300 } else if (ss2->ss_family == AF_CUST_SOCKPAIR) {
301 socklen_t addr_len;
302 inherited = 1;
303
304 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
305 addr_len = sizeof(*ss2);
306 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
307 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
308 goto fail;
309 }
310
311 ss2->ss_family = AF_CUST_SOCKPAIR; /* reassign AF_CUST_SOCKPAIR because of getsockname */
312 port = end = 0;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100313 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200314
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100315 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100316 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200317 memprintf(err, "%s for address '%s'.\n", *err, str);
318 goto fail;
319 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200320 } /* end while(next) */
321 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200322 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200323 fail:
324 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200325 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200326}
327
William Lallemand6e62fb62015-04-28 16:55:23 +0200328/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100329 * Report an error in <msg> when there are too many arguments. This version is
330 * intended to be used by keyword parsers so that the message will be included
331 * into the general error message. The index is the current keyword in args.
332 * Return 0 if the number of argument is correct, otherwise build a message and
333 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
334 * message may also be null, it will simply not be produced (useful to check only).
335 * <msg> and <err_code> are only affected on error.
336 */
337int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
338{
339 int i;
340
341 if (!*args[index + maxarg + 1])
342 return 0;
343
344 if (msg) {
345 *msg = NULL;
346 memprintf(msg, "%s", args[0]);
347 for (i = 1; i <= index; i++)
348 memprintf(msg, "%s %s", *msg, args[i]);
349
350 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
351 }
352 if (err_code)
353 *err_code |= ERR_ALERT | ERR_FATAL;
354
355 return 1;
356}
357
358/*
359 * same as too_many_args_idx with a 0 index
360 */
361int too_many_args(int maxarg, char **args, char **msg, int *err_code)
362{
363 return too_many_args_idx(maxarg, 0, args, msg, err_code);
364}
365
366/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200367 * Report a fatal Alert when there is too much arguments
368 * The index is the current keyword in args
369 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
370 * Fill err_code with an ERR_ALERT and an ERR_FATAL
371 */
372int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
373{
374 char *kw = NULL;
375 int i;
376
377 if (!*args[index + maxarg + 1])
378 return 0;
379
380 memprintf(&kw, "%s", args[0]);
381 for (i = 1; i <= index; i++) {
382 memprintf(&kw, "%s %s", kw, args[i]);
383 }
384
Christopher Faulet767a84b2017-11-24 16:50:31 +0100385 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 +0200386 free(kw);
387 *err_code |= ERR_ALERT | ERR_FATAL;
388 return 1;
389}
390
391/*
392 * same as alertif_too_many_args_idx with a 0 index
393 */
394int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
395{
396 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
397}
398
Willy Tarreau620408f2016-10-21 16:37:51 +0200399/* Report a warning if a rule is placed after a 'tcp-request session' rule.
400 * Return 1 if the warning has been emitted, otherwise 0.
401 */
402int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
403{
404 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100405 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
406 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200407 return 1;
408 }
409 return 0;
410}
411
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200412/* Report a warning if a rule is placed after a 'tcp-request content' rule.
413 * Return 1 if the warning has been emitted, otherwise 0.
414 */
415int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
416{
417 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100418 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
419 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200420 return 1;
421 }
422 return 0;
423}
424
Willy Tarreau721d8e02017-12-01 18:25:08 +0100425/* Report a warning if a rule is placed after a 'monitor fail' rule.
426 * Return 1 if the warning has been emitted, otherwise 0.
427 */
428int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
429{
430 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
431 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
432 file, line, arg);
433 return 1;
434 }
435 return 0;
436}
437
Willy Tarreau61d18892009-03-31 10:49:21 +0200438/* Report a warning if a rule is placed after a 'block' rule.
439 * Return 1 if the warning has been emitted, otherwise 0.
440 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100441int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200442{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200443 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100444 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
445 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200446 return 1;
447 }
448 return 0;
449}
450
Willy Tarreau5002f572014-04-23 01:32:02 +0200451/* Report a warning if a rule is placed after an 'http_request' rule.
452 * Return 1 if the warning has been emitted, otherwise 0.
453 */
454int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
455{
456 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100457 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
458 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200459 return 1;
460 }
461 return 0;
462}
463
Willy Tarreau61d18892009-03-31 10:49:21 +0200464/* Report a warning if a rule is placed after a reqrewrite rule.
465 * Return 1 if the warning has been emitted, otherwise 0.
466 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100467int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200468{
469 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100470 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
471 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200472 return 1;
473 }
474 return 0;
475}
476
477/* Report a warning if a rule is placed after a reqadd rule.
478 * Return 1 if the warning has been emitted, otherwise 0.
479 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100480int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200481{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100482 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100483 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
484 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200485 return 1;
486 }
487 return 0;
488}
489
490/* Report a warning if a rule is placed after a redirect rule.
491 * Return 1 if the warning has been emitted, otherwise 0.
492 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100493int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200494{
495 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100496 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
497 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200498 return 1;
499 }
500 return 0;
501}
502
503/* Report a warning if a rule is placed after a 'use_backend' rule.
504 * Return 1 if the warning has been emitted, otherwise 0.
505 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100506int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200507{
508 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100509 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
510 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200511 return 1;
512 }
513 return 0;
514}
515
Willy Tarreauee445d92014-04-23 01:39:04 +0200516/* Report a warning if a rule is placed after a 'use-server' rule.
517 * Return 1 if the warning has been emitted, otherwise 0.
518 */
519int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
520{
521 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100522 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
523 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200524 return 1;
525 }
526 return 0;
527}
528
Willy Tarreaud39ad442016-11-25 15:16:12 +0100529/* report a warning if a redirect rule is dangerously placed */
530int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200531{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100532 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200533 warnif_rule_after_use_server(proxy, file, line, arg);
534}
535
Willy Tarreaud39ad442016-11-25 15:16:12 +0100536/* report a warning if a reqadd rule is dangerously placed */
537int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200538{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100539 return warnif_rule_after_redirect(proxy, file, line, arg) ||
540 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200541}
542
Willy Tarreaud39ad442016-11-25 15:16:12 +0100543/* report a warning if a reqxxx rule is dangerously placed */
544int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200545{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100546 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
547 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200548}
549
550/* report a warning if an http-request rule is dangerously placed */
551int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
552{
Willy Tarreau61d18892009-03-31 10:49:21 +0200553 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100554 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200555}
556
Willy Tarreaud39ad442016-11-25 15:16:12 +0100557/* report a warning if a block rule is dangerously placed */
558int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200559{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100560 return warnif_rule_after_http_req(proxy, file, line, arg) ||
561 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200562}
563
Willy Tarreau721d8e02017-12-01 18:25:08 +0100564/* report a warning if a block rule is dangerously placed */
565int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200566{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100567 return warnif_rule_after_block(proxy, file, line, arg) ||
568 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200569}
570
Willy Tarreau721d8e02017-12-01 18:25:08 +0100571/* report a warning if a "tcp request content" rule is dangerously placed */
572int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
573{
574 return warnif_rule_after_monitor(proxy, file, line, arg) ||
575 warnif_misplaced_monitor(proxy, file, line, arg);
576}
577
Willy Tarreaud39ad442016-11-25 15:16:12 +0100578/* report a warning if a "tcp request session" rule is dangerously placed */
579int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200580{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100581 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
582 warnif_misplaced_tcp_cont(proxy, file, line, arg);
583}
584
585/* report a warning if a "tcp request connection" rule is dangerously placed */
586int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
587{
588 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
589 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200590}
591
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100592/* Report it if a request ACL condition uses some keywords that are incompatible
593 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
594 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
595 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100596 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100597static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100598{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100599 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200600 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100601
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100602 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100603 return 0;
604
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100605 acl = acl_cond_conflicts(cond, where);
606 if (acl) {
607 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100608 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
609 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100610 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100611 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
612 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100613 return ERR_WARN;
614 }
615 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100616 return 0;
617
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100618 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100619 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
620 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100621 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100622 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
623 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100624 return ERR_WARN;
625}
626
Christopher Faulet62519022017-10-16 15:49:32 +0200627/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100628 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100629 * two such numbers delimited by a dash ('-'). On success, it returns
630 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200631 *
632 * Note: this function can also be used to parse a thread number or a set of
633 * threads.
634 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100635int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200636{
Christopher Faulet26028f62017-11-22 15:01:51 +0100637 if (autoinc) {
638 *autoinc = 0;
639 if (strncmp(arg, "auto:", 5) == 0) {
640 arg += 5;
641 *autoinc = 1;
642 }
643 }
644
Christopher Faulet62519022017-10-16 15:49:32 +0200645 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100646 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200647 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100648 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200649 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100650 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200651 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100652 char *dash;
653 unsigned int low, high;
654
Christopher Faulet5ab51772017-11-22 11:21:58 +0100655 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100656 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100657 return -1;
658 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100659
660 low = high = str2uic(arg);
661 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100662 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
663
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100664 if (high < low) {
665 unsigned int swap = low;
666 low = high;
667 high = swap;
668 }
669
Christopher Faulet5ab51772017-11-22 11:21:58 +0100670 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100671 memprintf(err, "'%s' is not a valid number/range."
672 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100673 arg, LONGBITS);
674 return 1;
675 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100676
677 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100678 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200679 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100680
Christopher Faulet5ab51772017-11-22 11:21:58 +0100681 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200682}
683
David Carlier7e351ee2017-12-01 09:14:02 +0000684#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200685/* Parse cpu sets. Each CPU set is either a unique number between 0 and
686 * <LONGBITS> or a range with two such numbers delimited by a dash
687 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
688 * returns 0. otherwise it returns 1 with an error message in <err>.
689 */
690static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
691{
692 int cur_arg = 0;
693
694 *cpu_set = 0;
695 while (*args[cur_arg]) {
696 char *dash;
697 unsigned int low, high;
698
699 if (!isdigit((int)*args[cur_arg])) {
700 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
701 return -1;
702 }
703
704 low = high = str2uic(args[cur_arg]);
705 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100706 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200707
708 if (high < low) {
709 unsigned int swap = low;
710 low = high;
711 high = swap;
712 }
713
714 if (high >= LONGBITS) {
715 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
716 return 1;
717 }
718
719 while (low <= high)
720 *cpu_set |= 1UL << low++;
721
722 cur_arg++;
723 }
724 return 0;
725}
David Carlier7e351ee2017-12-01 09:14:02 +0000726#endif
727
Willy Tarreaubaaee002006-06-26 02:48:02 +0200728/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200729 * parse a line in a <global> section. Returns the error code, 0 if OK, or
730 * any combination of :
731 * - ERR_ABORT: must abort ASAP
732 * - ERR_FATAL: we can continue parsing but not start the service
733 * - ERR_WARN: a warning has been emitted
734 * - ERR_ALERT: an alert has been emitted
735 * Only the two first ones can stop processing, the two others are just
736 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200737 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200738int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200739{
Willy Tarreau058e9072009-07-20 09:30:05 +0200740 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200741 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200742
743 if (!strcmp(args[0], "global")) { /* new section */
744 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200745 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200746 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200747 }
748 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200749 if (alertif_too_many_args(0, file, linenum, args, &err_code))
750 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200751 global.mode |= MODE_DAEMON;
752 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200753 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200754 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200755 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200756 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100757 if (!strcmp(args[1], "no-exit-on-failure")) {
758 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200759 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100760 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 +0200761 err_code |= ERR_ALERT | ERR_FATAL;
762 goto out;
763 }
764 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200765 global.mode |= MODE_MWORKER;
766 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200767 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200768 if (alertif_too_many_args(0, file, linenum, args, &err_code))
769 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200770 global.mode |= MODE_DEBUG;
771 }
772 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200773 if (alertif_too_many_args(0, file, linenum, args, &err_code))
774 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100775 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200776 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200777 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200778 if (alertif_too_many_args(0, file, linenum, args, &err_code))
779 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100780 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200781 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200782 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200783 if (alertif_too_many_args(0, file, linenum, args, &err_code))
784 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100785 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200786 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100787 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200788 if (alertif_too_many_args(0, file, linenum, args, &err_code))
789 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100790 global.tune.options &= ~GTUNE_USE_SPLICE;
791 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200792 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200793 if (alertif_too_many_args(0, file, linenum, args, &err_code))
794 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200795 global.tune.options &= ~GTUNE_USE_GAI;
796 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000797 else if (!strcmp(args[0], "noreuseport")) {
798 if (alertif_too_many_args(0, file, linenum, args, &err_code))
799 goto out;
800 global.tune.options &= ~GTUNE_USE_REUSEPORT;
801 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200802 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200803 if (alertif_too_many_args(0, file, linenum, args, &err_code))
804 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200805 global.mode |= MODE_QUIET;
806 }
Olivier Houchard1599b802018-05-24 18:59:04 +0200807 else if (!strcmp(args[0], "tune.runqueue-depth")) {
808 if (alertif_too_many_args(1, file, linenum, args, &err_code))
809 goto out;
810 if (global.tune.runqueue_depth != 0) {
811 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
812 err_code |= ERR_ALERT;
813 goto out;
814 }
815 if (*(args[1]) == 0) {
816 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
817 err_code |= ERR_ALERT | ERR_FATAL;
818 goto out;
819 }
820 global.tune.runqueue_depth = atol(args[1]);
821
822 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200823 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200824 if (alertif_too_many_args(1, file, linenum, args, &err_code))
825 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200826 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100827 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200828 err_code |= ERR_ALERT;
829 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200830 }
831 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100832 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200833 err_code |= ERR_ALERT | ERR_FATAL;
834 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200835 }
836 global.tune.maxpollevents = atol(args[1]);
837 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100838 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200839 if (alertif_too_many_args(1, file, linenum, args, &err_code))
840 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100841 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100842 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200843 err_code |= ERR_ALERT;
844 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100845 }
846 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100847 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200848 err_code |= ERR_ALERT | ERR_FATAL;
849 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100850 }
851 global.tune.maxaccept = atol(args[1]);
852 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200853 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200854 if (alertif_too_many_args(1, file, linenum, args, &err_code))
855 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200856 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100857 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200858 err_code |= ERR_ALERT | ERR_FATAL;
859 goto out;
860 }
861 global.tune.chksize = atol(args[1]);
862 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100863 else if (!strcmp(args[0], "tune.recv_enough")) {
864 if (alertif_too_many_args(1, file, linenum, args, &err_code))
865 goto out;
866 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100867 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100868 err_code |= ERR_ALERT | ERR_FATAL;
869 goto out;
870 }
871 global.tune.recv_enough = atol(args[1]);
872 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100873 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200874 if (alertif_too_many_args(1, file, linenum, args, &err_code))
875 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100876 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100877 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100878 err_code |= ERR_ALERT | ERR_FATAL;
879 goto out;
880 }
881 global.tune.buf_limit = atol(args[1]);
882 if (global.tune.buf_limit) {
883 if (global.tune.buf_limit < 3)
884 global.tune.buf_limit = 3;
885 if (global.tune.buf_limit <= global.tune.reserved_bufs)
886 global.tune.buf_limit = global.tune.reserved_bufs + 1;
887 }
888 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100889 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200890 if (alertif_too_many_args(1, file, linenum, args, &err_code))
891 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100892 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100893 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100894 err_code |= ERR_ALERT | ERR_FATAL;
895 goto out;
896 }
897 global.tune.reserved_bufs = atol(args[1]);
898 if (global.tune.reserved_bufs < 2)
899 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100900 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
901 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100902 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200903 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200904 if (alertif_too_many_args(1, file, linenum, args, &err_code))
905 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200906 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100907 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200908 err_code |= ERR_ALERT | ERR_FATAL;
909 goto out;
910 }
911 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200912 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100913 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200914 err_code |= ERR_ALERT | ERR_FATAL;
915 goto out;
916 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200917 }
918 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200919 if (alertif_too_many_args(1, file, linenum, args, &err_code))
920 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200921 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100922 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200923 err_code |= ERR_ALERT | ERR_FATAL;
924 goto out;
925 }
926 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200927 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100928 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200929 err_code |= ERR_ALERT | ERR_FATAL;
930 goto out;
931 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200932 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100933 else if (!strcmp(args[0], "tune.idletimer")) {
934 unsigned int idle;
935 const char *res;
936
William Lallemand1a748ae2015-05-19 16:37:23 +0200937 if (alertif_too_many_args(1, file, linenum, args, &err_code))
938 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100939 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100940 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 +0100941 err_code |= ERR_ALERT | ERR_FATAL;
942 goto out;
943 }
944
945 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
946 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100947 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100948 file, linenum, *res, args[0]);
949 err_code |= ERR_ALERT | ERR_FATAL;
950 goto out;
951 }
952
953 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100954 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 +0100955 err_code |= ERR_ALERT | ERR_FATAL;
956 goto out;
957 }
958 global.tune.idle_timer = idle;
959 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100960 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200961 if (alertif_too_many_args(1, file, linenum, args, &err_code))
962 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100963 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100964 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100965 err_code |= ERR_ALERT;
966 goto out;
967 }
968 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100969 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100970 err_code |= ERR_ALERT | ERR_FATAL;
971 goto out;
972 }
973 global.tune.client_rcvbuf = atol(args[1]);
974 }
975 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200976 if (alertif_too_many_args(1, file, linenum, args, &err_code))
977 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100978 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100979 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100980 err_code |= ERR_ALERT;
981 goto out;
982 }
983 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100984 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100985 err_code |= ERR_ALERT | ERR_FATAL;
986 goto out;
987 }
988 global.tune.server_rcvbuf = atol(args[1]);
989 }
990 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200991 if (alertif_too_many_args(1, file, linenum, args, &err_code))
992 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100993 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100994 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100995 err_code |= ERR_ALERT;
996 goto out;
997 }
998 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100999 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001000 err_code |= ERR_ALERT | ERR_FATAL;
1001 goto out;
1002 }
1003 global.tune.client_sndbuf = atol(args[1]);
1004 }
1005 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001006 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1007 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +01001008 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001009 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001010 err_code |= ERR_ALERT;
1011 goto out;
1012 }
1013 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001014 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001015 err_code |= ERR_ALERT | ERR_FATAL;
1016 goto out;
1017 }
1018 global.tune.server_sndbuf = atol(args[1]);
1019 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001020 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001021 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1022 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001023 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001024 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001025 err_code |= ERR_ALERT | ERR_FATAL;
1026 goto out;
1027 }
1028 global.tune.pipesize = atol(args[1]);
1029 }
Willy Tarreau193b8c62012-11-22 00:17:38 +01001030 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001031 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1032 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001033 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001034 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001035 err_code |= ERR_ALERT | ERR_FATAL;
1036 goto out;
1037 }
1038 global.tune.cookie_len = atol(args[1]) + 1;
1039 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001040 else if (!strcmp(args[0], "tune.http.logurilen")) {
1041 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1042 goto out;
1043 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001044 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001045 err_code |= ERR_ALERT | ERR_FATAL;
1046 goto out;
1047 }
1048 global.tune.requri_len = atol(args[1]) + 1;
1049 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001050 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001051 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1052 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001053 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001054 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001055 err_code |= ERR_ALERT | ERR_FATAL;
1056 goto out;
1057 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001058 global.tune.max_http_hdr = atoi(args[1]);
1059 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001060 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1061 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001062 err_code |= ERR_ALERT | ERR_FATAL;
1063 goto out;
1064 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001065 }
William Lallemandf3747832012-11-09 12:33:10 +01001066 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001067 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1068 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001069 if (*args[1]) {
1070 global.tune.comp_maxlevel = atoi(args[1]);
1071 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001072 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1073 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001074 err_code |= ERR_ALERT | ERR_FATAL;
1075 goto out;
1076 }
1077 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001078 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1079 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001080 err_code |= ERR_ALERT | ERR_FATAL;
1081 goto out;
1082 }
1083 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001084 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1085 if (*args[1]) {
1086 global.tune.pattern_cache = atoi(args[1]);
1087 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001088 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1089 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001090 err_code |= ERR_ALERT | ERR_FATAL;
1091 goto out;
1092 }
1093 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001094 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1095 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001096 err_code |= ERR_ALERT | ERR_FATAL;
1097 goto out;
1098 }
1099 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001100 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001101 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1102 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001103 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001104 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001105 err_code |= ERR_ALERT;
1106 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001107 }
1108 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001109 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001110 err_code |= ERR_ALERT | ERR_FATAL;
1111 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001112 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001113 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001114 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 +01001115 err_code |= ERR_WARN;
1116 goto out;
1117 }
1118
Willy Tarreaubaaee002006-06-26 02:48:02 +02001119 }
1120 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001121 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1122 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001123 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001124 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001125 err_code |= ERR_ALERT;
1126 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001127 }
1128 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001129 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001130 err_code |= ERR_ALERT | ERR_FATAL;
1131 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001132 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001133 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001134 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 +01001135 err_code |= ERR_WARN;
1136 goto out;
1137 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001138 }
Simon Horman98637e52014-06-20 12:30:16 +09001139 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001140 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1141 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001142 global.external_check = 1;
1143 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001144 /* user/group name handling */
1145 else if (!strcmp(args[0], "user")) {
1146 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001147 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1148 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001149 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001150 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001151 err_code |= ERR_ALERT;
1152 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001153 }
1154 errno = 0;
1155 ha_user = getpwnam(args[1]);
1156 if (ha_user != NULL) {
1157 global.uid = (int)ha_user->pw_uid;
1158 }
1159 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001160 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 +02001161 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001162 }
1163 }
1164 else if (!strcmp(args[0], "group")) {
1165 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001166 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1167 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001168 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001169 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001170 err_code |= ERR_ALERT;
1171 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001172 }
1173 errno = 0;
1174 ha_group = getgrnam(args[1]);
1175 if (ha_group != NULL) {
1176 global.gid = (int)ha_group->gr_gid;
1177 }
1178 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 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 +02001180 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001181 }
1182 }
1183 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001184 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001185 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1186 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001187 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001188 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001189 err_code |= ERR_ALERT | ERR_FATAL;
1190 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001191 }
1192 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001193 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001194 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1195 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001196 err_code |= ERR_ALERT | ERR_FATAL;
1197 goto out;
1198 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001199 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001200 else if (!strcmp(args[0], "nbthread")) {
1201 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1202 goto out;
1203 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001204 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001205 err_code |= ERR_ALERT | ERR_FATAL;
1206 goto out;
1207 }
Willy Tarreau0ccd3222018-07-30 10:34:35 +02001208 global.nbthread = parse_nbthread(args[1], &errmsg);
1209 if (!global.nbthread) {
1210 ha_alert("parsing [%s:%d] : '%s' %s.\n",
1211 file, linenum, args[0], errmsg);
Willy Tarreau421f02e2018-01-20 18:19:22 +01001212 err_code |= ERR_ALERT | ERR_FATAL;
1213 goto out;
1214 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001215 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001216 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001217 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1218 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001219 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001220 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001221 err_code |= ERR_ALERT;
1222 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001223 }
1224 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001225 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001226 err_code |= ERR_ALERT | ERR_FATAL;
1227 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001228 }
1229 global.maxconn = atol(args[1]);
1230#ifdef SYSTEM_MAXCONN
1231 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001232 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 +02001233 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001234 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001235 }
1236#endif /* SYSTEM_MAXCONN */
1237 }
Emeric Brun850efd52014-01-29 12:24:34 +01001238 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001239 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1240 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001241 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001242 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001243 err_code |= ERR_ALERT | ERR_FATAL;
1244 goto out;
1245 }
1246 if (strcmp(args[1],"none") == 0)
1247 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1248 else if (strcmp(args[1],"required") == 0)
1249 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1250 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001251 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001252 err_code |= ERR_ALERT | ERR_FATAL;
1253 goto out;
1254 }
1255 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001256 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001257 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1258 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001259 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001260 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001261 err_code |= ERR_ALERT;
1262 goto out;
1263 }
1264 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001265 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001266 err_code |= ERR_ALERT | ERR_FATAL;
1267 goto out;
1268 }
1269 global.cps_lim = atol(args[1]);
1270 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001271 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001272 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1273 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001274 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001275 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001276 err_code |= ERR_ALERT;
1277 goto out;
1278 }
1279 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001280 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001281 err_code |= ERR_ALERT | ERR_FATAL;
1282 goto out;
1283 }
1284 global.sps_lim = atol(args[1]);
1285 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001286 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001287 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1288 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001289 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001290 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001291 err_code |= ERR_ALERT;
1292 goto out;
1293 }
1294 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001295 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001296 err_code |= ERR_ALERT | ERR_FATAL;
1297 goto out;
1298 }
1299 global.ssl_lim = atol(args[1]);
1300 }
William Lallemandd85f9172012-11-09 17:05:39 +01001301 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001302 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1303 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001304 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001305 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 +01001306 err_code |= ERR_ALERT | ERR_FATAL;
1307 goto out;
1308 }
1309 global.comp_rate_lim = atoi(args[1]) * 1024;
1310 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001311 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001312 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1313 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001314 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001315 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001316 err_code |= ERR_ALERT;
1317 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001318 }
1319 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001320 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001321 err_code |= ERR_ALERT | ERR_FATAL;
1322 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001323 }
1324 global.maxpipes = atol(args[1]);
1325 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001326 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001327 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1328 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001329 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001330 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001331 err_code |= ERR_ALERT | ERR_FATAL;
1332 goto out;
1333 }
William Lallemande3a7d992012-11-20 11:25:20 +01001334 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001335 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001336 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001337 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1338 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001339 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001340 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 +01001341 err_code |= ERR_ALERT | ERR_FATAL;
1342 goto out;
1343 }
1344 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001345 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001346 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 +01001347 err_code |= ERR_ALERT | ERR_FATAL;
1348 goto out;
1349 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001350 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001351
Willy Tarreaubaaee002006-06-26 02:48:02 +02001352 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001353 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1354 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001355 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001356 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001357 err_code |= ERR_ALERT;
1358 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001359 }
1360 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001361 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001362 err_code |= ERR_ALERT | ERR_FATAL;
1363 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001364 }
1365 global.rlimit_nofile = atol(args[1]);
1366 }
1367 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001368 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1369 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001370 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001371 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001372 err_code |= ERR_ALERT;
1373 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001374 }
1375 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001376 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001377 err_code |= ERR_ALERT | ERR_FATAL;
1378 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001379 }
1380 global.chroot = strdup(args[1]);
1381 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001382 else if (!strcmp(args[0], "description")) {
1383 int i, len=0;
1384 char *d;
1385
1386 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001387 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1388 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001389 err_code |= ERR_ALERT | ERR_FATAL;
1390 goto out;
1391 }
1392
Willy Tarreau348acfe2014-04-14 15:00:39 +02001393 for (i = 1; *args[i]; i++)
1394 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001395
1396 if (global.desc)
1397 free(global.desc);
1398
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001399 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001400
Willy Tarreau348acfe2014-04-14 15:00:39 +02001401 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1402 for (i = 2; *args[i]; i++)
1403 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001404 }
1405 else if (!strcmp(args[0], "node")) {
1406 int i;
1407 char c;
1408
William Lallemand1a748ae2015-05-19 16:37:23 +02001409 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1410 goto out;
1411
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001412 for (i=0; args[1][i]; i++) {
1413 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001414 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1415 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001416 break;
1417 }
1418
1419 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001420 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1421 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1422 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001423 err_code |= ERR_ALERT | ERR_FATAL;
1424 goto out;
1425 }
1426
1427 if (global.node)
1428 free(global.node);
1429
1430 global.node = strdup(args[1]);
1431 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001432 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001433 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1434 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001435 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001436 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001437 err_code |= ERR_ALERT;
1438 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001439 }
1440 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001441 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 +02001442 err_code |= ERR_ALERT | ERR_FATAL;
1443 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001444 }
1445 global.pidfile = strdup(args[1]);
1446 }
Emeric Bruned760922010-10-22 17:59:25 +02001447 else if (!strcmp(args[0], "unix-bind")) {
1448 int cur_arg = 1;
1449 while (*(args[cur_arg])) {
1450 if (!strcmp(args[cur_arg], "prefix")) {
1451 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001452 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001453 err_code |= ERR_ALERT;
1454 cur_arg += 2;
1455 continue;
1456 }
1457
1458 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001459 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 +02001460 err_code |= ERR_ALERT | ERR_FATAL;
1461 goto out;
1462 }
1463 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1464 cur_arg += 2;
1465 continue;
1466 }
1467
1468 if (!strcmp(args[cur_arg], "mode")) {
1469
1470 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1471 cur_arg += 2;
1472 continue;
1473 }
1474
1475 if (!strcmp(args[cur_arg], "uid")) {
1476
1477 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1478 cur_arg += 2;
1479 continue;
1480 }
1481
1482 if (!strcmp(args[cur_arg], "gid")) {
1483
1484 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1485 cur_arg += 2;
1486 continue;
1487 }
1488
1489 if (!strcmp(args[cur_arg], "user")) {
1490 struct passwd *user;
1491
1492 user = getpwnam(args[cur_arg + 1]);
1493 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001494 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1495 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001496 err_code |= ERR_ALERT | ERR_FATAL;
1497 goto out;
1498 }
1499
1500 global.unix_bind.ux.uid = user->pw_uid;
1501 cur_arg += 2;
1502 continue;
1503 }
1504
1505 if (!strcmp(args[cur_arg], "group")) {
1506 struct group *group;
1507
1508 group = getgrnam(args[cur_arg + 1]);
1509 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001510 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1511 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001512 err_code |= ERR_ALERT | ERR_FATAL;
1513 goto out;
1514 }
1515
1516 global.unix_bind.ux.gid = group->gr_gid;
1517 cur_arg += 2;
1518 continue;
1519 }
1520
Christopher Faulet767a84b2017-11-24 16:50:31 +01001521 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1522 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001523 err_code |= ERR_ALERT | ERR_FATAL;
1524 goto out;
1525 }
1526 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001527 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1528 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1529 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001530 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001531 goto out;
1532 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001533 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001534 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1535 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001536
1537 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001538 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001539 err_code |= ERR_ALERT;
1540 goto out;
1541 }
1542
1543 if (*(args[1]))
1544 name = args[1];
1545 else
1546 name = hostname;
1547
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001548 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001549 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001550 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001551 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1552 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001553 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001554 err_code |= ERR_ALERT;
1555 goto out;
1556 }
1557
1558 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001559 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001560 err_code |= ERR_FATAL;
1561 goto out;
1562 }
1563
1564 global.server_state_base = strdup(args[1]);
1565 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001566 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1567 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001568 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001569 err_code |= ERR_ALERT;
1570 goto out;
1571 }
1572
1573 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001574 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001575 err_code |= ERR_FATAL;
1576 goto out;
1577 }
1578
1579 global.server_state_file = strdup(args[1]);
1580 }
Kevinm48936af2010-12-22 16:08:21 +00001581 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001582 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1583 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001584 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001585 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001586 err_code |= ERR_ALERT | ERR_FATAL;
1587 goto out;
1588 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001589 chunk_destroy(&global.log_tag);
1590 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001591 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001592 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001593 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1594 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001595 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001596 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001597 err_code |= ERR_ALERT;
1598 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001599 }
1600 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001601 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001602 err_code |= ERR_ALERT | ERR_FATAL;
1603 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001604 }
1605 global.spread_checks = atol(args[1]);
1606 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001607 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 +02001608 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001609 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001610 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001611 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1612 const char *err;
1613 unsigned int val;
1614
William Lallemand1a748ae2015-05-19 16:37:23 +02001615 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1616 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001617 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001618 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001619 err_code |= ERR_ALERT | ERR_FATAL;
1620 goto out;
1621 }
1622
1623 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1624 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001625 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 +02001626 err_code |= ERR_ALERT | ERR_FATAL;
1627 }
1628 global.max_spread_checks = val;
1629 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001630 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001631 err_code |= ERR_ALERT | ERR_FATAL;
1632 }
1633 }
Christopher Faulet62519022017-10-16 15:49:32 +02001634 else if (strcmp(args[0], "cpu-map") == 0) {
1635 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001636#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001637 char *slash;
1638 unsigned long proc = 0, thread = 0, cpus;
1639 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001640
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001641 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001642 ha_alert("parsing [%s:%d] : %s expects a process number "
1643 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1644 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1645 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001646 err_code |= ERR_ALERT | ERR_FATAL;
1647 goto out;
1648 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001649
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001650 if ((slash = strchr(args[1], '/')) != NULL)
1651 *slash = 0;
1652
Christopher Faulet26028f62017-11-22 15:01:51 +01001653 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001654 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001655 err_code |= ERR_ALERT | ERR_FATAL;
1656 goto out;
1657 }
1658
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001659 if (slash) {
1660 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001661 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001662 err_code |= ERR_ALERT | ERR_FATAL;
1663 goto out;
1664 }
1665 *slash = '/';
1666
1667 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001668 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1669 "a process range _AND_ a thread range\n",
1670 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001671 err_code |= ERR_ALERT | ERR_FATAL;
1672 goto out;
1673 }
1674 }
1675
Christopher Faulet62519022017-10-16 15:49:32 +02001676 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001677 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001678 err_code |= ERR_ALERT | ERR_FATAL;
1679 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001680 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001681
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001682 if (autoinc &&
1683 my_popcountl(proc) != my_popcountl(cpus) &&
1684 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001685 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1686 "must have the same size to be automatically bound\n",
1687 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001688 err_code |= ERR_ALERT | ERR_FATAL;
1689 goto out;
1690 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001691
Christopher Faulet26028f62017-11-22 15:01:51 +01001692 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001693 /* No mapping for this process */
1694 if (!(proc & (1UL << i)))
1695 continue;
1696
1697 /* Mapping at the process level */
1698 if (!thread) {
1699 if (!autoinc)
1700 global.cpu_map.proc[i] = cpus;
1701 else {
1702 n += my_ffsl(cpus >> n);
1703 global.cpu_map.proc[i] = (1UL << (n-1));
1704 }
1705 continue;
1706 }
1707
1708 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001709 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001710 /* Np mapping for this thread */
1711 if (!(thread & (1UL << j)))
1712 continue;
1713
1714 if (!autoinc)
1715 global.cpu_map.thread[i][j] = cpus;
1716 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001717 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001718 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001719 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001720 }
1721 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001722#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001723 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1724 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001725 err_code |= ERR_ALERT | ERR_FATAL;
1726 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001727#endif /* ! USE_CPU_AFFINITY */
1728 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001729 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1730 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1731 goto out;
1732
1733 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001734 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001735 err_code |= ERR_ALERT | ERR_FATAL;
1736 goto out;
1737 }
1738
1739 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1740 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001741 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 +01001742 err_code |= ERR_ALERT | ERR_FATAL;
1743 goto out;
1744 }
1745 }
1746 else if (!strcmp(args[0], "unsetenv")) {
1747 int arg;
1748
1749 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001750 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001751 err_code |= ERR_ALERT | ERR_FATAL;
1752 goto out;
1753 }
1754
1755 for (arg = 1; *args[arg]; arg++) {
1756 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001757 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 +01001758 err_code |= ERR_ALERT | ERR_FATAL;
1759 goto out;
1760 }
1761 }
1762 }
1763 else if (!strcmp(args[0], "resetenv")) {
1764 extern char **environ;
1765 char **env = environ;
1766
1767 /* args contain variable names to keep, one per argument */
1768 while (*env) {
1769 int arg;
1770
1771 /* look for current variable in among all those we want to keep */
1772 for (arg = 1; *args[arg]; arg++) {
1773 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1774 (*env)[strlen(args[arg])] == '=')
1775 break;
1776 }
1777
1778 /* delete this variable */
1779 if (!*args[arg]) {
1780 char *delim = strchr(*env, '=');
1781
1782 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001783 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 +01001784 err_code |= ERR_ALERT | ERR_FATAL;
1785 goto out;
1786 }
1787
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001788 memcpy(trash.area, *env, delim - *env);
1789 trash.area[delim - *env] = 0;
Willy Tarreau1d549722016-02-16 12:41:57 +01001790
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001791 if (unsetenv(trash.area) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001792 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 +01001793 err_code |= ERR_ALERT | ERR_FATAL;
1794 goto out;
1795 }
1796 }
1797 else
1798 env++;
1799 }
1800 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001801 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001802 struct cfg_kw_list *kwl;
1803 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001804 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001805
1806 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1807 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1808 if (kwl->kw[index].section != CFG_GLOBAL)
1809 continue;
1810 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001811 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001812 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001813 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001814 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001815 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001816 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001817 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001818 err_code |= ERR_WARN;
1819 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001820 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001821 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001822 }
1823 }
1824 }
1825
Christopher Faulet767a84b2017-11-24 16:50:31 +01001826 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001827 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001828 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001829
Willy Tarreau058e9072009-07-20 09:30:05 +02001830 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001831 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001832 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001833}
1834
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001835void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001836{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001837 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001838 defproxy.mode = PR_MODE_TCP;
1839 defproxy.state = PR_STNEW;
1840 defproxy.maxconn = cfg_maxpconn;
1841 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001842 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001843 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001844
Simon Horman66183002013-02-23 10:16:43 +09001845 defproxy.defsrv.check.inter = DEF_CHKINTR;
1846 defproxy.defsrv.check.fastinter = 0;
1847 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001848 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1849 defproxy.defsrv.agent.fastinter = 0;
1850 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001851 defproxy.defsrv.check.rise = DEF_RISETIME;
1852 defproxy.defsrv.check.fall = DEF_FALLTIME;
1853 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1854 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001855 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001856 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001857 defproxy.defsrv.maxqueue = 0;
1858 defproxy.defsrv.minconn = 0;
1859 defproxy.defsrv.maxconn = 0;
1860 defproxy.defsrv.slowstart = 0;
1861 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1862 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1863 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001864
1865 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001866 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001867}
1868
Willy Tarreauade5ec42010-01-28 19:33:49 +01001869
Willy Tarreau63af98d2014-05-18 08:11:41 +02001870/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1871 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1872 * ERR_FATAL in case of error.
1873 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001874static int create_cond_regex_rule(const char *file, int line,
1875 struct proxy *px, int dir, int action, int flags,
1876 const char *cmd, const char *reg, const char *repl,
1877 const char **cond_start)
1878{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001879 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001880 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001881 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001882 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001883 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001884 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001885 int cs;
1886 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001887
1888 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001889 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001890 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001891 goto err;
1892 }
1893
1894 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001895 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001896 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001897 goto err;
1898 }
1899
Christopher Faulet898566e2016-10-26 11:06:28 +02001900 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001901 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001902
Willy Tarreau5321c422010-01-28 20:35:13 +01001903 if (cond_start &&
1904 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001905 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001906 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1907 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001908 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001909 goto err;
1910 }
1911 }
1912 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001913 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1914 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001915 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001916 goto err;
1917 }
1918
Willy Tarreau63af98d2014-05-18 08:11:41 +02001919 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001920 (dir == SMP_OPT_DIR_REQ) ?
1921 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1922 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1923 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001924
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001925 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001926 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001927 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001928 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001929 goto err;
1930 }
1931
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001932 cs = !(flags & REG_ICASE);
1933 cap = !(flags & REG_NOSUB);
1934 error = NULL;
1935 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001936 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001937 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001938 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001939 goto err;
1940 }
1941
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001942 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001943 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001944 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001945 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1946 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001947 ret_code |= ERR_ALERT | ERR_FATAL;
1948 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001949 }
1950
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001951 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001952 ret_code |= ERR_WARN;
1953
1954 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001955
Willy Tarreau63af98d2014-05-18 08:11:41 +02001956 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001957 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001958 err:
1959 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001960 free(errmsg);
1961 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001962}
1963
Willy Tarreaubaaee002006-06-26 02:48:02 +02001964/*
William Lallemand51097192015-04-14 16:35:22 +02001965 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001966 * Returns the error code, 0 if OK, or any combination of :
1967 * - ERR_ABORT: must abort ASAP
1968 * - ERR_FATAL: we can continue parsing but not start the service
1969 * - ERR_WARN: a warning has been emitted
1970 * - ERR_ALERT: an alert has been emitted
1971 * Only the two first ones can stop processing, the two others are just
1972 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001973 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001974int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1975{
1976 static struct peers *curpeers = NULL;
1977 struct peer *newpeer = NULL;
1978 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001979 struct bind_conf *bind_conf;
1980 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001981 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001982 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001983
1984 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001985 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001986 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001987 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001988 goto out;
1989 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001990
William Lallemand6e62fb62015-04-28 16:55:23 +02001991 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1992 goto out;
1993
Emeric Brun32da3c42010-09-23 18:39:19 +02001994 err = invalid_char(args[1]);
1995 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001996 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1997 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001998 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001999 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002000 }
2001
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002002 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02002003 /*
2004 * If there are two proxies with the same name only following
2005 * combinations are allowed:
2006 */
2007 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002008 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2009 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002010 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002011 }
2012 }
2013
Vincent Bernat02779b62016-04-03 13:48:43 +02002014 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002015 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002016 err_code |= ERR_ALERT | ERR_ABORT;
2017 goto out;
2018 }
2019
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002020 curpeers->next = cfg_peers;
2021 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002022 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002023 curpeers->conf.line = linenum;
2024 curpeers->last_change = now.tv_sec;
2025 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002026 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002027 }
2028 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002029 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002030 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002031 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002032
2033 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002034 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2035 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002036 err_code |= ERR_ALERT | ERR_FATAL;
2037 goto out;
2038 }
2039
2040 err = invalid_char(args[1]);
2041 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002042 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2043 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002044 err_code |= ERR_ALERT | ERR_FATAL;
2045 goto out;
2046 }
2047
Vincent Bernat02779b62016-04-03 13:48:43 +02002048 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002049 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002050 err_code |= ERR_ALERT | ERR_ABORT;
2051 goto out;
2052 }
2053
2054 /* the peers are linked backwards first */
2055 curpeers->count++;
2056 newpeer->next = curpeers->remote;
2057 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002058 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002059 newpeer->conf.line = linenum;
2060
2061 newpeer->last_change = now.tv_sec;
2062 newpeer->id = strdup(args[1]);
2063
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002064 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002065 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002066 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002067 err_code |= ERR_ALERT | ERR_FATAL;
2068 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002069 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002070
2071 proto = protocol_by_family(sk->ss_family);
2072 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002073 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2074 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002075 err_code |= ERR_ALERT | ERR_FATAL;
2076 goto out;
2077 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002078
2079 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002080 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2081 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002082 err_code |= ERR_ALERT | ERR_FATAL;
2083 goto out;
2084 }
2085
Willy Tarreau2aa38802013-02-20 19:20:59 +01002086 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002087 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2088 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002089 err_code |= ERR_ALERT | ERR_FATAL;
2090 goto out;
2091 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002092
Emeric Brun32da3c42010-09-23 18:39:19 +02002093 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002094 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002095 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002096 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002097 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002098
Emeric Brun32da3c42010-09-23 18:39:19 +02002099 if (strcmp(newpeer->id, localpeer) == 0) {
2100 /* Current is local peer, it define a frontend */
2101 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002102 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002103
2104 if (!curpeers->peers_fe) {
2105 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002106 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002107 err_code |= ERR_ALERT | ERR_ABORT;
2108 goto out;
2109 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002110
Willy Tarreau237250c2011-07-29 01:49:03 +02002111 init_new_proxy(curpeers->peers_fe);
2112 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002113 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002114 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2115 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002116 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002117
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002118 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002119
Willy Tarreau902636f2013-03-10 19:44:48 +01002120 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2121 if (errmsg && *errmsg) {
2122 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002123 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002124 }
2125 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002126 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2127 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002128 err_code |= ERR_FATAL;
2129 goto out;
2130 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002131
2132 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002133 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002134 l->maxconn = curpeers->peers_fe->maxconn;
2135 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002136 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002137 l->analysers |= curpeers->peers_fe->fe_req_ana;
2138 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002139 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2140 global.maxsock += l->maxconn;
2141 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002142 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002143 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002144 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2145 file, linenum, args[0], args[1],
2146 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002147 err_code |= ERR_FATAL;
2148 goto out;
2149 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002150 }
2151 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002152 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2153 curpeers->state = PR_STSTOPPED;
2154 }
2155 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2156 curpeers->state = PR_STNEW;
2157 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002158 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002159 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002160 err_code |= ERR_ALERT | ERR_FATAL;
2161 goto out;
2162 }
2163
2164out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002165 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002166 return err_code;
2167}
2168
Baptiste Assmann325137d2015-04-13 23:40:55 +02002169/*
2170 * Parse a <resolvers> section.
2171 * Returns the error code, 0 if OK, or any combination of :
2172 * - ERR_ABORT: must abort ASAP
2173 * - ERR_FATAL: we can continue parsing but not start the service
2174 * - ERR_WARN: a warning has been emitted
2175 * - ERR_ALERT: an alert has been emitted
2176 * Only the two first ones can stop processing, the two others are just
2177 * indicators.
2178 */
2179int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2180{
2181 static struct dns_resolvers *curr_resolvers = NULL;
2182 struct dns_nameserver *newnameserver = NULL;
2183 const char *err;
2184 int err_code = 0;
2185 char *errmsg = NULL;
2186
2187 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2188 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002189 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002190 err_code |= ERR_ALERT | ERR_ABORT;
2191 goto out;
2192 }
2193
2194 err = invalid_char(args[1]);
2195 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002196 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2197 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002198 err_code |= ERR_ALERT | ERR_ABORT;
2199 goto out;
2200 }
2201
2202 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2203 /* Error if two resolvers owns the same name */
2204 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002205 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2206 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002207 err_code |= ERR_ALERT | ERR_ABORT;
2208 }
2209 }
2210
Vincent Bernat02779b62016-04-03 13:48:43 +02002211 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002212 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002213 err_code |= ERR_ALERT | ERR_ABORT;
2214 goto out;
2215 }
2216
2217 /* default values */
2218 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2219 curr_resolvers->conf.file = strdup(file);
2220 curr_resolvers->conf.line = linenum;
2221 curr_resolvers->id = strdup(args[1]);
2222 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002223 /* default maximum response size */
2224 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002225 /* default hold period for nx, other, refuse and timeout is 30s */
2226 curr_resolvers->hold.nx = 30000;
2227 curr_resolvers->hold.other = 30000;
2228 curr_resolvers->hold.refused = 30000;
2229 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002230 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002231 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002232 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002233 curr_resolvers->timeout.resolve = 1000;
2234 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002235 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002236 curr_resolvers->nb_nameservers = 0;
2237 LIST_INIT(&curr_resolvers->nameservers);
2238 LIST_INIT(&curr_resolvers->resolutions.curr);
2239 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002240 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002241 }
2242 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2243 struct sockaddr_storage *sk;
2244 int port1, port2;
2245 struct protocol *proto;
2246
2247 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002248 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2249 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002250 err_code |= ERR_ALERT | ERR_FATAL;
2251 goto out;
2252 }
2253
2254 err = invalid_char(args[1]);
2255 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002256 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2257 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002258 err_code |= ERR_ALERT | ERR_FATAL;
2259 goto out;
2260 }
2261
Christopher Faulet67957bd2017-09-27 11:00:59 +02002262 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002263 /* Error if two resolvers owns the same name */
2264 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002265 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 -06002266 file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002267 err_code |= ERR_ALERT | ERR_FATAL;
2268 }
2269 }
2270
Vincent Bernat02779b62016-04-03 13:48:43 +02002271 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002272 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002273 err_code |= ERR_ALERT | ERR_ABORT;
2274 goto out;
2275 }
2276
2277 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002278 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002279 newnameserver->resolvers = curr_resolvers;
2280 newnameserver->conf.file = strdup(file);
2281 newnameserver->conf.line = linenum;
2282 newnameserver->id = strdup(args[1]);
2283
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002284 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002285 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002286 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002287 err_code |= ERR_ALERT | ERR_FATAL;
2288 goto out;
2289 }
2290
2291 proto = protocol_by_family(sk->ss_family);
2292 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002293 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002294 file, linenum, args[0], args[1]);
2295 err_code |= ERR_ALERT | ERR_FATAL;
2296 goto out;
2297 }
2298
2299 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002300 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2301 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002302 err_code |= ERR_ALERT | ERR_FATAL;
2303 goto out;
2304 }
2305
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002306 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002307 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2308 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002309 err_code |= ERR_ALERT | ERR_FATAL;
2310 goto out;
2311 }
2312
Baptiste Assmann325137d2015-04-13 23:40:55 +02002313 newnameserver->addr = *sk;
2314 }
Ben Draut44e609b2018-05-29 15:40:08 -06002315 else if (strcmp(args[0], "parse-resolv-conf") == 0) {
2316 const char *whitespace = "\r\n\t ";
2317 char *resolv_line = NULL;
2318 int resolv_linenum = 0;
2319 FILE *f = NULL;
2320 char *address = NULL;
2321 struct sockaddr_storage *sk = NULL;
2322 struct protocol *proto;
2323 int duplicate_name = 0;
2324
2325 if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
2326 ha_alert("parsing [%s:%d] : out of memory.\n",
2327 file, linenum);
2328 err_code |= ERR_ALERT | ERR_FATAL;
2329 goto resolv_out;
2330 }
2331
2332 if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
2333 ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n",
2334 file, linenum);
2335 err_code |= ERR_ALERT | ERR_FATAL;
2336 goto resolv_out;
2337 }
2338
2339 sk = calloc(1, sizeof(*sk));
2340 if (sk == NULL) {
2341 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n",
2342 resolv_linenum);
2343 err_code |= ERR_ALERT | ERR_FATAL;
2344 goto resolv_out;
2345 }
2346
2347 while (fgets(resolv_line, LINESIZE, f) != NULL) {
2348 resolv_linenum++;
2349 if (strncmp(resolv_line, "nameserver", 10) != 0)
2350 continue;
2351
2352 address = strtok(resolv_line + 10, whitespace);
2353 if (address == resolv_line + 10)
2354 continue;
2355
2356 if (address == NULL) {
2357 ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
2358 resolv_linenum);
2359 err_code |= ERR_WARN;
2360 continue;
2361 }
2362
2363 duplicate_name = 0;
2364 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
2365 if (strcmp(newnameserver->id, address) == 0) {
2366 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",
2367 resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line);
2368 err_code |= ERR_WARN;
2369 duplicate_name = 1;
2370 }
2371 }
2372
2373 if (duplicate_name)
2374 continue;
2375
2376 memset(sk, 0, sizeof(*sk));
2377 sk = str2ip2(address, sk, 1);
2378 if (!sk) {
2379 ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, namerserver will be excluded.\n",
2380 resolv_linenum, address);
2381 err_code |= ERR_WARN;
2382 continue;
2383 }
2384
2385 set_host_port(sk, 53);
2386
2387 proto = protocol_by_family(sk->ss_family);
2388 if (!proto || !proto->connect) {
2389 ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
2390 resolv_linenum, address);
2391 err_code |= ERR_WARN;
2392 continue;
2393 }
2394
2395 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
2396 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2397 err_code |= ERR_ALERT | ERR_FATAL;
2398 goto resolv_out;
2399 }
2400
2401 newnameserver->conf.file = strdup("/etc/resolv.conf");
2402 if (newnameserver->conf.file == NULL) {
2403 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2404 err_code |= ERR_ALERT | ERR_FATAL;
2405 goto resolv_out;
2406 }
2407
2408 newnameserver->id = strdup(address);
2409 if (newnameserver->id == NULL) {
2410 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2411 err_code |= ERR_ALERT | ERR_FATAL;
2412 goto resolv_out;
2413 }
2414
2415 newnameserver->resolvers = curr_resolvers;
2416 newnameserver->conf.line = resolv_linenum;
2417 newnameserver->addr = *sk;
2418
2419 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
2420 }
2421
2422resolv_out:
2423 free(sk);
2424 free(resolv_line);
2425 if (f != NULL)
2426 fclose(f);
2427 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002428 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2429 const char *res;
2430 unsigned int time;
2431
2432 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002433 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2434 file, linenum, args[0]);
2435 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002436 err_code |= ERR_ALERT | ERR_FATAL;
2437 goto out;
2438 }
2439 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2440 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002441 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2442 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002443 err_code |= ERR_ALERT | ERR_FATAL;
2444 goto out;
2445 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002446 if (strcmp(args[1], "nx") == 0)
2447 curr_resolvers->hold.nx = time;
2448 else if (strcmp(args[1], "other") == 0)
2449 curr_resolvers->hold.other = time;
2450 else if (strcmp(args[1], "refused") == 0)
2451 curr_resolvers->hold.refused = time;
2452 else if (strcmp(args[1], "timeout") == 0)
2453 curr_resolvers->hold.timeout = time;
2454 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002455 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002456 else if (strcmp(args[1], "obsolete") == 0)
2457 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002458 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002459 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2460 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002461 err_code |= ERR_ALERT | ERR_FATAL;
2462 goto out;
2463 }
2464
2465 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002466 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002467 int i = 0;
2468
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002469 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002470 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2471 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002472 err_code |= ERR_ALERT | ERR_FATAL;
2473 goto out;
2474 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002475
2476 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002477 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002478 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2479 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002480 err_code |= ERR_ALERT | ERR_FATAL;
2481 goto out;
2482 }
2483
2484 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002485 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002486 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002487 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2488 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002489 err_code |= ERR_WARN;
2490 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002491 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002492 else if (strcmp(args[0], "resolve_retries") == 0) {
2493 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002494 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2495 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002496 err_code |= ERR_ALERT | ERR_FATAL;
2497 goto out;
2498 }
2499 curr_resolvers->resolve_retries = atoi(args[1]);
2500 }
2501 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002502 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002503 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2504 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002505 err_code |= ERR_ALERT | ERR_FATAL;
2506 goto out;
2507 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002508 else if (strcmp(args[1], "retry") == 0 ||
2509 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002510 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002511 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002512
2513 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002514 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2515 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002516 err_code |= ERR_ALERT | ERR_FATAL;
2517 goto out;
2518 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002519 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002520 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002521 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2522 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002523 err_code |= ERR_ALERT | ERR_FATAL;
2524 goto out;
2525 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002526 if (args[1][2] == 't')
2527 curr_resolvers->timeout.retry = tout;
2528 else
2529 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002530 }
2531 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002532 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2533 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002534 err_code |= ERR_ALERT | ERR_FATAL;
2535 goto out;
2536 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002537 } /* neither "nameserver" nor "resolvers" */
2538 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002539 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002540 err_code |= ERR_ALERT | ERR_FATAL;
2541 goto out;
2542 }
2543
2544 out:
2545 free(errmsg);
2546 return err_code;
2547}
Simon Horman0d16a402015-01-30 11:22:58 +09002548
2549/*
William Lallemand51097192015-04-14 16:35:22 +02002550 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002551 * Returns the error code, 0 if OK, or any combination of :
2552 * - ERR_ABORT: must abort ASAP
2553 * - ERR_FATAL: we can continue parsing but not start the service
2554 * - ERR_WARN: a warning has been emitted
2555 * - ERR_ALERT: an alert has been emitted
2556 * Only the two first ones can stop processing, the two others are just
2557 * indicators.
2558 */
2559int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2560{
2561 static struct mailers *curmailers = NULL;
2562 struct mailer *newmailer = NULL;
2563 const char *err;
2564 int err_code = 0;
2565 char *errmsg = NULL;
2566
2567 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2568 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002569 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002570 err_code |= ERR_ALERT | ERR_ABORT;
2571 goto out;
2572 }
2573
2574 err = invalid_char(args[1]);
2575 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002576 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2577 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002578 err_code |= ERR_ALERT | ERR_ABORT;
2579 goto out;
2580 }
2581
2582 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2583 /*
2584 * If there are two proxies with the same name only following
2585 * combinations are allowed:
2586 */
2587 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002588 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2589 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002590 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002591 }
2592 }
2593
Vincent Bernat02779b62016-04-03 13:48:43 +02002594 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002595 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002596 err_code |= ERR_ALERT | ERR_ABORT;
2597 goto out;
2598 }
2599
2600 curmailers->next = mailers;
2601 mailers = curmailers;
2602 curmailers->conf.file = strdup(file);
2603 curmailers->conf.line = linenum;
2604 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002605 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2606 * But need enough time so that timeouts don't occur
2607 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002608 }
2609 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2610 struct sockaddr_storage *sk;
2611 int port1, port2;
2612 struct protocol *proto;
2613
2614 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002615 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2616 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002617 err_code |= ERR_ALERT | ERR_FATAL;
2618 goto out;
2619 }
2620
2621 err = invalid_char(args[1]);
2622 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002623 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2624 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002625 err_code |= ERR_ALERT | ERR_FATAL;
2626 goto out;
2627 }
2628
Vincent Bernat02779b62016-04-03 13:48:43 +02002629 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002630 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002631 err_code |= ERR_ALERT | ERR_ABORT;
2632 goto out;
2633 }
2634
2635 /* the mailers are linked backwards first */
2636 curmailers->count++;
2637 newmailer->next = curmailers->mailer_list;
2638 curmailers->mailer_list = newmailer;
2639 newmailer->mailers = curmailers;
2640 newmailer->conf.file = strdup(file);
2641 newmailer->conf.line = linenum;
2642
2643 newmailer->id = strdup(args[1]);
2644
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002645 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002646 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002647 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002648 err_code |= ERR_ALERT | ERR_FATAL;
2649 goto out;
2650 }
2651
2652 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002653 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002654 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2655 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002656 err_code |= ERR_ALERT | ERR_FATAL;
2657 goto out;
2658 }
2659
2660 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002661 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2662 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002663 err_code |= ERR_ALERT | ERR_FATAL;
2664 goto out;
2665 }
2666
2667 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002668 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2669 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002670 err_code |= ERR_ALERT | ERR_FATAL;
2671 goto out;
2672 }
2673
2674 newmailer->addr = *sk;
2675 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002676 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002677 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002678 }
2679 else if (strcmp(args[0], "timeout") == 0) {
2680 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002681 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2682 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002683 err_code |= ERR_ALERT | ERR_FATAL;
2684 goto out;
2685 }
2686 else if (strcmp(args[1], "mail") == 0) {
2687 const char *res;
2688 unsigned int timeout_mail;
2689 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002690 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2691 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002692 err_code |= ERR_ALERT | ERR_FATAL;
2693 goto out;
2694 }
2695 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2696 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002697 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2698 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002699 err_code |= ERR_ALERT | ERR_FATAL;
2700 goto out;
2701 }
2702 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002703 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 +01002704 err_code |= ERR_ALERT | ERR_FATAL;
2705 goto out;
2706 }
2707 curmailers->timeout.mail = timeout_mail;
2708 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002709 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002710 file, linenum, args[0], args[1]);
2711 err_code |= ERR_ALERT | ERR_FATAL;
2712 goto out;
2713 }
2714 }
Simon Horman0d16a402015-01-30 11:22:58 +09002715 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002716 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002717 err_code |= ERR_ALERT | ERR_FATAL;
2718 goto out;
2719 }
2720
2721out:
2722 free(errmsg);
2723 return err_code;
2724}
2725
Simon Horman9dc49962015-01-30 11:22:59 +09002726static void free_email_alert(struct proxy *p)
2727{
2728 free(p->email_alert.mailers.name);
2729 p->email_alert.mailers.name = NULL;
2730 free(p->email_alert.from);
2731 p->email_alert.from = NULL;
2732 free(p->email_alert.to);
2733 p->email_alert.to = NULL;
2734 free(p->email_alert.myhostname);
2735 p->email_alert.myhostname = NULL;
2736}
2737
Willy Tarreau3842f002009-06-14 11:39:52 +02002738int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002739{
2740 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002741 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002742 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002743 int rc;
2744 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002745 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002746 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002747 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002748 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002749 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002750
Willy Tarreau977b8e42006-12-29 14:19:17 +01002751 if (!strcmp(args[0], "listen"))
2752 rc = PR_CAP_LISTEN;
2753 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002754 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002755 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002756 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002757 else
2758 rc = PR_CAP_NONE;
2759
2760 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002761 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002762 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2763 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2764 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002765 err_code |= ERR_ALERT | ERR_ABORT;
2766 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002767 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002768
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002769 err = invalid_char(args[1]);
2770 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002771 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2772 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002773 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002774 }
2775
Willy Tarreau8f50b682015-05-26 11:45:02 +02002776 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2777 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002778 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2779 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2780 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002781 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002782 }
2783
Vincent Bernat02779b62016-04-03 13:48:43 +02002784 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002785 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002786 err_code |= ERR_ALERT | ERR_ABORT;
2787 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002788 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002789
Willy Tarreau97cb7802010-01-03 20:23:58 +01002790 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002791 curproxy->next = proxies_list;
2792 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002793 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2794 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002795 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002796 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002797 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002798 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002799
William Lallemand6e62fb62015-04-28 16:55:23 +02002800 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2801 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002802 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002803 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002804 }
2805
2806 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002807 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002808 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002809
Willy Tarreaubaaee002006-06-26 02:48:02 +02002810 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002811 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002812 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002813 curproxy->no_options = defproxy.no_options;
2814 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002815 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002816 curproxy->except_net = defproxy.except_net;
2817 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002818 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002819 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002820
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002821 if (defproxy.fwdfor_hdr_len) {
2822 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2823 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2824 }
2825
Willy Tarreaub86db342009-11-30 11:50:16 +01002826 if (defproxy.orgto_hdr_len) {
2827 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2828 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2829 }
2830
Mark Lamourinec2247f02012-01-04 13:02:01 -05002831 if (defproxy.server_id_hdr_len) {
2832 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2833 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2834 }
2835
Willy Tarreau977b8e42006-12-29 14:19:17 +01002836 if (curproxy->cap & PR_CAP_FE) {
2837 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002838 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002839 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002840
2841 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002842 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2843 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002844
2845 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2846 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002847
Willy Tarreau977b8e42006-12-29 14:19:17 +01002848 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002849 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002850 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002851 curproxy->fullconn = defproxy.fullconn;
2852 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002853 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002854 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002855
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002856 if (defproxy.check_req) {
2857 curproxy->check_req = calloc(1, defproxy.check_len);
2858 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2859 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002860 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002861
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002862 if (defproxy.expect_str) {
2863 curproxy->expect_str = strdup(defproxy.expect_str);
2864 if (defproxy.expect_regex) {
2865 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002866 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2867 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002868 }
2869 }
2870
Willy Tarreau67402132012-05-31 20:40:20 +02002871 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002872 if (defproxy.cookie_name)
2873 curproxy->cookie_name = strdup(defproxy.cookie_name);
2874 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002875
2876 if (defproxy.dyncookie_key)
2877 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002878 if (defproxy.cookie_domain)
2879 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002880
Willy Tarreau31936852010-10-06 16:59:56 +02002881 if (defproxy.cookie_maxidle)
2882 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2883
2884 if (defproxy.cookie_maxlife)
2885 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2886
Emeric Brun647caf12009-06-30 17:57:00 +02002887 if (defproxy.rdp_cookie_name)
2888 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2889 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2890
Willy Tarreau01732802007-11-01 22:48:15 +01002891 if (defproxy.url_param_name)
2892 curproxy->url_param_name = strdup(defproxy.url_param_name);
2893 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002894
Benoitaffb4812009-03-25 13:02:10 +01002895 if (defproxy.hh_name)
2896 curproxy->hh_name = strdup(defproxy.hh_name);
2897 curproxy->hh_len = defproxy.hh_len;
2898 curproxy->hh_match_domain = defproxy.hh_match_domain;
2899
Willy Tarreauef9a3602012-12-08 22:29:20 +01002900 if (defproxy.conn_src.iface_name)
2901 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2902 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002903 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002904#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002905 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002906#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002907 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002908 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002909
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002910 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002911 if (defproxy.capture_name)
2912 curproxy->capture_name = strdup(defproxy.capture_name);
2913 curproxy->capture_namelen = defproxy.capture_namelen;
2914 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002915 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002916
Willy Tarreau977b8e42006-12-29 14:19:17 +01002917 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002918 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002919 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002920 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002921 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002922 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002923 curproxy->mon_net = defproxy.mon_net;
2924 curproxy->mon_mask = defproxy.mon_mask;
2925 if (defproxy.monitor_uri)
2926 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2927 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002928 if (defproxy.defbe.name)
2929 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002930
2931 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002932 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2933 if (curproxy->conf.logformat_string &&
2934 curproxy->conf.logformat_string != default_http_log_format &&
2935 curproxy->conf.logformat_string != default_tcp_log_format &&
2936 curproxy->conf.logformat_string != clf_http_log_format)
2937 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2938
2939 if (defproxy.conf.lfs_file) {
2940 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2941 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2942 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002943
2944 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2945 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2946 if (curproxy->conf.logformat_sd_string &&
2947 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2948 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2949
2950 if (defproxy.conf.lfsd_file) {
2951 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2952 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2953 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002954 }
2955
2956 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002957 curproxy->timeout.connect = defproxy.timeout.connect;
2958 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002959 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002960 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002961 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002962 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002963 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002964 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002965 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002966 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002967 }
2968
Willy Tarreaubaaee002006-06-26 02:48:02 +02002969 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002970 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002971
2972 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002973 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002974 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002975 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002976 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002977 LIST_INIT(&node->list);
2978 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2979 }
2980
Willy Tarreau62a61232013-04-12 18:13:46 +02002981 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2982 if (curproxy->conf.uniqueid_format_string)
2983 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2984
Dragan Dosen43885c72015-10-01 13:18:13 +02002985 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002986
Willy Tarreau62a61232013-04-12 18:13:46 +02002987 if (defproxy.conf.uif_file) {
2988 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2989 curproxy->conf.uif_line = defproxy.conf.uif_line;
2990 }
William Lallemanda73203e2012-03-12 12:48:57 +01002991
2992 /* copy default header unique id */
2993 if (defproxy.header_unique_id)
2994 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2995
William Lallemand82fe75c2012-10-23 10:25:10 +02002996 /* default compression options */
2997 if (defproxy.comp != NULL) {
2998 curproxy->comp = calloc(1, sizeof(struct comp));
2999 curproxy->comp->algos = defproxy.comp->algos;
3000 curproxy->comp->types = defproxy.comp->types;
3001 }
3002
Willy Tarreaubaaee002006-06-26 02:48:02 +02003003 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003004 curproxy->conf.used_listener_id = EB_ROOT;
3005 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003006
Simon Horman98637e52014-06-20 12:30:16 +09003007 if (defproxy.check_path)
3008 curproxy->check_path = strdup(defproxy.check_path);
3009 if (defproxy.check_command)
3010 curproxy->check_command = strdup(defproxy.check_command);
3011
Simon Horman9dc49962015-01-30 11:22:59 +09003012 if (defproxy.email_alert.mailers.name)
3013 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
3014 if (defproxy.email_alert.from)
3015 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
3016 if (defproxy.email_alert.to)
3017 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
3018 if (defproxy.email_alert.myhostname)
3019 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003020 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003021 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003022
Willy Tarreau93893792009-07-23 13:19:11 +02003023 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003024 }
3025 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3026 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003027 /* FIXME-20070101: we should do this too at the end of the
3028 * config parsing to free all default values.
3029 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003030 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3031 err_code |= ERR_ABORT;
3032 goto out;
3033 }
3034
Willy Tarreaua534fea2008-08-03 12:19:50 +02003035 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003036 free(defproxy.check_command);
3037 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003038 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003039 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003040 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003041 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003042 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003043 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003044 free(defproxy.capture_name);
3045 free(defproxy.monitor_uri);
3046 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003047 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003048 free(defproxy.fwdfor_hdr_name);
3049 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003050 free(defproxy.orgto_hdr_name);
3051 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003052 free(defproxy.server_id_hdr_name);
3053 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003054 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003055 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003056 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003057 free(defproxy.expect_regex);
3058 defproxy.expect_regex = NULL;
3059 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003060
Willy Tarreau62a61232013-04-12 18:13:46 +02003061 if (defproxy.conf.logformat_string != default_http_log_format &&
3062 defproxy.conf.logformat_string != default_tcp_log_format &&
3063 defproxy.conf.logformat_string != clf_http_log_format)
3064 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003065
Willy Tarreau62a61232013-04-12 18:13:46 +02003066 free(defproxy.conf.uniqueid_format_string);
3067 free(defproxy.conf.lfs_file);
3068 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003069 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003070 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003071
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003072 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3073 free(defproxy.conf.logformat_sd_string);
3074 free(defproxy.conf.lfsd_file);
3075
Willy Tarreaua534fea2008-08-03 12:19:50 +02003076 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003077 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003078
Willy Tarreaubaaee002006-06-26 02:48:02 +02003079 /* we cannot free uri_auth because it might already be used */
3080 init_default_instance();
3081 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003082 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3083 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003084 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003085 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003086 }
3087 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003088 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003089 err_code |= ERR_ALERT | ERR_FATAL;
3090 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003091 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003092
3093 /* update the current file and line being parsed */
3094 curproxy->conf.args.file = curproxy->conf.file;
3095 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003096
3097 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003098 if (!strcmp(args[0], "server") ||
3099 !strcmp(args[0], "default-server") ||
3100 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003101 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3102 if (err_code & ERR_FATAL)
3103 goto out;
3104 }
3105 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003106 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003107 int cur_arg;
3108
Willy Tarreaubaaee002006-06-26 02:48:02 +02003109 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003110 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003111 err_code |= ERR_ALERT | ERR_FATAL;
3112 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003113 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003114 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003115 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003116
Willy Tarreau24709282013-03-10 21:32:12 +01003117 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003118 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3119 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003120 err_code |= ERR_ALERT | ERR_FATAL;
3121 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003122 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003123
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003124 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003125
3126 /* use default settings for unix sockets */
3127 bind_conf->ux.uid = global.unix_bind.ux.uid;
3128 bind_conf->ux.gid = global.unix_bind.ux.gid;
3129 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003130
3131 /* NOTE: the following line might create several listeners if there
3132 * are comma-separated IPs or port ranges. So all further processing
3133 * will have to be applied to all listeners created after last_listen.
3134 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003135 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3136 if (errmsg && *errmsg) {
3137 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003138 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003139 }
3140 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003141 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3142 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003143 err_code |= ERR_ALERT | ERR_FATAL;
3144 goto out;
3145 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003146
Willy Tarreau4348fad2012-09-20 16:48:07 +02003147 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3148 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003149 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003150 }
3151
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003152 cur_arg = 2;
3153 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003154 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003155 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003156 char *err;
3157
Willy Tarreau26982662012-09-12 23:17:10 +02003158 kw = bind_find_kw(args[cur_arg]);
3159 if (kw) {
3160 char *err = NULL;
3161 int code;
3162
3163 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003164 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3165 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003166 cur_arg += 1 + kw->skip ;
3167 err_code |= ERR_ALERT | ERR_FATAL;
3168 goto out;
3169 }
3170
Willy Tarreau4348fad2012-09-20 16:48:07 +02003171 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003172 err_code |= code;
3173
3174 if (code) {
3175 if (err && *err) {
3176 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003177 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003178 }
3179 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003180 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3181 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003182 if (code & ERR_FATAL) {
3183 free(err);
3184 cur_arg += 1 + kw->skip;
3185 goto out;
3186 }
3187 }
3188 free(err);
3189 cur_arg += 1 + kw->skip;
3190 continue;
3191 }
3192
Willy Tarreau8638f482012-09-18 18:01:17 +02003193 err = NULL;
3194 if (!bind_dumped) {
3195 bind_dump_kws(&err);
3196 indent_msg(&err, 4);
3197 bind_dumped = 1;
3198 }
3199
Christopher Faulet767a84b2017-11-24 16:50:31 +01003200 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3201 file, linenum, args[0], args[1], args[cur_arg],
3202 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003203 free(err);
3204
Willy Tarreau93893792009-07-23 13:19:11 +02003205 err_code |= ERR_ALERT | ERR_FATAL;
3206 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003207 }
Willy Tarreau93893792009-07-23 13:19:11 +02003208 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003209 }
3210 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003211 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003212 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3213 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003214 err_code |= ERR_ALERT | ERR_FATAL;
3215 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003216 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003217 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003218 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003219
Willy Tarreaubaaee002006-06-26 02:48:02 +02003220 /* flush useless bits */
3221 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003222 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003223 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003224 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003225 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003226 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003227
William Lallemanddf1425a2015-04-28 20:17:49 +02003228 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3229 goto out;
3230
Willy Tarreau1c47f852006-07-09 08:22:27 +02003231 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003232 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3233 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003234 err_code |= ERR_ALERT | ERR_FATAL;
3235 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003236 }
3237
Willy Tarreaua534fea2008-08-03 12:19:50 +02003238 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003239 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003240 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003241 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003242 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3243
Willy Tarreau93893792009-07-23 13:19:11 +02003244 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003245 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003246 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003247 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3248 goto out;
3249
Willy Tarreaubaaee002006-06-26 02:48:02 +02003250 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3251 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3252 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3253 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003254 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003255 err_code |= ERR_ALERT | ERR_FATAL;
3256 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003257 }
3258 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003259 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003260 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003261
3262 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003263 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003264 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003265 err_code |= ERR_ALERT | ERR_FATAL;
3266 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003267 }
3268
William Lallemanddf1425a2015-04-28 20:17:49 +02003269 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3270 goto out;
3271
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003272 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003273 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3274 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003275 err_code |= ERR_ALERT | ERR_FATAL;
3276 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003277 }
3278
3279 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003280 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003281 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003282
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003283 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003284 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3285 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003286 err_code |= ERR_ALERT | ERR_FATAL;
3287 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003288 }
3289
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003290 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3291 if (node) {
3292 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003293 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3294 file, linenum, proxy_type_str(curproxy), curproxy->id,
3295 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003296 err_code |= ERR_ALERT | ERR_FATAL;
3297 goto out;
3298 }
3299 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003300 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003301 else if (!strcmp(args[0], "description")) {
3302 int i, len=0;
3303 char *d;
3304
Cyril Bonté99ed3272010-01-24 23:29:44 +01003305 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003306 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003307 file, linenum, args[0]);
3308 err_code |= ERR_ALERT | ERR_FATAL;
3309 goto out;
3310 }
3311
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003312 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003313 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3314 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003315 return -1;
3316 }
3317
Willy Tarreau348acfe2014-04-14 15:00:39 +02003318 for (i = 1; *args[i]; i++)
3319 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003320
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003321 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003322 curproxy->desc = d;
3323
Willy Tarreau348acfe2014-04-14 15:00:39 +02003324 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3325 for (i = 2; *args[i]; i++)
3326 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003327
3328 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003329 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003330 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3331 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003332 curproxy->state = PR_STSTOPPED;
3333 }
3334 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003335 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3336 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003337 curproxy->state = PR_STNEW;
3338 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003339 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3340 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003341 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003342
3343 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003344 if (strcmp(args[cur_arg], "all") == 0) {
3345 set = 0;
3346 break;
3347 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003348 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003349 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003350 err_code |= ERR_ALERT | ERR_FATAL;
3351 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003352 }
3353 cur_arg++;
3354 }
3355 curproxy->bind_proc = set;
3356 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003357 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003358 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003359 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003360 err_code |= ERR_ALERT | ERR_FATAL;
3361 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003362 }
3363
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003364 err = invalid_char(args[1]);
3365 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003366 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3367 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003368 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003369 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003370 }
3371
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003372 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003373 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3374 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003375 err_code |= ERR_ALERT | ERR_FATAL;
3376 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003377 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003378 }
3379 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3380
3381 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3382 err_code |= ERR_WARN;
3383
3384 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003385 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3386 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003387 err_code |= ERR_ALERT | ERR_FATAL;
3388 goto out;
3389 }
3390 free(curproxy->dyncookie_key);
3391 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003392 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003393 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3394 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003395
Willy Tarreau977b8e42006-12-29 14:19:17 +01003396 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003397 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003398
Willy Tarreaubaaee002006-06-26 02:48:02 +02003399 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003400 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3401 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003402 err_code |= ERR_ALERT | ERR_FATAL;
3403 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003404 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003405
Willy Tarreau67402132012-05-31 20:40:20 +02003406 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003407 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003408 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003409 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003410 curproxy->cookie_name = strdup(args[1]);
3411 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003412
Willy Tarreaubaaee002006-06-26 02:48:02 +02003413 cur_arg = 2;
3414 while (*(args[cur_arg])) {
3415 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003416 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003417 }
3418 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003419 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003420 }
3421 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003422 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003423 }
3424 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003425 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003426 }
3427 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003428 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003429 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003430 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003431 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003432 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003433 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003434 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003435 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003436 else if (!strcmp(args[cur_arg], "httponly")) {
3437 curproxy->ck_opts |= PR_CK_HTTPONLY;
3438 }
3439 else if (!strcmp(args[cur_arg], "secure")) {
3440 curproxy->ck_opts |= PR_CK_SECURE;
3441 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003442 else if (!strcmp(args[cur_arg], "domain")) {
3443 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003444 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3445 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003446 err_code |= ERR_ALERT | ERR_FATAL;
3447 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003448 }
3449
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003450 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003451 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003452 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3453 " dots nor does not start with a dot."
3454 " RFC forbids it, this configuration may not work properly.\n",
3455 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003456 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003457 }
3458
3459 err = invalid_domainchar(args[cur_arg + 1]);
3460 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003461 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3462 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003463 err_code |= ERR_ALERT | ERR_FATAL;
3464 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003465 }
3466
Willy Tarreau68a897b2009-12-03 23:28:34 +01003467 if (!curproxy->cookie_domain) {
3468 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3469 } else {
3470 /* one domain was already specified, add another one by
3471 * building the string which will be returned along with
3472 * the cookie.
3473 */
3474 char *new_ptr;
3475 int new_len = strlen(curproxy->cookie_domain) +
3476 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3477 new_ptr = malloc(new_len);
3478 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3479 free(curproxy->cookie_domain);
3480 curproxy->cookie_domain = new_ptr;
3481 }
Willy Tarreau31936852010-10-06 16:59:56 +02003482 cur_arg++;
3483 }
3484 else if (!strcmp(args[cur_arg], "maxidle")) {
3485 unsigned int maxidle;
3486 const char *res;
3487
3488 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003489 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3490 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003491 err_code |= ERR_ALERT | ERR_FATAL;
3492 goto out;
3493 }
3494
3495 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3496 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003497 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3498 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003499 err_code |= ERR_ALERT | ERR_FATAL;
3500 goto out;
3501 }
3502 curproxy->cookie_maxidle = maxidle;
3503 cur_arg++;
3504 }
3505 else if (!strcmp(args[cur_arg], "maxlife")) {
3506 unsigned int maxlife;
3507 const char *res;
3508
3509 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003510 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3511 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003512 err_code |= ERR_ALERT | ERR_FATAL;
3513 goto out;
3514 }
3515
3516 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3517 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003518 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3519 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003520 err_code |= ERR_ALERT | ERR_FATAL;
3521 goto out;
3522 }
3523 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003524 cur_arg++;
3525 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003526 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003527
3528 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3529 err_code |= ERR_WARN;
3530 curproxy->ck_opts |= PR_CK_DYNAMIC;
3531 }
3532
Willy Tarreaubaaee002006-06-26 02:48:02 +02003533 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003534 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3535 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003536 err_code |= ERR_ALERT | ERR_FATAL;
3537 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003538 }
3539 cur_arg++;
3540 }
Willy Tarreau67402132012-05-31 20:40:20 +02003541 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003542 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3543 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003544 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003545 }
3546
Willy Tarreau67402132012-05-31 20:40:20 +02003547 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003548 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3549 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003550 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003551 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003552
Willy Tarreau67402132012-05-31 20:40:20 +02003553 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003554 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3555 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003556 err_code |= ERR_ALERT | ERR_FATAL;
3557 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003558 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003559 else if (!strcmp(args[0], "email-alert")) {
3560 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003561 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3562 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003563 err_code |= ERR_ALERT | ERR_FATAL;
3564 goto out;
3565 }
3566
3567 if (!strcmp(args[1], "from")) {
3568 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003569 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3570 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003571 err_code |= ERR_ALERT | ERR_FATAL;
3572 goto out;
3573 }
3574 free(curproxy->email_alert.from);
3575 curproxy->email_alert.from = strdup(args[2]);
3576 }
3577 else if (!strcmp(args[1], "mailers")) {
3578 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003579 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3580 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003581 err_code |= ERR_ALERT | ERR_FATAL;
3582 goto out;
3583 }
3584 free(curproxy->email_alert.mailers.name);
3585 curproxy->email_alert.mailers.name = strdup(args[2]);
3586 }
3587 else if (!strcmp(args[1], "myhostname")) {
3588 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003589 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3590 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003591 err_code |= ERR_ALERT | ERR_FATAL;
3592 goto out;
3593 }
3594 free(curproxy->email_alert.myhostname);
3595 curproxy->email_alert.myhostname = strdup(args[2]);
3596 }
Simon Horman64e34162015-02-06 11:11:57 +09003597 else if (!strcmp(args[1], "level")) {
3598 curproxy->email_alert.level = get_log_level(args[2]);
3599 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003600 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3601 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003602 err_code |= ERR_ALERT | ERR_FATAL;
3603 goto out;
3604 }
3605 }
Simon Horman9dc49962015-01-30 11:22:59 +09003606 else if (!strcmp(args[1], "to")) {
3607 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003608 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3609 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003610 err_code |= ERR_ALERT | ERR_FATAL;
3611 goto out;
3612 }
3613 free(curproxy->email_alert.to);
3614 curproxy->email_alert.to = strdup(args[2]);
3615 }
3616 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003617 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3618 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003619 err_code |= ERR_ALERT | ERR_FATAL;
3620 goto out;
3621 }
Simon Horman64e34162015-02-06 11:11:57 +09003622 /* Indicate that the email_alert is at least partially configured */
3623 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003624 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003625 else if (!strcmp(args[0], "external-check")) {
3626 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003627 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3628 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003629 err_code |= ERR_ALERT | ERR_FATAL;
3630 goto out;
3631 }
3632
3633 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003634 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003635 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003636 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003637 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3638 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003639 err_code |= ERR_ALERT | ERR_FATAL;
3640 goto out;
3641 }
3642 free(curproxy->check_command);
3643 curproxy->check_command = strdup(args[2]);
3644 }
3645 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003646 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003647 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003648 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003649 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3650 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003651 err_code |= ERR_ALERT | ERR_FATAL;
3652 goto out;
3653 }
3654 free(curproxy->check_path);
3655 curproxy->check_path = strdup(args[2]);
3656 }
3657 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003658 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3659 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003660 err_code |= ERR_ALERT | ERR_FATAL;
3661 goto out;
3662 }
3663 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003664 else if (!strcmp(args[0], "persist")) { /* persist */
3665 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003666 ha_alert("parsing [%s:%d] : missing persist method.\n",
3667 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003668 err_code |= ERR_ALERT | ERR_FATAL;
3669 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003670 }
3671
3672 if (!strncmp(args[1], "rdp-cookie", 10)) {
3673 curproxy->options2 |= PR_O2_RDPC_PRST;
3674
Emeric Brunb982a3d2010-01-04 15:45:53 +01003675 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003676 const char *beg, *end;
3677
3678 beg = args[1] + 11;
3679 end = strchr(beg, ')');
3680
William Lallemanddf1425a2015-04-28 20:17:49 +02003681 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3682 goto out;
3683
Emeric Brun647caf12009-06-30 17:57:00 +02003684 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003685 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3686 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003687 err_code |= ERR_ALERT | ERR_FATAL;
3688 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003689 }
3690
3691 free(curproxy->rdp_cookie_name);
3692 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3693 curproxy->rdp_cookie_len = end-beg;
3694 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003695 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003696 free(curproxy->rdp_cookie_name);
3697 curproxy->rdp_cookie_name = strdup("msts");
3698 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3699 }
3700 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003701 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3702 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003703 err_code |= ERR_ALERT | ERR_FATAL;
3704 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003705 }
3706 }
3707 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003708 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3709 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003710 err_code |= ERR_ALERT | ERR_FATAL;
3711 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003712 }
3713 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003714 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003715 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 +02003716 err_code |= ERR_ALERT | ERR_FATAL;
3717 goto out;
3718 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003719 else if (!strcmp(args[0], "load-server-state-from-file")) {
3720 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3721 err_code |= ERR_WARN;
3722 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3723 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3724 }
3725 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3726 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3727 }
3728 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3729 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3730 }
3731 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003732 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3733 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003734 err_code |= ERR_ALERT | ERR_FATAL;
3735 goto out;
3736 }
3737 }
3738 else if (!strcmp(args[0], "server-state-file-name")) {
3739 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3740 err_code |= ERR_WARN;
3741 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003742 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3743 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003744 err_code |= ERR_ALERT | ERR_FATAL;
3745 goto out;
3746 }
3747 else if (!strcmp(args[1], "use-backend-name"))
3748 curproxy->server_state_file_name = strdup(curproxy->id);
3749 else
3750 curproxy->server_state_file_name = strdup(args[1]);
3751 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003752 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003753 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003754 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003755
Willy Tarreaubaaee002006-06-26 02:48:02 +02003756 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003757 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003758 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 +01003759 err_code |= ERR_ALERT | ERR_FATAL;
3760 goto out;
3761 }
3762
William Lallemand1a748ae2015-05-19 16:37:23 +02003763 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3764 goto out;
3765
Willy Tarreaubaaee002006-06-26 02:48:02 +02003766 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003767 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3768 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003769 err_code |= ERR_ALERT | ERR_FATAL;
3770 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003771 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003772 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003773 curproxy->capture_name = strdup(args[2]);
3774 curproxy->capture_namelen = strlen(curproxy->capture_name);
3775 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003776 curproxy->to_log |= LW_COOKIE;
3777 }
3778 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3779 struct cap_hdr *hdr;
3780
3781 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003782 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 +02003783 err_code |= ERR_ALERT | ERR_FATAL;
3784 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003785 }
3786
William Lallemand1a748ae2015-05-19 16:37:23 +02003787 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3788 goto out;
3789
Willy Tarreaubaaee002006-06-26 02:48:02 +02003790 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003791 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3792 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003793 err_code |= ERR_ALERT | ERR_FATAL;
3794 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003795 }
3796
Vincent Bernat02779b62016-04-03 13:48:43 +02003797 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003798 hdr->next = curproxy->req_cap;
3799 hdr->name = strdup(args[3]);
3800 hdr->namelen = strlen(args[3]);
3801 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003802 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003803 hdr->index = curproxy->nb_req_cap++;
3804 curproxy->req_cap = hdr;
3805 curproxy->to_log |= LW_REQHDR;
3806 }
3807 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3808 struct cap_hdr *hdr;
3809
3810 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003811 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 +02003812 err_code |= ERR_ALERT | ERR_FATAL;
3813 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003814 }
3815
William Lallemand1a748ae2015-05-19 16:37:23 +02003816 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3817 goto out;
3818
Willy Tarreaubaaee002006-06-26 02:48:02 +02003819 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003820 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3821 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003822 err_code |= ERR_ALERT | ERR_FATAL;
3823 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003824 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003825 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003826 hdr->next = curproxy->rsp_cap;
3827 hdr->name = strdup(args[3]);
3828 hdr->namelen = strlen(args[3]);
3829 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003830 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003831 hdr->index = curproxy->nb_rsp_cap++;
3832 curproxy->rsp_cap = hdr;
3833 curproxy->to_log |= LW_RSPHDR;
3834 }
3835 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003836 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3837 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003838 err_code |= ERR_ALERT | ERR_FATAL;
3839 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003840 }
3841 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003842 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003843 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003844 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003845
William Lallemanddf1425a2015-04-28 20:17:49 +02003846 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3847 goto out;
3848
Willy Tarreaubaaee002006-06-26 02:48:02 +02003849 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003850 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3851 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003852 err_code |= ERR_ALERT | ERR_FATAL;
3853 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003854 }
3855 curproxy->conn_retries = atol(args[1]);
3856 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003857 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003858 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003859
3860 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003861 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003862 err_code |= ERR_ALERT | ERR_FATAL;
3863 goto out;
3864 }
3865
Willy Tarreau20b0de52012-12-24 15:45:22 +01003866 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003867 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003868 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3869 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3870 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3871 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003872 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3873 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003874 err_code |= ERR_WARN;
3875 }
3876
Willy Tarreauff011f22011-01-06 17:51:27 +01003877 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003878
Willy Tarreauff011f22011-01-06 17:51:27 +01003879 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003880 err_code |= ERR_ALERT | ERR_ABORT;
3881 goto out;
3882 }
3883
Willy Tarreau5002f572014-04-23 01:32:02 +02003884 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003885 err_code |= warnif_cond_conflicts(rule->cond,
3886 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3887 file, linenum);
3888
Willy Tarreauff011f22011-01-06 17:51:27 +01003889 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003890 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003891 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003892 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003893
3894 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003895 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003896 err_code |= ERR_ALERT | ERR_FATAL;
3897 goto out;
3898 }
3899
3900 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003901 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003902 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3903 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003904 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3905 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003906 err_code |= ERR_WARN;
3907 }
3908
3909 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3910
3911 if (!rule) {
3912 err_code |= ERR_ALERT | ERR_ABORT;
3913 goto out;
3914 }
3915
3916 err_code |= warnif_cond_conflicts(rule->cond,
3917 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3918 file, linenum);
3919
3920 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3921 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003922 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3923 /* set the header name and length into the proxy structure */
3924 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3925 err_code |= ERR_WARN;
3926
3927 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003928 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3929 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003930 err_code |= ERR_ALERT | ERR_FATAL;
3931 goto out;
3932 }
3933
3934 /* set the desired header name */
3935 free(curproxy->server_id_hdr_name);
3936 curproxy->server_id_hdr_name = strdup(args[1]);
3937 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3938 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003939 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003940 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003941
Willy Tarreaub099aca2008-10-12 17:26:37 +02003942 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003943 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003944 err_code |= ERR_ALERT | ERR_FATAL;
3945 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003946 }
3947
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003948 /* emulate "block" using "http-request block". Since these rules are supposed to
3949 * be processed before all http-request rules, we put them into their own list
3950 * and will insert them at the end.
3951 */
3952 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3953 if (!rule) {
3954 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003955 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003956 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003957 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3958 err_code |= warnif_cond_conflicts(rule->cond,
3959 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3960 file, linenum);
3961 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003962
3963 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003964 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 +02003965
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003966 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003967 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003968 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003969
Cyril Bonté99ed3272010-01-24 23:29:44 +01003970 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003971 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003972 err_code |= ERR_ALERT | ERR_FATAL;
3973 goto out;
3974 }
3975
Willy Tarreaube4653b2015-05-28 15:26:58 +02003976 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003977 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3978 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003979 err_code |= ERR_ALERT | ERR_FATAL;
3980 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003981 }
3982
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003983 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003984 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003985 err_code |= warnif_cond_conflicts(rule->cond,
3986 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3987 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003988 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003989 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003990 struct switching_rule *rule;
3991
Willy Tarreaub099aca2008-10-12 17:26:37 +02003992 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003993 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003994 err_code |= ERR_ALERT | ERR_FATAL;
3995 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003996 }
3997
Willy Tarreau55ea7572007-06-17 19:56:27 +02003998 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003999 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02004000
4001 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004002 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004003 err_code |= ERR_ALERT | ERR_FATAL;
4004 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02004005 }
4006
Willy Tarreauf51658d2014-04-23 01:21:56 +02004007 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004008 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004009 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4010 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02004011 err_code |= ERR_ALERT | ERR_FATAL;
4012 goto out;
4013 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004014
Willy Tarreauf51658d2014-04-23 01:21:56 +02004015 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004016 }
Willy Tarreau4f862642017-02-28 09:34:39 +01004017 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004018 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
4019 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004020 err_code |= ERR_ALERT | ERR_FATAL;
4021 goto out;
4022 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004023
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004024 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004025 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004026 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004027 goto out;
4028 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004029 rule->cond = cond;
4030 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004031 rule->line = linenum;
4032 rule->file = strdup(file);
4033 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004034 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004035 goto out;
4036 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004037 LIST_INIT(&rule->list);
4038 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4039 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004040 else if (strcmp(args[0], "use-server") == 0) {
4041 struct server_rule *rule;
4042
4043 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004044 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004045 err_code |= ERR_ALERT | ERR_FATAL;
4046 goto out;
4047 }
4048
4049 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4050 err_code |= ERR_WARN;
4051
4052 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004053 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004054 err_code |= ERR_ALERT | ERR_FATAL;
4055 goto out;
4056 }
4057
4058 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004059 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4060 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004061 err_code |= ERR_ALERT | ERR_FATAL;
4062 goto out;
4063 }
4064
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004065 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004066 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4067 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004068 err_code |= ERR_ALERT | ERR_FATAL;
4069 goto out;
4070 }
4071
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004072 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004073
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004074 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004075 rule->cond = cond;
4076 rule->srv.name = strdup(args[1]);
4077 LIST_INIT(&rule->list);
4078 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4079 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4080 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004081 else if ((!strcmp(args[0], "force-persist")) ||
4082 (!strcmp(args[0], "ignore-persist"))) {
4083 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004084
4085 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004086 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004087 err_code |= ERR_ALERT | ERR_FATAL;
4088 goto out;
4089 }
4090
Cyril Bonté4288c5a2018-03-12 22:02:59 +01004091 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01004092 err_code |= ERR_WARN;
4093
Willy Tarreauef6494c2010-01-28 17:12:36 +01004094 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004095 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4096 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004097 err_code |= ERR_ALERT | ERR_FATAL;
4098 goto out;
4099 }
4100
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004101 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004102 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4103 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004104 err_code |= ERR_ALERT | ERR_FATAL;
4105 goto out;
4106 }
4107
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004108 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4109 * where force-persist is applied.
4110 */
4111 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004112
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004113 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004114 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004115 if (!strcmp(args[0], "force-persist")) {
4116 rule->type = PERSIST_TYPE_FORCE;
4117 } else {
4118 rule->type = PERSIST_TYPE_IGNORE;
4119 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004120 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004121 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004122 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004123 else if (!strcmp(args[0], "stick-table")) {
4124 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004125 struct proxy *other;
4126
Willy Tarreauc7867682018-07-27 10:26:22 +02004127 if (curproxy == &defproxy) {
4128 ha_alert("parsing [%s:%d] : 'stick-table' is not supported in 'defaults' section.\n",
4129 file, linenum);
4130 err_code |= ERR_ALERT | ERR_FATAL;
4131 goto out;
4132 }
4133
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004134 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004135 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004136 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4137 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004138 err_code |= ERR_ALERT | ERR_FATAL;
4139 goto out;
4140 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004141
Emeric Brun32da3c42010-09-23 18:39:19 +02004142 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004143 curproxy->table.type = (unsigned int)-1;
4144 while (*args[myidx]) {
4145 const char *err;
4146
4147 if (strcmp(args[myidx], "size") == 0) {
4148 myidx++;
4149 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004150 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4151 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004152 err_code |= ERR_ALERT | ERR_FATAL;
4153 goto out;
4154 }
4155 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004156 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4157 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004158 err_code |= ERR_ALERT | ERR_FATAL;
4159 goto out;
4160 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004161 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004162 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004163 else if (strcmp(args[myidx], "peers") == 0) {
4164 myidx++;
Godbach50523162013-12-11 19:48:57 +08004165 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004166 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4167 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004168 err_code |= ERR_ALERT | ERR_FATAL;
4169 goto out;
Godbach50523162013-12-11 19:48:57 +08004170 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004171 curproxy->table.peers.name = strdup(args[myidx++]);
4172 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004173 else if (strcmp(args[myidx], "expire") == 0) {
4174 myidx++;
4175 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004176 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4177 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004178 err_code |= ERR_ALERT | ERR_FATAL;
4179 goto out;
4180 }
4181 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4182 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004183 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4184 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004185 err_code |= ERR_ALERT | ERR_FATAL;
4186 goto out;
4187 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004188 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004189 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4190 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004191 err_code |= ERR_ALERT | ERR_FATAL;
4192 goto out;
4193 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004194 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004195 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004196 }
4197 else if (strcmp(args[myidx], "nopurge") == 0) {
4198 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004199 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004200 }
4201 else if (strcmp(args[myidx], "type") == 0) {
4202 myidx++;
4203 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004204 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4205 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004206 err_code |= ERR_ALERT | ERR_FATAL;
4207 goto out;
4208 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004209 /* myidx already points to next arg */
4210 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004211 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004212 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004213 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004214
4215 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004216 nw = args[myidx];
4217 while (*nw) {
4218 /* the "store" keyword supports a comma-separated list */
4219 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004220 sa = NULL; /* store arg */
4221 while (*nw && *nw != ',') {
4222 if (*nw == '(') {
4223 *nw = 0;
4224 sa = ++nw;
4225 while (*nw != ')') {
4226 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004227 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4228 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004229 err_code |= ERR_ALERT | ERR_FATAL;
4230 goto out;
4231 }
4232 nw++;
4233 }
4234 *nw = '\0';
4235 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004236 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004237 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004238 if (*nw)
4239 *nw++ = '\0';
4240 type = stktable_get_data_type(cw);
4241 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004242 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4243 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004244 err_code |= ERR_ALERT | ERR_FATAL;
4245 goto out;
4246 }
Willy Tarreauac782882010-06-20 10:41:54 +02004247
4248 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4249 switch (err) {
4250 case PE_NONE: break;
4251 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004252 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4253 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004254 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004255 break;
4256
4257 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004258 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4259 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004260 err_code |= ERR_ALERT | ERR_FATAL;
4261 goto out;
4262
4263 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004264 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4265 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004266 err_code |= ERR_ALERT | ERR_FATAL;
4267 goto out;
4268
4269 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004270 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4271 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004272 err_code |= ERR_ALERT | ERR_FATAL;
4273 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004274 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004275 }
4276 myidx++;
4277 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004278 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004279 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4280 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004281 err_code |= ERR_ALERT | ERR_FATAL;
4282 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004283 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004284 }
4285
4286 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004287 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4288 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004289 err_code |= ERR_ALERT | ERR_FATAL;
4290 goto out;
4291 }
4292
4293 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004294 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4295 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004296 err_code |= ERR_ALERT | ERR_FATAL;
4297 goto out;
4298 }
4299 }
4300 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004301 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004302 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004303 int myidx = 0;
4304 const char *name = NULL;
4305 int flags;
4306
4307 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004308 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004309 err_code |= ERR_ALERT | ERR_FATAL;
4310 goto out;
4311 }
4312
4313 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4314 err_code |= ERR_WARN;
4315 goto out;
4316 }
4317
4318 myidx++;
4319 if ((strcmp(args[myidx], "store") == 0) ||
4320 (strcmp(args[myidx], "store-request") == 0)) {
4321 myidx++;
4322 flags = STK_IS_STORE;
4323 }
4324 else if (strcmp(args[myidx], "store-response") == 0) {
4325 myidx++;
4326 flags = STK_IS_STORE | STK_ON_RSP;
4327 }
4328 else if (strcmp(args[myidx], "match") == 0) {
4329 myidx++;
4330 flags = STK_IS_MATCH;
4331 }
4332 else if (strcmp(args[myidx], "on") == 0) {
4333 myidx++;
4334 flags = STK_IS_MATCH | STK_IS_STORE;
4335 }
4336 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004337 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004338 err_code |= ERR_ALERT | ERR_FATAL;
4339 goto out;
4340 }
4341
4342 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004343 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004344 err_code |= ERR_ALERT | ERR_FATAL;
4345 goto out;
4346 }
4347
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004348 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004349 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004350 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004351 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004352 err_code |= ERR_ALERT | ERR_FATAL;
4353 goto out;
4354 }
4355
4356 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004357 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004358 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4359 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004360 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004361 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004362 goto out;
4363 }
4364 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004365 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004366 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4367 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004368 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004369 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004370 goto out;
4371 }
4372 }
4373
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004374 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004375 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004376
Emeric Brunb982a3d2010-01-04 15:45:53 +01004377 if (strcmp(args[myidx], "table") == 0) {
4378 myidx++;
4379 name = args[myidx++];
4380 }
4381
Willy Tarreauef6494c2010-01-28 17:12:36 +01004382 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004383 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004384 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4385 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004386 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004387 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004388 goto out;
4389 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004390 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004391 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004392 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4393 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004394 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004395 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004396 goto out;
4397 }
Emeric Brun97679e72010-09-23 17:56:44 +02004398 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004399 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004400 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004401 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004402
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004403 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004404 rule->cond = cond;
4405 rule->expr = expr;
4406 rule->flags = flags;
4407 rule->table.name = name ? strdup(name) : NULL;
4408 LIST_INIT(&rule->list);
4409 if (flags & STK_ON_RSP)
4410 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4411 else
4412 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4413 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004414 else if (!strcmp(args[0], "stats")) {
4415 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4416 curproxy->uri_auth = NULL; /* we must detach from the default config */
4417
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004418 if (!*args[1]) {
4419 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004420 } else if (!strcmp(args[1], "admin")) {
4421 struct stats_admin_rule *rule;
4422
4423 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004424 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 +02004425 err_code |= ERR_ALERT | ERR_FATAL;
4426 goto out;
4427 }
4428
4429 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004430 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004431 err_code |= ERR_ALERT | ERR_ABORT;
4432 goto out;
4433 }
4434
4435 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004436 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4437 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004438 err_code |= ERR_ALERT | ERR_FATAL;
4439 goto out;
4440 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004441 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004442 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4443 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004444 err_code |= ERR_ALERT | ERR_FATAL;
4445 goto out;
4446 }
4447
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004448 err_code |= warnif_cond_conflicts(cond,
4449 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4450 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004451
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004452 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004453 rule->cond = cond;
4454 LIST_INIT(&rule->list);
4455 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004456 } else if (!strcmp(args[1], "uri")) {
4457 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004458 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004459 err_code |= ERR_ALERT | ERR_FATAL;
4460 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004461 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004462 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004463 err_code |= ERR_ALERT | ERR_ABORT;
4464 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004465 }
4466 } else if (!strcmp(args[1], "realm")) {
4467 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004468 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004469 err_code |= ERR_ALERT | ERR_FATAL;
4470 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004471 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004472 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004473 err_code |= ERR_ALERT | ERR_ABORT;
4474 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004475 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004476 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004477 unsigned interval;
4478
4479 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4480 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004481 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4482 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004483 err_code |= ERR_ALERT | ERR_FATAL;
4484 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004485 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004486 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004487 err_code |= ERR_ALERT | ERR_ABORT;
4488 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004489 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004490 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004491 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004492
4493 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004494 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004495 err_code |= ERR_ALERT | ERR_FATAL;
4496 goto out;
4497 }
4498
4499 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004500 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004501 err_code |= ERR_ALERT | ERR_ABORT;
4502 goto out;
4503 }
4504
Willy Tarreauff011f22011-01-06 17:51:27 +01004505 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004506 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004507 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4508 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004509 err_code |= ERR_WARN;
4510 }
4511
Willy Tarreauff011f22011-01-06 17:51:27 +01004512 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004513
Willy Tarreauff011f22011-01-06 17:51:27 +01004514 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004515 err_code |= ERR_ALERT | ERR_ABORT;
4516 goto out;
4517 }
4518
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004519 err_code |= warnif_cond_conflicts(rule->cond,
4520 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4521 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004522 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004523
Willy Tarreaubaaee002006-06-26 02:48:02 +02004524 } else if (!strcmp(args[1], "auth")) {
4525 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004526 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004527 err_code |= ERR_ALERT | ERR_FATAL;
4528 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004529 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004530 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004531 err_code |= ERR_ALERT | ERR_ABORT;
4532 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004533 }
4534 } else if (!strcmp(args[1], "scope")) {
4535 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004536 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004537 err_code |= ERR_ALERT | ERR_FATAL;
4538 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004539 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004540 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004541 err_code |= ERR_ALERT | ERR_ABORT;
4542 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004543 }
4544 } else if (!strcmp(args[1], "enable")) {
4545 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004546 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004547 err_code |= ERR_ALERT | ERR_ABORT;
4548 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004549 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004550 } else if (!strcmp(args[1], "hide-version")) {
4551 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004552 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004553 err_code |= ERR_ALERT | ERR_ABORT;
4554 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004555 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004556 } else if (!strcmp(args[1], "show-legends")) {
4557 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004558 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004559 err_code |= ERR_ALERT | ERR_ABORT;
4560 goto out;
4561 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004562 } else if (!strcmp(args[1], "show-node")) {
4563
4564 if (*args[2]) {
4565 int i;
4566 char c;
4567
4568 for (i=0; args[2][i]; i++) {
4569 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004570 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4571 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004572 break;
4573 }
4574
4575 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004576 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4577 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4578 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004579 err_code |= ERR_ALERT | ERR_FATAL;
4580 goto out;
4581 }
4582 }
4583
4584 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004585 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004586 err_code |= ERR_ALERT | ERR_ABORT;
4587 goto out;
4588 }
4589 } else if (!strcmp(args[1], "show-desc")) {
4590 char *desc = NULL;
4591
4592 if (*args[2]) {
4593 int i, len=0;
4594 char *d;
4595
Willy Tarreau348acfe2014-04-14 15:00:39 +02004596 for (i = 2; *args[i]; i++)
4597 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004598
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004599 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004600
Willy Tarreau348acfe2014-04-14 15:00:39 +02004601 d += snprintf(d, desc + len - d, "%s", args[2]);
4602 for (i = 3; *args[i]; i++)
4603 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004604 }
4605
4606 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004607 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4608 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004609 else {
4610 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4611 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004612 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004613 err_code |= ERR_ALERT | ERR_ABORT;
4614 goto out;
4615 }
4616 free(desc);
4617 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004618 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004619stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004620 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4621 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004622 err_code |= ERR_ALERT | ERR_FATAL;
4623 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004624 }
4625 }
4626 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004627 int optnum;
4628
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004629 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004630 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4631 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004632 err_code |= ERR_ALERT | ERR_FATAL;
4633 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004634 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004635
4636 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4637 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004638 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004639 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4640 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004641 err_code |= ERR_ALERT | ERR_FATAL;
4642 goto out;
4643 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004644 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4645 goto out;
4646
Willy Tarreau93893792009-07-23 13:19:11 +02004647 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4648 err_code |= ERR_WARN;
4649 goto out;
4650 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004651
Willy Tarreau3842f002009-06-14 11:39:52 +02004652 curproxy->no_options &= ~cfg_opts[optnum].val;
4653 curproxy->options &= ~cfg_opts[optnum].val;
4654
4655 switch (kwm) {
4656 case KWM_STD:
4657 curproxy->options |= cfg_opts[optnum].val;
4658 break;
4659 case KWM_NO:
4660 curproxy->no_options |= cfg_opts[optnum].val;
4661 break;
4662 case KWM_DEF: /* already cleared */
4663 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004664 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004665
Willy Tarreau93893792009-07-23 13:19:11 +02004666 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004667 }
4668 }
4669
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004670 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4671 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004672 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004673 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4674 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004675 err_code |= ERR_ALERT | ERR_FATAL;
4676 goto out;
4677 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004678 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4679 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004680 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4681 err_code |= ERR_WARN;
4682 goto out;
4683 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004684
Willy Tarreau3842f002009-06-14 11:39:52 +02004685 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4686 curproxy->options2 &= ~cfg_opts2[optnum].val;
4687
4688 switch (kwm) {
4689 case KWM_STD:
4690 curproxy->options2 |= cfg_opts2[optnum].val;
4691 break;
4692 case KWM_NO:
4693 curproxy->no_options2 |= cfg_opts2[optnum].val;
4694 break;
4695 case KWM_DEF: /* already cleared */
4696 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004697 }
Willy Tarreau93893792009-07-23 13:19:11 +02004698 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004699 }
4700 }
4701
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004702 /* HTTP options override each other. They can be cancelled using
4703 * "no option xxx" which only switches to default mode if the mode
4704 * was this one (useful for cancelling options set in defaults
4705 * sections).
4706 */
4707 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004708 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4709 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004710 if (kwm == KWM_STD) {
4711 curproxy->options &= ~PR_O_HTTP_MODE;
4712 curproxy->options |= PR_O_HTTP_PCL;
4713 goto out;
4714 }
4715 else if (kwm == KWM_NO) {
4716 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4717 curproxy->options &= ~PR_O_HTTP_MODE;
4718 goto out;
4719 }
4720 }
4721 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004722 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4723 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004724 if (kwm == KWM_STD) {
4725 curproxy->options &= ~PR_O_HTTP_MODE;
4726 curproxy->options |= PR_O_HTTP_FCL;
4727 goto out;
4728 }
4729 else if (kwm == KWM_NO) {
4730 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4731 curproxy->options &= ~PR_O_HTTP_MODE;
4732 goto out;
4733 }
4734 }
4735 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004736 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4737 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004738 if (kwm == KWM_STD) {
4739 curproxy->options &= ~PR_O_HTTP_MODE;
4740 curproxy->options |= PR_O_HTTP_SCL;
4741 goto out;
4742 }
4743 else if (kwm == KWM_NO) {
4744 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4745 curproxy->options &= ~PR_O_HTTP_MODE;
4746 goto out;
4747 }
4748 }
4749 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004750 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4751 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004752 if (kwm == KWM_STD) {
4753 curproxy->options &= ~PR_O_HTTP_MODE;
4754 curproxy->options |= PR_O_HTTP_KAL;
4755 goto out;
4756 }
4757 else if (kwm == KWM_NO) {
4758 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4759 curproxy->options &= ~PR_O_HTTP_MODE;
4760 goto out;
4761 }
4762 }
4763 else if (strcmp(args[1], "http-tunnel") == 0) {
Christopher Faulet4212a302018-09-21 10:42:19 +02004764 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[1], NULL)) {
4765 err_code |= ERR_WARN;
4766 goto out;
4767 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004768 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4769 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004770 if (kwm == KWM_STD) {
4771 curproxy->options &= ~PR_O_HTTP_MODE;
4772 curproxy->options |= PR_O_HTTP_TUN;
4773 goto out;
4774 }
4775 else if (kwm == KWM_NO) {
4776 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4777 curproxy->options &= ~PR_O_HTTP_MODE;
4778 goto out;
4779 }
4780 }
4781
Joseph Lynch726ab712015-05-11 23:25:34 -07004782 /* Redispatch can take an integer argument that control when the
4783 * resispatch occurs. All values are relative to the retries option.
4784 * This can be cancelled using "no option xxx".
4785 */
4786 if (strcmp(args[1], "redispatch") == 0) {
4787 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4788 err_code |= ERR_WARN;
4789 goto out;
4790 }
4791
4792 curproxy->no_options &= ~PR_O_REDISP;
4793 curproxy->options &= ~PR_O_REDISP;
4794
4795 switch (kwm) {
4796 case KWM_STD:
4797 curproxy->options |= PR_O_REDISP;
4798 curproxy->redispatch_after = -1;
4799 if(*args[2]) {
4800 curproxy->redispatch_after = atol(args[2]);
4801 }
4802 break;
4803 case KWM_NO:
4804 curproxy->no_options |= PR_O_REDISP;
4805 curproxy->redispatch_after = 0;
4806 break;
4807 case KWM_DEF: /* already cleared */
4808 break;
4809 }
4810 goto out;
4811 }
4812
Willy Tarreau3842f002009-06-14 11:39:52 +02004813 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004814 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4815 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004816 err_code |= ERR_ALERT | ERR_FATAL;
4817 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004818 }
4819
Emeric Brun3a058f32009-06-30 18:26:00 +02004820 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004821 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004822 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004823 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004824 if (*(args[2]) != '\0') {
4825 if (!strcmp(args[2], "clf")) {
4826 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004827 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004828 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004829 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004830 err_code |= ERR_ALERT | ERR_FATAL;
4831 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004832 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004833 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4834 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004835 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004836 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4837 char *oldlogformat = "log-format";
4838 char *clflogformat = "";
4839
4840 if (curproxy->conf.logformat_string == default_http_log_format)
4841 oldlogformat = "option httplog";
4842 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4843 oldlogformat = "option tcplog";
4844 else if (curproxy->conf.logformat_string == clf_http_log_format)
4845 oldlogformat = "option httplog clf";
4846 if (logformat == clf_http_log_format)
4847 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004848 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4849 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004850 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004851 if (curproxy->conf.logformat_string != default_http_log_format &&
4852 curproxy->conf.logformat_string != default_tcp_log_format &&
4853 curproxy->conf.logformat_string != clf_http_log_format)
4854 free(curproxy->conf.logformat_string);
4855 curproxy->conf.logformat_string = logformat;
4856
4857 free(curproxy->conf.lfs_file);
4858 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4859 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004860
4861 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4862 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4863 file, linenum, curproxy->id);
4864 err_code |= ERR_WARN;
4865 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004866 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004867 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004868 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4869 char *oldlogformat = "log-format";
4870
4871 if (curproxy->conf.logformat_string == default_http_log_format)
4872 oldlogformat = "option httplog";
4873 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4874 oldlogformat = "option tcplog";
4875 else if (curproxy->conf.logformat_string == clf_http_log_format)
4876 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004877 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4878 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004879 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004880 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004881 if (curproxy->conf.logformat_string != default_http_log_format &&
4882 curproxy->conf.logformat_string != default_tcp_log_format &&
4883 curproxy->conf.logformat_string != clf_http_log_format)
4884 free(curproxy->conf.logformat_string);
4885 curproxy->conf.logformat_string = default_tcp_log_format;
4886
4887 free(curproxy->conf.lfs_file);
4888 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4889 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004890
4891 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4892 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004893
4894 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4895 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4896 file, linenum, curproxy->id);
4897 err_code |= ERR_WARN;
4898 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004899 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004900 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004901 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004902 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004903 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004904
William Lallemanddf1425a2015-04-28 20:17:49 +02004905 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4906 goto out;
4907
Willy Tarreau13943ab2006-12-31 00:24:10 +01004908 if (curproxy->cap & PR_CAP_FE)
4909 curproxy->options |= PR_O_TCP_CLI_KA;
4910 if (curproxy->cap & PR_CAP_BE)
4911 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004912 }
4913 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004914 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004915 err_code |= ERR_WARN;
4916
Willy Tarreaubaaee002006-06-26 02:48:02 +02004917 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004918 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004919 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004920 curproxy->options2 &= ~PR_O2_CHK_ANY;
4921 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004922 if (!*args[2]) { /* no argument */
4923 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4924 curproxy->check_len = strlen(DEF_CHECK_REQ);
4925 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004926 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004927 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004928 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004929 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004930 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004931 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004932 if (*args[4])
4933 reqlen += strlen(args[4]);
4934 else
4935 reqlen += strlen("HTTP/1.0");
4936
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004937 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004938 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004939 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004940 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004941 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4942 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004943 }
4944 else if (!strcmp(args[1], "ssl-hello-chk")) {
4945 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004946 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004947 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004948
Willy Tarreaua534fea2008-08-03 12:19:50 +02004949 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004950 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004951 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004952 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004953
4954 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4955 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004956 }
Willy Tarreau23677902007-05-08 23:50:35 +02004957 else if (!strcmp(args[1], "smtpchk")) {
4958 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004959 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004960 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004961 curproxy->options2 &= ~PR_O2_CHK_ANY;
4962 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004963
4964 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4965 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4966 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4967 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4968 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4969 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004970 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004971 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4972 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4973 } else {
4974 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4975 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4976 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4977 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4978 }
4979 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004980 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4981 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004982 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004983 else if (!strcmp(args[1], "pgsql-check")) {
4984 /* use PostgreSQL request to check servers' health */
4985 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4986 err_code |= ERR_WARN;
4987
4988 free(curproxy->check_req);
4989 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004990 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004991 curproxy->options2 |= PR_O2_PGSQL_CHK;
4992
4993 if (*(args[2])) {
4994 int cur_arg = 2;
4995
4996 while (*(args[cur_arg])) {
4997 if (strcmp(args[cur_arg], "user") == 0) {
4998 char * packet;
4999 uint32_t packet_len;
5000 uint32_t pv;
5001
5002 /* suboption header - needs additional argument for it */
5003 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005004 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5005 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005006 err_code |= ERR_ALERT | ERR_FATAL;
5007 goto out;
5008 }
5009
5010 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
5011 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
5012 pv = htonl(0x30000); /* protocol version 3.0 */
5013
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005014 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005015
5016 memcpy(packet + 4, &pv, 4);
5017
5018 /* copy "user" */
5019 memcpy(packet + 8, "user", 4);
5020
5021 /* copy username */
5022 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
5023
5024 free(curproxy->check_req);
5025 curproxy->check_req = packet;
5026 curproxy->check_len = packet_len;
5027
5028 packet_len = htonl(packet_len);
5029 memcpy(packet, &packet_len, 4);
5030 cur_arg += 2;
5031 } else {
5032 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005033 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5034 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005035 err_code |= ERR_ALERT | ERR_FATAL;
5036 goto out;
5037 }
5038 } /* end while loop */
5039 }
William Lallemanddf1425a2015-04-28 20:17:49 +02005040 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
5041 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005042 }
5043
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005044 else if (!strcmp(args[1], "redis-check")) {
5045 /* use REDIS PING request to check servers' health */
5046 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5047 err_code |= ERR_WARN;
5048
5049 free(curproxy->check_req);
5050 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005051 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005052 curproxy->options2 |= PR_O2_REDIS_CHK;
5053
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005054 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005055 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5056 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005057
5058 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5059 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005060 }
5061
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005062 else if (!strcmp(args[1], "mysql-check")) {
5063 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005064 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5065 err_code |= ERR_WARN;
5066
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005067 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005068 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005069 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005070 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005071
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005072 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005073 * const char mysql40_client_auth_pkt[] = {
5074 * "\x0e\x00\x00" // packet length
5075 * "\x01" // packet number
5076 * "\x00\x00" // client capabilities
5077 * "\x00\x00\x01" // max packet
5078 * "haproxy\x00" // username (null terminated string)
5079 * "\x00" // filler (always 0x00)
5080 * "\x01\x00\x00" // packet length
5081 * "\x00" // packet number
5082 * "\x01" // COM_QUIT command
5083 * };
5084 */
5085
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005086 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5087 * const char mysql41_client_auth_pkt[] = {
5088 * "\x0e\x00\x00\" // packet length
5089 * "\x01" // packet number
5090 * "\x00\x00\x00\x00" // client capabilities
5091 * "\x00\x00\x00\x01" // max packet
5092 * "\x21" // character set (UTF-8)
5093 * char[23] // All zeroes
5094 * "haproxy\x00" // username (null terminated string)
5095 * "\x00" // filler (always 0x00)
5096 * "\x01\x00\x00" // packet length
5097 * "\x00" // packet number
5098 * "\x01" // COM_QUIT command
5099 * };
5100 */
5101
5102
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005103 if (*(args[2])) {
5104 int cur_arg = 2;
5105
5106 while (*(args[cur_arg])) {
5107 if (strcmp(args[cur_arg], "user") == 0) {
5108 char *mysqluser;
5109 int packetlen, reqlen, userlen;
5110
5111 /* suboption header - needs additional argument for it */
5112 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005113 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5114 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005115 err_code |= ERR_ALERT | ERR_FATAL;
5116 goto out;
5117 }
5118 mysqluser = args[cur_arg + 1];
5119 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005120
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005121 if (*(args[cur_arg+2])) {
5122 if (!strcmp(args[cur_arg+2], "post-41")) {
5123 packetlen = userlen + 7 + 27;
5124 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005125
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005126 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005127 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005128 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005129
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005130 snprintf(curproxy->check_req, 4, "%c%c%c",
5131 ((unsigned char) packetlen & 0xff),
5132 ((unsigned char) (packetlen >> 8) & 0xff),
5133 ((unsigned char) (packetlen >> 16) & 0xff));
5134
5135 curproxy->check_req[3] = 1;
5136 curproxy->check_req[5] = 130;
5137 curproxy->check_req[11] = 1;
5138 curproxy->check_req[12] = 33;
5139 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5140 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5141 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5142 cur_arg += 3;
5143 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005144 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 +02005145 err_code |= ERR_ALERT | ERR_FATAL;
5146 goto out;
5147 }
5148 } else {
5149 packetlen = userlen + 7;
5150 reqlen = packetlen + 9;
5151
5152 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005153 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005154 curproxy->check_len = reqlen;
5155
5156 snprintf(curproxy->check_req, 4, "%c%c%c",
5157 ((unsigned char) packetlen & 0xff),
5158 ((unsigned char) (packetlen >> 8) & 0xff),
5159 ((unsigned char) (packetlen >> 16) & 0xff));
5160
5161 curproxy->check_req[3] = 1;
5162 curproxy->check_req[5] = 128;
5163 curproxy->check_req[8] = 1;
5164 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5165 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5166 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5167 cur_arg += 2;
5168 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005169 } else {
5170 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005171 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5172 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005173 err_code |= ERR_ALERT | ERR_FATAL;
5174 goto out;
5175 }
5176 } /* end while loop */
5177 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005178 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005179 else if (!strcmp(args[1], "ldap-check")) {
5180 /* use LDAP request to check servers' health */
5181 free(curproxy->check_req);
5182 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005183 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005184 curproxy->options2 |= PR_O2_LDAP_CHK;
5185
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005186 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005187 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5188 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005189 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5190 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005191 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005192 else if (!strcmp(args[1], "spop-check")) {
5193 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005194 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5195 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005196 err_code |= ERR_ALERT | ERR_FATAL;
5197 goto out;
5198 }
5199 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005200 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5201 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005202 err_code |= ERR_ALERT | ERR_FATAL;
5203 goto out;
5204 }
5205
5206 /* use SPOE request to check servers' health */
5207 free(curproxy->check_req);
5208 curproxy->check_req = NULL;
5209 curproxy->options2 &= ~PR_O2_CHK_ANY;
5210 curproxy->options2 |= PR_O2_SPOP_CHK;
5211
Christopher Faulet8ef75252017-02-20 22:56:03 +01005212 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005213 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005214 err_code |= ERR_ALERT | ERR_FATAL;
5215 goto out;
5216 }
5217 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5218 goto out;
5219 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005220 else if (!strcmp(args[1], "tcp-check")) {
5221 /* use raw TCPCHK send/expect to check servers' health */
5222 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5223 err_code |= ERR_WARN;
5224
5225 free(curproxy->check_req);
5226 curproxy->check_req = NULL;
5227 curproxy->options2 &= ~PR_O2_CHK_ANY;
5228 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005229 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5230 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005231 }
Simon Horman98637e52014-06-20 12:30:16 +09005232 else if (!strcmp(args[1], "external-check")) {
5233 /* excute an external command to check servers' health */
5234 free(curproxy->check_req);
5235 curproxy->check_req = NULL;
5236 curproxy->options2 &= ~PR_O2_CHK_ANY;
5237 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005238 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5239 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005240 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005241 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005242 int cur_arg;
5243
5244 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5245 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005246 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005247
Willy Tarreau87cf5142011-08-19 22:57:24 +02005248 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005249
5250 free(curproxy->fwdfor_hdr_name);
5251 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5252 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5253
5254 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5255 cur_arg = 2;
5256 while (*(args[cur_arg])) {
5257 if (!strcmp(args[cur_arg], "except")) {
5258 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005259 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005260 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5261 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005262 err_code |= ERR_ALERT | ERR_FATAL;
5263 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005264 }
5265 /* flush useless bits */
5266 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005267 cur_arg += 2;
5268 } else if (!strcmp(args[cur_arg], "header")) {
5269 /* suboption header - needs additional argument for it */
5270 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005271 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5272 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005273 err_code |= ERR_ALERT | ERR_FATAL;
5274 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005275 }
5276 free(curproxy->fwdfor_hdr_name);
5277 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5278 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5279 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005280 } else if (!strcmp(args[cur_arg], "if-none")) {
5281 curproxy->options &= ~PR_O_FF_ALWAYS;
5282 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005283 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005284 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005285 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5286 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005287 err_code |= ERR_ALERT | ERR_FATAL;
5288 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005289 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005290 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005291 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005292 else if (!strcmp(args[1], "originalto")) {
5293 int cur_arg;
5294
5295 /* insert x-original-to field, but not for the IP address listed as an except.
5296 * set default options (ie: bitfield, header name, etc)
5297 */
5298
5299 curproxy->options |= PR_O_ORGTO;
5300
5301 free(curproxy->orgto_hdr_name);
5302 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5303 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5304
Willy Tarreau87cf5142011-08-19 22:57:24 +02005305 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005306 cur_arg = 2;
5307 while (*(args[cur_arg])) {
5308 if (!strcmp(args[cur_arg], "except")) {
5309 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005310 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 +01005311 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5312 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005313 err_code |= ERR_ALERT | ERR_FATAL;
5314 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005315 }
5316 /* flush useless bits */
5317 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5318 cur_arg += 2;
5319 } else if (!strcmp(args[cur_arg], "header")) {
5320 /* suboption header - needs additional argument for it */
5321 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005322 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5323 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005324 err_code |= ERR_ALERT | ERR_FATAL;
5325 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005326 }
5327 free(curproxy->orgto_hdr_name);
5328 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5329 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5330 cur_arg += 2;
5331 } else {
5332 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005333 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5334 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005335 err_code |= ERR_ALERT | ERR_FATAL;
5336 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005337 }
5338 } /* end while loop */
5339 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005340 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005341 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005342 err_code |= ERR_ALERT | ERR_FATAL;
5343 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005344 }
Willy Tarreau93893792009-07-23 13:19:11 +02005345 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005346 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005347 else if (!strcmp(args[0], "default_backend")) {
5348 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005349 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005350
5351 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005352 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005353 err_code |= ERR_ALERT | ERR_FATAL;
5354 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005355 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005356 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005357 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005358
5359 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5360 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005361 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005362 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005363 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005364 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005365
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005366 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005367 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5368 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005369 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005370 /* enable reconnections to dispatch */
5371 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005372
5373 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5374 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005375 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005376 else if (!strcmp(args[0], "http-reuse")) {
5377 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5378 err_code |= ERR_WARN;
5379
5380 if (strcmp(args[1], "never") == 0) {
5381 /* enable a graceful server shutdown on an HTTP 404 response */
5382 curproxy->options &= ~PR_O_REUSE_MASK;
5383 curproxy->options |= PR_O_REUSE_NEVR;
5384 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5385 goto out;
5386 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005387 else if (strcmp(args[1], "safe") == 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_SAFE;
5391 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5392 goto out;
5393 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005394 else if (strcmp(args[1], "aggressive") == 0) {
5395 curproxy->options &= ~PR_O_REUSE_MASK;
5396 curproxy->options |= PR_O_REUSE_AGGR;
5397 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5398 goto out;
5399 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005400 else if (strcmp(args[1], "always") == 0) {
5401 /* enable a graceful server shutdown on an HTTP 404 response */
5402 curproxy->options &= ~PR_O_REUSE_MASK;
5403 curproxy->options |= PR_O_REUSE_ALWS;
5404 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5405 goto out;
5406 }
5407 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005408 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005409 err_code |= ERR_ALERT | ERR_FATAL;
5410 goto out;
5411 }
5412 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005413 else if (!strcmp(args[0], "http-check")) {
5414 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005415 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005416
5417 if (strcmp(args[1], "disable-on-404") == 0) {
5418 /* enable a graceful server shutdown on an HTTP 404 response */
5419 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005420 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5421 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005422 }
Willy Tarreauef781042010-01-27 11:53:01 +01005423 else if (strcmp(args[1], "send-state") == 0) {
5424 /* enable emission of the apparent state of a server in HTTP checks */
5425 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005426 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5427 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005428 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005429 else if (strcmp(args[1], "expect") == 0) {
5430 const char *ptr_arg;
5431 int cur_arg;
5432
5433 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005434 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005435 err_code |= ERR_ALERT | ERR_FATAL;
5436 goto out;
5437 }
5438
5439 cur_arg = 2;
5440 /* consider exclamation marks, sole or at the beginning of a word */
5441 while (*(ptr_arg = args[cur_arg])) {
5442 while (*ptr_arg == '!') {
5443 curproxy->options2 ^= PR_O2_EXP_INV;
5444 ptr_arg++;
5445 }
5446 if (*ptr_arg)
5447 break;
5448 cur_arg++;
5449 }
5450 /* now ptr_arg points to the beginning of a word past any possible
5451 * exclamation mark, and cur_arg is the argument which holds this word.
5452 */
5453 if (strcmp(ptr_arg, "status") == 0) {
5454 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005455 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5456 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005457 err_code |= ERR_ALERT | ERR_FATAL;
5458 goto out;
5459 }
5460 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005461 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005462 curproxy->expect_str = strdup(args[cur_arg + 1]);
5463 }
5464 else if (strcmp(ptr_arg, "string") == 0) {
5465 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005466 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5467 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005468 err_code |= ERR_ALERT | ERR_FATAL;
5469 goto out;
5470 }
5471 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005472 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005473 curproxy->expect_str = strdup(args[cur_arg + 1]);
5474 }
5475 else if (strcmp(ptr_arg, "rstatus") == 0) {
5476 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005477 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5478 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005479 err_code |= ERR_ALERT | ERR_FATAL;
5480 goto out;
5481 }
5482 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005483 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005484 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005485 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005486 free(curproxy->expect_regex);
5487 curproxy->expect_regex = NULL;
5488 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005489 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005490 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5491 error = NULL;
5492 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005493 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5494 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005495 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005496 err_code |= ERR_ALERT | ERR_FATAL;
5497 goto out;
5498 }
5499 }
5500 else if (strcmp(ptr_arg, "rstring") == 0) {
5501 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005502 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5503 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005504 err_code |= ERR_ALERT | ERR_FATAL;
5505 goto out;
5506 }
5507 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005508 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005509 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005510 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005511 free(curproxy->expect_regex);
5512 curproxy->expect_regex = NULL;
5513 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005514 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005515 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5516 error = NULL;
5517 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005518 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5519 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005520 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005521 err_code |= ERR_ALERT | ERR_FATAL;
5522 goto out;
5523 }
5524 }
5525 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005526 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5527 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005528 err_code |= ERR_ALERT | ERR_FATAL;
5529 goto out;
5530 }
5531 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005532 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005533 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 +02005534 err_code |= ERR_ALERT | ERR_FATAL;
5535 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005536 }
5537 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005538 else if (!strcmp(args[0], "tcp-check")) {
5539 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5540 err_code |= ERR_WARN;
5541
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005542 if (strcmp(args[1], "comment") == 0) {
5543 int cur_arg;
5544 struct tcpcheck_rule *tcpcheck;
5545
5546 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005547 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005548 tcpcheck->action = TCPCHK_ACT_COMMENT;
5549
5550 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005551 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5552 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005553 err_code |= ERR_ALERT | ERR_FATAL;
5554 goto out;
5555 }
5556
5557 tcpcheck->comment = strdup(args[cur_arg + 1]);
5558
5559 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005560 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5561 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005562 }
5563 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005564 const char *ptr_arg;
5565 int cur_arg;
5566 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005567
5568 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005569 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5570 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5571 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5572 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5573 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005574
Willy Tarreau5581c272015-05-13 12:24:53 +02005575 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5576 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005577 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5578 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005579 err_code |= ERR_ALERT | ERR_FATAL;
5580 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005581 }
5582
5583 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005584 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005585 tcpcheck->action = TCPCHK_ACT_CONNECT;
5586
5587 /* parsing each parameters to fill up the rule */
5588 while (*(ptr_arg = args[cur_arg])) {
5589 /* tcp port */
5590 if (strcmp(args[cur_arg], "port") == 0) {
5591 if ( (atol(args[cur_arg + 1]) > 65535) ||
5592 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005593 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5594 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005595 err_code |= ERR_ALERT | ERR_FATAL;
5596 goto out;
5597 }
5598 tcpcheck->port = atol(args[cur_arg + 1]);
5599 cur_arg += 2;
5600 }
5601 /* send proxy protocol */
5602 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5603 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5604 cur_arg++;
5605 }
5606#ifdef USE_OPENSSL
5607 else if (strcmp(args[cur_arg], "ssl") == 0) {
5608 curproxy->options |= PR_O_TCPCHK_SSL;
5609 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5610 cur_arg++;
5611 }
5612#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005613 /* comment for this tcpcheck line */
5614 else if (strcmp(args[cur_arg], "comment") == 0) {
5615 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005616 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5617 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005618 err_code |= ERR_ALERT | ERR_FATAL;
5619 goto out;
5620 }
5621 tcpcheck->comment = strdup(args[cur_arg + 1]);
5622 cur_arg += 2;
5623 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005624 else {
5625#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005626 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 +01005627#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005628 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 +01005629#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005630 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005631 err_code |= ERR_ALERT | ERR_FATAL;
5632 goto out;
5633 }
5634
5635 }
5636
5637 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5638 }
5639 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005640 if (! *(args[2]) ) {
5641 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005642 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5643 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005644 err_code |= ERR_ALERT | ERR_FATAL;
5645 goto out;
5646 } else {
5647 struct tcpcheck_rule *tcpcheck;
5648
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005649 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005650
5651 tcpcheck->action = TCPCHK_ACT_SEND;
5652 tcpcheck->string_len = strlen(args[2]);
5653 tcpcheck->string = strdup(args[2]);
5654 tcpcheck->expect_regex = NULL;
5655
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005656 /* comment for this tcpcheck line */
5657 if (strcmp(args[3], "comment") == 0) {
5658 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005659 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5660 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005661 err_code |= ERR_ALERT | ERR_FATAL;
5662 goto out;
5663 }
5664 tcpcheck->comment = strdup(args[4]);
5665 }
5666
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005667 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5668 }
5669 }
5670 else if (strcmp(args[1], "send-binary") == 0) {
5671 if (! *(args[2]) ) {
5672 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005673 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5674 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005675 err_code |= ERR_ALERT | ERR_FATAL;
5676 goto out;
5677 } else {
5678 struct tcpcheck_rule *tcpcheck;
5679 char *err = NULL;
5680
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005681 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005682
5683 tcpcheck->action = TCPCHK_ACT_SEND;
5684 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005685 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5686 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005687 err_code |= ERR_ALERT | ERR_FATAL;
5688 goto out;
5689 }
5690 tcpcheck->expect_regex = NULL;
5691
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005692 /* comment for this tcpcheck line */
5693 if (strcmp(args[3], "comment") == 0) {
5694 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005695 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5696 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005697 err_code |= ERR_ALERT | ERR_FATAL;
5698 goto out;
5699 }
5700 tcpcheck->comment = strdup(args[4]);
5701 }
5702
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005703 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5704 }
5705 }
5706 else if (strcmp(args[1], "expect") == 0) {
5707 const char *ptr_arg;
5708 int cur_arg;
5709 int inverse = 0;
5710
5711 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005712 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005713 err_code |= ERR_ALERT | ERR_FATAL;
5714 goto out;
5715 }
5716
5717 cur_arg = 2;
5718 /* consider exclamation marks, sole or at the beginning of a word */
5719 while (*(ptr_arg = args[cur_arg])) {
5720 while (*ptr_arg == '!') {
5721 inverse = !inverse;
5722 ptr_arg++;
5723 }
5724 if (*ptr_arg)
5725 break;
5726 cur_arg++;
5727 }
5728 /* now ptr_arg points to the beginning of a word past any possible
5729 * exclamation mark, and cur_arg is the argument which holds this word.
5730 */
5731 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005732 struct tcpcheck_rule *tcpcheck;
5733 char *err = NULL;
5734
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005735 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005736 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5737 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005738 err_code |= ERR_ALERT | ERR_FATAL;
5739 goto out;
5740 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005741
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005742 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005743
5744 tcpcheck->action = TCPCHK_ACT_EXPECT;
5745 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005746 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5747 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005748 err_code |= ERR_ALERT | ERR_FATAL;
5749 goto out;
5750 }
5751 tcpcheck->expect_regex = NULL;
5752 tcpcheck->inverse = inverse;
5753
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005754 /* tcpcheck comment */
5755 cur_arg += 2;
5756 if (strcmp(args[cur_arg], "comment") == 0) {
5757 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005758 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5759 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005760 err_code |= ERR_ALERT | ERR_FATAL;
5761 goto out;
5762 }
5763 tcpcheck->comment = strdup(args[cur_arg + 1]);
5764 }
5765
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005766 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5767 }
5768 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005769 struct tcpcheck_rule *tcpcheck;
5770
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005771 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005772 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5773 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005774 err_code |= ERR_ALERT | ERR_FATAL;
5775 goto out;
5776 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005777
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005778 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005779
5780 tcpcheck->action = TCPCHK_ACT_EXPECT;
5781 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5782 tcpcheck->string = strdup(args[cur_arg + 1]);
5783 tcpcheck->expect_regex = NULL;
5784 tcpcheck->inverse = inverse;
5785
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005786 /* tcpcheck comment */
5787 cur_arg += 2;
5788 if (strcmp(args[cur_arg], "comment") == 0) {
5789 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005790 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5791 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005792 err_code |= ERR_ALERT | ERR_FATAL;
5793 goto out;
5794 }
5795 tcpcheck->comment = strdup(args[cur_arg + 1]);
5796 }
5797
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005798 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5799 }
5800 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005801 struct tcpcheck_rule *tcpcheck;
5802
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005803 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005804 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5805 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005806 err_code |= ERR_ALERT | ERR_FATAL;
5807 goto out;
5808 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005809
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005810 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005811
5812 tcpcheck->action = TCPCHK_ACT_EXPECT;
5813 tcpcheck->string_len = 0;
5814 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005815 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5816 error = NULL;
5817 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005818 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5819 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005820 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005821 err_code |= ERR_ALERT | ERR_FATAL;
5822 goto out;
5823 }
5824 tcpcheck->inverse = inverse;
5825
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005826 /* tcpcheck comment */
5827 cur_arg += 2;
5828 if (strcmp(args[cur_arg], "comment") == 0) {
5829 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005830 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5831 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005832 err_code |= ERR_ALERT | ERR_FATAL;
5833 goto out;
5834 }
5835 tcpcheck->comment = strdup(args[cur_arg + 1]);
5836 }
5837
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005838 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5839 }
5840 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005841 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5842 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005843 err_code |= ERR_ALERT | ERR_FATAL;
5844 goto out;
5845 }
5846 }
5847 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005848 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 +02005849 err_code |= ERR_ALERT | ERR_FATAL;
5850 goto out;
5851 }
5852 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005853 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005854 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005855 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005856 err_code |= ERR_ALERT | ERR_FATAL;
5857 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005858 }
5859
Willy Tarreaub80c2302007-11-30 20:51:32 +01005860 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005861 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005862
5863 if (strcmp(args[1], "fail") == 0) {
5864 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005865 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005866 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5867 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005868 err_code |= ERR_ALERT | ERR_FATAL;
5869 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005870 }
5871
Willy Tarreau721d8e02017-12-01 18:25:08 +01005872 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005873 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005874 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5875 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005876 err_code |= ERR_ALERT | ERR_FATAL;
5877 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005878 }
5879 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5880 }
5881 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005882 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005883 err_code |= ERR_ALERT | ERR_FATAL;
5884 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005885 }
5886 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005887#ifdef TPROXY
5888 else if (!strcmp(args[0], "transparent")) {
5889 /* enable transparent proxy connections */
5890 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005891 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5892 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005893 }
5894#endif
5895 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005896 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005897 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005898
Willy Tarreaubaaee002006-06-26 02:48:02 +02005899 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 Tarreaubaaee002006-06-26 02:48:02 +02005903 }
5904 curproxy->maxconn = 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 Tarreaubaaee002006-06-26 02:48:02 +02005907 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005908 else if (!strcmp(args[0], "backlog")) { /* backlog */
5909 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005910 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005911
5912 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 Tarreauc73ce2b2008-01-06 10:55:10 +01005916 }
5917 curproxy->backlog = 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 Tarreauc73ce2b2008-01-06 10:55:10 +01005920 }
Willy Tarreau86034312006-12-29 00:10:33 +01005921 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005922 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005923 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005924
Willy Tarreau86034312006-12-29 00:10:33 +01005925 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005926 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005927 err_code |= ERR_ALERT | ERR_FATAL;
5928 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005929 }
5930 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005931 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5932 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005933 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005934 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5935 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005936 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005937 err_code |= ERR_ALERT | ERR_FATAL;
5938 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005939 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005940 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5941 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005942 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5943 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005944 err_code |= ERR_ALERT | ERR_FATAL;
5945 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005946 }
5947 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005948 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5949 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005950 }
5951 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005952 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005953 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005954 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005955
Willy Tarreaubaaee002006-06-26 02:48:02 +02005956 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005957 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005958 err_code |= ERR_ALERT | ERR_FATAL;
5959 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005960 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005961 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005962 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005963
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005964 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005965 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005966 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005967 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005968 goto out;
5969 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005970
5971 proto = protocol_by_family(sk->ss_family);
5972 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005973 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5974 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005975 err_code |= ERR_ALERT | ERR_FATAL;
5976 goto out;
5977 }
5978
5979 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005980 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5981 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005982 err_code |= ERR_ALERT | ERR_FATAL;
5983 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005984 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005985
5986 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005987 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5988 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005989 err_code |= ERR_ALERT | ERR_FATAL;
5990 goto out;
5991 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005992
William Lallemanddf1425a2015-04-28 20:17:49 +02005993 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5994 goto out;
5995
Willy Tarreaud5191e72010-02-09 20:50:45 +01005996 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005997 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005998 }
5999 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01006000 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006001 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006002
Willy Tarreaua93c74b2012-05-08 18:14:39 +02006003 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006004 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006005 err_code |= ERR_ALERT | ERR_FATAL;
6006 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02006007 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006008 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006009 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006010 /**
6011 * The syntax for hash-type config element is
6012 * hash-type {map-based|consistent} [[<algo>] avalanche]
6013 *
6014 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
6015 */
6016 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04006017
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006018 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
6019 err_code |= ERR_WARN;
6020
6021 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006022 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
6023 }
6024 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006025 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
6026 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006027 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006028 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 -05006029 err_code |= ERR_ALERT | ERR_FATAL;
6030 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01006031 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006032 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006033 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006034 err_code |= ERR_ALERT | ERR_FATAL;
6035 goto out;
6036 }
Bhaskar98634f02013-10-29 23:30:51 -04006037
6038 /* set the hash function to use */
6039 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006040 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04006041 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006042
6043 /* if consistent with no argument, then avalanche modifier is also applied */
6044 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6045 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006046 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006047 /* set the hash function */
6048 if (!strcmp(args[2], "sdbm")) {
6049 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6050 }
6051 else if (!strcmp(args[2], "djb2")) {
6052 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006053 }
6054 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006055 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006056 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006057 else if (!strcmp(args[2], "crc32")) {
6058 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6059 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006060 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006061 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 -05006062 err_code |= ERR_ALERT | ERR_FATAL;
6063 goto out;
6064 }
6065
6066 /* set the hash modifier */
6067 if (!strcmp(args[3], "avalanche")) {
6068 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6069 }
6070 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006071 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 -05006072 err_code |= ERR_ALERT | ERR_FATAL;
6073 goto out;
6074 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006075 }
William Lallemanda73203e2012-03-12 12:48:57 +01006076 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006077 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6078 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006079 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006080 err_code |= ERR_ALERT | ERR_FATAL;
6081 goto out;
6082 }
6083 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6084 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006085 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 -04006086 err_code |= ERR_ALERT | ERR_FATAL;
6087 goto out;
6088 }
6089 }
William Lallemanda73203e2012-03-12 12:48:57 +01006090 else if (strcmp(args[0], "unique-id-format") == 0) {
6091 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006092 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006093 err_code |= ERR_ALERT | ERR_FATAL;
6094 goto out;
6095 }
William Lallemand3203ff42012-11-11 17:30:56 +01006096 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006097 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 +01006098 err_code |= ERR_ALERT | ERR_FATAL;
6099 goto out;
6100 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006101 free(curproxy->conf.uniqueid_format_string);
6102 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006103
Willy Tarreau62a61232013-04-12 18:13:46 +02006104 free(curproxy->conf.uif_file);
6105 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6106 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006107 }
William Lallemanda73203e2012-03-12 12:48:57 +01006108
6109 else if (strcmp(args[0], "unique-id-header") == 0) {
6110 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006111 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006112 err_code |= ERR_ALERT | ERR_FATAL;
6113 goto out;
6114 }
6115 free(curproxy->header_unique_id);
6116 curproxy->header_unique_id = strdup(args[1]);
6117 }
6118
William Lallemand723b73a2012-02-08 16:37:49 +01006119 else if (strcmp(args[0], "log-format") == 0) {
6120 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006121 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006122 err_code |= ERR_ALERT | ERR_FATAL;
6123 goto out;
6124 }
William Lallemand3203ff42012-11-11 17:30:56 +01006125 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006126 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 +01006127 err_code |= ERR_ALERT | ERR_FATAL;
6128 goto out;
6129 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006130 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6131 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006132
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006133 if (curproxy->conf.logformat_string == default_http_log_format)
6134 oldlogformat = "option httplog";
6135 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6136 oldlogformat = "option tcplog";
6137 else if (curproxy->conf.logformat_string == clf_http_log_format)
6138 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006139 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6140 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006141 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006142 if (curproxy->conf.logformat_string != default_http_log_format &&
6143 curproxy->conf.logformat_string != default_tcp_log_format &&
6144 curproxy->conf.logformat_string != clf_http_log_format)
6145 free(curproxy->conf.logformat_string);
6146 curproxy->conf.logformat_string = strdup(args[1]);
6147
6148 free(curproxy->conf.lfs_file);
6149 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6150 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006151
6152 /* get a chance to improve log-format error reporting by
6153 * reporting the correct line-number when possible.
6154 */
6155 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006156 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6157 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006158 err_code |= ERR_WARN;
6159 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006160 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006161 else if (!strcmp(args[0], "log-format-sd")) {
6162 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006163 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006164 err_code |= ERR_ALERT | ERR_FATAL;
6165 goto out;
6166 }
6167 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006168 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 +02006169 err_code |= ERR_ALERT | ERR_FATAL;
6170 goto out;
6171 }
6172
6173 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6174 free(curproxy->conf.logformat_sd_string);
6175 curproxy->conf.logformat_sd_string = strdup(args[1]);
6176
6177 free(curproxy->conf.lfsd_file);
6178 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6179 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6180
6181 /* get a chance to improve log-format-sd error reporting by
6182 * reporting the correct line-number when possible.
6183 */
6184 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006185 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6186 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006187 err_code |= ERR_WARN;
6188 }
6189 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006190 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6191 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006192 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 +01006193 err_code |= ERR_ALERT | ERR_FATAL;
6194 goto out;
6195 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006196 chunk_destroy(&curproxy->log_tag);
6197 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006198 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006199 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6200 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6201 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006202 err_code |= ERR_ALERT | ERR_FATAL;
6203 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006204 }
6205 }
6206 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006207 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006208 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006209 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006210 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006211
Willy Tarreau977b8e42006-12-29 14:19:17 +01006212 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006213 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006214
Willy Tarreaubaaee002006-06-26 02:48:02 +02006215 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006216 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6217 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006218 err_code |= ERR_ALERT | ERR_FATAL;
6219 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006220 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006221
6222 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006223 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6224 free(curproxy->conn_src.iface_name);
6225 curproxy->conn_src.iface_name = NULL;
6226 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006227
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006228 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006229 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006230 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6231 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006232 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006233 goto out;
6234 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006235
6236 proto = protocol_by_family(sk->ss_family);
6237 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006238 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6239 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006240 err_code |= ERR_ALERT | ERR_FATAL;
6241 goto out;
6242 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006243
6244 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006245 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6246 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006247 err_code |= ERR_ALERT | ERR_FATAL;
6248 goto out;
6249 }
6250
Willy Tarreauef9a3602012-12-08 22:29:20 +01006251 curproxy->conn_src.source_addr = *sk;
6252 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006253
6254 cur_arg = 2;
6255 while (*(args[cur_arg])) {
6256 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006257#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006258 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006259 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6260 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006261 err_code |= ERR_ALERT | ERR_FATAL;
6262 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006263 }
6264
6265 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006266 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6267 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006268 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006269 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6270 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006271 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6272 char *name, *end;
6273
6274 name = args[cur_arg+1] + 7;
6275 while (isspace(*name))
6276 name++;
6277
6278 end = name;
6279 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6280 end++;
6281
Willy Tarreauef9a3602012-12-08 22:29:20 +01006282 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6283 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6284 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6285 curproxy->conn_src.bind_hdr_len = end - name;
6286 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6287 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6288 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006289
6290 /* now look for an occurrence number */
6291 while (isspace(*end))
6292 end++;
6293 if (*end == ',') {
6294 end++;
6295 name = end;
6296 if (*end == '-')
6297 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006298 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006299 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006300 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006301 }
6302
Willy Tarreauef9a3602012-12-08 22:29:20 +01006303 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006304 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6305 " occurrences values smaller than %d.\n",
6306 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006307 err_code |= ERR_ALERT | ERR_FATAL;
6308 goto out;
6309 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006310 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006311 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006312
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006313 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006314 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006315 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6316 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006317 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006318 goto out;
6319 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006320
6321 proto = protocol_by_family(sk->ss_family);
6322 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006323 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6324 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006325 err_code |= ERR_ALERT | ERR_FATAL;
6326 goto out;
6327 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006328
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006329 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006330 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6331 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006332 err_code |= ERR_ALERT | ERR_FATAL;
6333 goto out;
6334 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006335 curproxy->conn_src.tproxy_addr = *sk;
6336 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006337 }
6338 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006339#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006340 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6341 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006342 err_code |= ERR_ALERT | ERR_FATAL;
6343 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006344#endif
6345 cur_arg += 2;
6346 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006347 }
6348
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006349 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6350#ifdef SO_BINDTODEVICE
6351 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006352 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6353 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006354 err_code |= ERR_ALERT | ERR_FATAL;
6355 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006356 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006357 free(curproxy->conn_src.iface_name);
6358 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6359 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006360 global.last_checks |= LSTCHK_NETADM;
6361#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006362 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6363 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006364 err_code |= ERR_ALERT | ERR_FATAL;
6365 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006366#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006367 cur_arg += 2;
6368 continue;
6369 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006370 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6371 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006372 err_code |= ERR_ALERT | ERR_FATAL;
6373 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006374 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006375 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006376 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006377 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6378 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006379 err_code |= ERR_ALERT | ERR_FATAL;
6380 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006381 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006382 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006383 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006384 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6385 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006386 err_code |= ERR_ALERT | ERR_FATAL;
6387 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006388 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006389
6390 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006391 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006392 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006393 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006394 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006395 }
6396 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006397 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006398 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006399 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006400 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006401 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006402 }
6403 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006404 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006405 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006406 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006407 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006408 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006409 }
6410 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006411 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006412 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006413 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006414 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006415 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006416 }
6417 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006418 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006419 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006420 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006421 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006422 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006423 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006424 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006425 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006426 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006427 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006428 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006429 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006430 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006431 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006432 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006433 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6434 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006435 err_code |= ERR_ALERT | ERR_FATAL;
6436 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006437 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006438
6439 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006440 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006441 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006442 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006443 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006444 }
6445 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006446 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006447 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006448 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006449 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006450 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006451 }
6452 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006453 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006454 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006455 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006456 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006457 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006458 }
6459 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006460 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006461 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006462 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006463 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006464 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006465 }
6466 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006467 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006468 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006469 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006470 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006471 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006472 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006473 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006474 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006475 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006476 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006477 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006478 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006479 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006480 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006481 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006482
Willy Tarreaubaaee002006-06-26 02:48:02 +02006483 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006484 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006485 err_code |= ERR_ALERT | ERR_FATAL;
6486 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006487 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006488 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006489 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006490
Willy Tarreaubaaee002006-06-26 02:48:02 +02006491 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006492 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006493 err_code |= ERR_ALERT | ERR_FATAL;
6494 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006495 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006496
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006497 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006498 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006499 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6500 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006501 err_code |= ERR_ALERT | ERR_FATAL;
6502 goto out;
6503 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006504 err_code |= warnif_cond_conflicts(cond,
6505 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6506 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006507 }
6508 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006509 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6510 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006511 err_code |= ERR_ALERT | ERR_FATAL;
6512 goto out;
6513 }
6514
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006515 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006516 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006517 wl->s = strdup(args[1]);
6518 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006519 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006520 }
6521 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006522 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006523 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6524 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006525 err_code |= ERR_ALERT | ERR_FATAL;
6526 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006527 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006528
Willy Tarreauade5ec42010-01-28 19:33:49 +01006529 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006530 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006531 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006532 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006533 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006534 }
6535 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006536 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006537 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006538 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006539 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006540 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006541 }
6542 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006543 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006544 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006545 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006546 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006547 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006548 }
6549 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006550 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006551 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6552 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006553 err_code |= ERR_ALERT | ERR_FATAL;
6554 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006555 }
6556
Willy Tarreauade5ec42010-01-28 19:33:49 +01006557 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006558 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006559 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006560 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006561 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006562 }
6563 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006564 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006565 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006566 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006567 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006568 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006569 }
6570 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006571 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006572 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006573 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006574 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006575 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006576 }
6577 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006578 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006579
Willy Tarreaubaaee002006-06-26 02:48:02 +02006580 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006581 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006582 err_code |= ERR_ALERT | ERR_FATAL;
6583 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006584 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006585 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006586 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006587
Willy Tarreaubaaee002006-06-26 02:48:02 +02006588 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006589 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006590 err_code |= ERR_ALERT | ERR_FATAL;
6591 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006592 }
6593
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006594 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006595 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006596 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6597 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006598 err_code |= ERR_ALERT | ERR_FATAL;
6599 goto out;
6600 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006601 err_code |= warnif_cond_conflicts(cond,
6602 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6603 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006604 }
6605 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006606 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6607 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006608 err_code |= ERR_ALERT | ERR_FATAL;
6609 goto out;
6610 }
6611
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006612 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006613 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006614 wl->s = strdup(args[1]);
6615 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006616 }
6617 else if (!strcmp(args[0], "errorloc") ||
6618 !strcmp(args[0], "errorloc302") ||
6619 !strcmp(args[0], "errorloc303")) { /* error location */
6620 int errnum, errlen;
6621 char *err;
6622
Willy Tarreau977b8e42006-12-29 14:19:17 +01006623 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006624 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006625
Willy Tarreaubaaee002006-06-26 02:48:02 +02006626 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006627 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 +02006628 err_code |= ERR_ALERT | ERR_FATAL;
6629 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006630 }
6631
6632 errnum = atol(args[1]);
6633 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006634 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6635 err = malloc(errlen);
6636 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006637 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006638 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6639 err = malloc(errlen);
6640 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006641 }
6642
Willy Tarreau0f772532006-12-23 20:51:41 +01006643 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6644 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006645 chunk_destroy(&curproxy->errmsg[rc]);
6646 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006647 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006648 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006649 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006650
6651 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006652 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6653 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006654 free(err);
6655 }
6656 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006657 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6658 int errnum, errlen, fd;
6659 char *err;
6660 struct stat stat;
6661
6662 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006663 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006664
6665 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006666 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 +02006667 err_code |= ERR_ALERT | ERR_FATAL;
6668 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006669 }
6670
6671 fd = open(args[2], O_RDONLY);
6672 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006673 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6674 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006675 if (fd >= 0)
6676 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006677 err_code |= ERR_ALERT | ERR_FATAL;
6678 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006679 }
6680
Willy Tarreau27a674e2009-08-17 07:23:33 +02006681 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006682 errlen = stat.st_size;
6683 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006684 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6685 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006686 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006687 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006688 }
6689
6690 err = malloc(errlen); /* malloc() must succeed during parsing */
6691 errnum = read(fd, err, errlen);
6692 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006693 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6694 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006695 close(fd);
6696 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006697 err_code |= ERR_ALERT | ERR_FATAL;
6698 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006699 }
6700 close(fd);
6701
6702 errnum = atol(args[1]);
6703 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6704 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006705 chunk_destroy(&curproxy->errmsg[rc]);
6706 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006707 break;
6708 }
6709 }
6710
6711 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006712 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6713 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006714 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006715 free(err);
6716 }
6717 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006718 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006719 struct cfg_kw_list *kwl;
6720 int index;
6721
6722 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6723 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6724 if (kwl->kw[index].section != CFG_LISTEN)
6725 continue;
6726 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6727 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006728 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006729 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006730 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006731 err_code |= ERR_ALERT | ERR_FATAL;
6732 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006733 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006734 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006735 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006736 err_code |= ERR_WARN;
6737 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006738 }
Willy Tarreau93893792009-07-23 13:19:11 +02006739 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006740 }
6741 }
6742 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006743
Christopher Faulet767a84b2017-11-24 16:50:31 +01006744 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006745 err_code |= ERR_ALERT | ERR_FATAL;
6746 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006747 }
Willy Tarreau93893792009-07-23 13:19:11 +02006748 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006749 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006750 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006751}
6752
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006753int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006754cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6755{
6756#ifdef CONFIG_HAP_NS
6757 const char *err;
6758 const char *item = args[0];
6759
6760 if (!strcmp(item, "namespace_list")) {
6761 return 0;
6762 }
6763 else if (!strcmp(item, "namespace")) {
6764 size_t idx = 1;
6765 const char *current;
6766 while (*(current = args[idx++])) {
6767 err = invalid_char(current);
6768 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006769 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6770 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006771 return ERR_ALERT | ERR_FATAL;
6772 }
6773
6774 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006775 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6776 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006777 return ERR_ALERT | ERR_FATAL;
6778 }
6779 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006780 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6781 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006782 return ERR_ALERT | ERR_FATAL;
6783 }
6784 }
6785 }
6786
6787 return 0;
6788#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006789 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6790 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006791 return ERR_ALERT | ERR_FATAL;
6792#endif
6793}
6794
6795int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006796cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6797{
6798
6799 int err_code = 0;
6800 const char *err;
6801
6802 if (!strcmp(args[0], "userlist")) { /* new userlist */
6803 struct userlist *newul;
6804
6805 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006806 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6807 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006808 err_code |= ERR_ALERT | ERR_FATAL;
6809 goto out;
6810 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006811 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6812 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006813
6814 err = invalid_char(args[1]);
6815 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006816 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6817 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006818 err_code |= ERR_ALERT | ERR_FATAL;
6819 goto out;
6820 }
6821
6822 for (newul = userlist; newul; newul = newul->next)
6823 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006824 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6825 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006826 err_code |= ERR_WARN;
6827 goto out;
6828 }
6829
Vincent Bernat02779b62016-04-03 13:48:43 +02006830 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006831 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006832 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006833 err_code |= ERR_ALERT | ERR_ABORT;
6834 goto out;
6835 }
6836
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006837 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006838 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006839 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006840 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006841 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006842 goto out;
6843 }
6844
6845 newul->next = userlist;
6846 userlist = newul;
6847
6848 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006849 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006850 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006851 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006852
6853 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006854 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6855 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006856 err_code |= ERR_ALERT | ERR_FATAL;
6857 goto out;
6858 }
6859
6860 err = invalid_char(args[1]);
6861 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006862 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6863 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006864 err_code |= ERR_ALERT | ERR_FATAL;
6865 goto out;
6866 }
6867
William Lallemand4ac9f542015-05-28 18:03:51 +02006868 if (!userlist)
6869 goto out;
6870
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006871 for (ag = userlist->groups; ag; ag = ag->next)
6872 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006873 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6874 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006875 err_code |= ERR_ALERT;
6876 goto out;
6877 }
6878
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006879 ag = calloc(1, sizeof(*ag));
6880 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006881 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006882 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006883 goto out;
6884 }
6885
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006886 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006887 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006888 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006889 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006890 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006891 goto out;
6892 }
6893
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006894 cur_arg = 2;
6895
6896 while (*args[cur_arg]) {
6897 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006898 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006899 cur_arg += 2;
6900 continue;
6901 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006902 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6903 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006904 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006905 free(ag->groupusers);
6906 free(ag->name);
6907 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006908 goto out;
6909 }
6910 }
6911
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006912 ag->next = userlist->groups;
6913 userlist->groups = ag;
6914
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006915 } else if (!strcmp(args[0], "user")) { /* new user */
6916 struct auth_users *newuser;
6917 int cur_arg;
6918
6919 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006920 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6921 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006922 err_code |= ERR_ALERT | ERR_FATAL;
6923 goto out;
6924 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006925 if (!userlist)
6926 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006927
6928 for (newuser = userlist->users; newuser; newuser = newuser->next)
6929 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006930 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6931 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006932 err_code |= ERR_ALERT;
6933 goto out;
6934 }
6935
Vincent Bernat02779b62016-04-03 13:48:43 +02006936 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006937 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006938 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006939 err_code |= ERR_ALERT | ERR_ABORT;
6940 goto out;
6941 }
6942
6943 newuser->user = strdup(args[1]);
6944
6945 newuser->next = userlist->users;
6946 userlist->users = newuser;
6947
6948 cur_arg = 2;
6949
6950 while (*args[cur_arg]) {
6951 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006952#ifdef CONFIG_HAP_CRYPT
6953 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006954 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6955 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006956 err_code |= ERR_ALERT | ERR_FATAL;
6957 goto out;
6958 }
6959#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006960 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6961 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006962 err_code |= ERR_ALERT;
6963#endif
6964 newuser->pass = strdup(args[cur_arg + 1]);
6965 cur_arg += 2;
6966 continue;
6967 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6968 newuser->pass = strdup(args[cur_arg + 1]);
6969 newuser->flags |= AU_O_INSECURE;
6970 cur_arg += 2;
6971 continue;
6972 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006973 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006974 cur_arg += 2;
6975 continue;
6976 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006977 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6978 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006979 err_code |= ERR_ALERT | ERR_FATAL;
6980 goto out;
6981 }
6982 }
6983 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006984 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 +01006985 err_code |= ERR_ALERT | ERR_FATAL;
6986 }
6987
6988out:
6989 return err_code;
6990}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006991
Christopher Faulet79bdef32016-11-04 22:36:15 +01006992int
6993cfg_parse_scope(const char *file, int linenum, char *line)
6994{
6995 char *beg, *end, *scope = NULL;
6996 int err_code = 0;
6997 const char *err;
6998
6999 beg = line + 1;
7000 end = strchr(beg, ']');
7001
7002 /* Detect end of scope declaration */
7003 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007004 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
7005 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007006 err_code |= ERR_ALERT | ERR_FATAL;
7007 goto out;
7008 }
7009
7010 /* Get scope name and check its validity */
7011 scope = my_strndup(beg, end-beg);
7012 err = invalid_char(scope);
7013 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007014 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
7015 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007016 err_code |= ERR_ALERT | ERR_ABORT;
7017 goto out;
7018 }
7019
7020 /* Be sure to have a scope declaration alone on its line */
7021 line = end+1;
7022 while (isspace((unsigned char)*line))
7023 line++;
7024 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007025 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7026 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007027 err_code |= ERR_ALERT | ERR_ABORT;
7028 goto out;
7029 }
7030
7031 /* We have a valid scope declaration, save it */
7032 free(cfg_scope);
7033 cfg_scope = scope;
7034 scope = NULL;
7035
7036 out:
7037 free(scope);
7038 return err_code;
7039}
7040
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01007041int
7042cfg_parse_track_sc_num(unsigned int *track_sc_num,
7043 const char *arg, const char *end, char **errmsg)
7044{
7045 const char *p;
7046 unsigned int num;
7047
7048 p = arg;
7049 num = read_uint64(&arg, end);
7050
7051 if (arg != end) {
7052 memprintf(errmsg, "Wrong track-sc number '%s'", p);
7053 return -1;
7054 }
7055
7056 if (num >= MAX_SESS_STKCTR) {
7057 memprintf(errmsg, "%u track-sc number exceeding "
7058 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
7059 return -1;
7060 }
7061
7062 *track_sc_num = num;
7063 return 0;
7064}
7065
Willy Tarreaubaaee002006-06-26 02:48:02 +02007066/*
7067 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007068 * Returns the error code, 0 if OK, or any combination of :
7069 * - ERR_ABORT: must abort ASAP
7070 * - ERR_FATAL: we can continue parsing but not start the service
7071 * - ERR_WARN: a warning has been emitted
7072 * - ERR_ALERT: an alert has been emitted
7073 * Only the two first ones can stop processing, the two others are just
7074 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007075 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007076int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007077{
William Lallemand64e84512015-05-12 14:25:37 +02007078 char *thisline;
7079 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007080 FILE *f;
7081 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007082 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007083 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007084 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007085 int readbytes = 0;
7086
7087 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007088 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007089 return -1;
7090 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007091
David Carlier97880bb2016-04-08 10:35:26 +01007092 if ((f=fopen(file,"r")) == NULL) {
7093 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007094 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007095 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007096
William Lallemandb2f07452015-05-12 14:27:13 +02007097next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007098 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007099 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007100 char *end;
7101 char *args[MAX_LINE_ARGS + 1];
7102 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007103 int dquote = 0; /* double quote */
7104 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007105
Willy Tarreaubaaee002006-06-26 02:48:02 +02007106 linenum++;
7107
7108 end = line + strlen(line);
7109
William Lallemand64e84512015-05-12 14:25:37 +02007110 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007111 /* Check if we reached the limit and the last char is not \n.
7112 * Watch out for the last line without the terminating '\n'!
7113 */
William Lallemand64e84512015-05-12 14:25:37 +02007114 char *newline;
7115 int newlinesize = linesize * 2;
7116
7117 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7118 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007119 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7120 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007121 err_code |= ERR_ALERT | ERR_FATAL;
7122 continue;
7123 }
7124
7125 readbytes = linesize - 1;
7126 linesize = newlinesize;
7127 thisline = newline;
7128 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007129 }
7130
William Lallemand64e84512015-05-12 14:25:37 +02007131 readbytes = 0;
7132
Willy Tarreaubaaee002006-06-26 02:48:02 +02007133 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007134 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007135 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007136
Christopher Faulet79bdef32016-11-04 22:36:15 +01007137
7138 if (*line == '[') {/* This is the begining if a scope */
7139 err_code |= cfg_parse_scope(file, linenum, line);
7140 goto next_line;
7141 }
7142
Willy Tarreaubaaee002006-06-26 02:48:02 +02007143 arg = 0;
7144 args[arg] = line;
7145
7146 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007147 if (*line == '"' && !squote) { /* double quote outside single quotes */
7148 if (dquote)
7149 dquote = 0;
7150 else
7151 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007152 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007153 end--;
7154 }
7155 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7156 if (squote)
7157 squote = 0;
7158 else
7159 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007160 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007161 end--;
7162 }
7163 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007164 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7165 * C equivalent value. Other combinations left unchanged (eg: \1).
7166 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007167 int skip = 0;
7168 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7169 *line = line[1];
7170 skip = 1;
7171 }
7172 else if (line[1] == 'r') {
7173 *line = '\r';
7174 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007175 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007176 else if (line[1] == 'n') {
7177 *line = '\n';
7178 skip = 1;
7179 }
7180 else if (line[1] == 't') {
7181 *line = '\t';
7182 skip = 1;
7183 }
7184 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007185 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007186 unsigned char hex1, hex2;
7187 hex1 = toupper(line[2]) - '0';
7188 hex2 = toupper(line[3]) - '0';
7189 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7190 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7191 *line = (hex1<<4) + hex2;
7192 skip = 3;
7193 }
7194 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007195 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007196 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007197 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007198 } else if (line[1] == '"') {
7199 *line = '"';
7200 skip = 1;
7201 } else if (line[1] == '\'') {
7202 *line = '\'';
7203 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007204 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7205 *line = '$';
7206 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007207 }
7208 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007209 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007210 end -= skip;
7211 }
7212 line++;
7213 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007214 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007215 /* end of string, end of loop */
7216 *line = 0;
7217 break;
7218 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007219 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007220 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007221 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007222 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007223 line++;
7224 args[++arg] = line;
7225 }
William Lallemandb2f07452015-05-12 14:27:13 +02007226 else if (dquote && *line == '$') {
7227 /* environment variables are evaluated inside double quotes */
7228 char *var_beg;
7229 char *var_end;
7230 char save_char;
7231 char *value;
7232 int val_len;
7233 int newlinesize;
7234 int braces = 0;
7235
7236 var_beg = line + 1;
7237 var_end = var_beg;
7238
7239 if (*var_beg == '{') {
7240 var_beg++;
7241 var_end++;
7242 braces = 1;
7243 }
7244
7245 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007246 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 +02007247 err_code |= ERR_ALERT | ERR_FATAL;
7248 goto next_line; /* skip current line */
7249 }
7250
7251 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7252 var_end++;
7253
7254 save_char = *var_end;
7255 *var_end = '\0';
7256 value = getenv(var_beg);
7257 *var_end = save_char;
7258 val_len = value ? strlen(value) : 0;
7259
7260 if (braces) {
7261 if (*var_end == '}') {
7262 var_end++;
7263 braces = 0;
7264 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007265 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007266 err_code |= ERR_ALERT | ERR_FATAL;
7267 goto next_line; /* skip current line */
7268 }
7269 }
7270
7271 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7272
7273 /* if not enough space in thisline */
7274 if (newlinesize > linesize) {
7275 char *newline;
7276
7277 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7278 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007279 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007280 err_code |= ERR_ALERT | ERR_FATAL;
7281 goto next_line; /* slip current line */
7282 }
7283 /* recompute pointers if realloc returns a new pointer */
7284 if (newline != thisline) {
7285 int i;
7286 int diff;
7287
7288 for (i = 0; i <= arg; i++) {
7289 diff = args[i] - thisline;
7290 args[i] = newline + diff;
7291 }
7292
7293 diff = var_end - thisline;
7294 var_end = newline + diff;
7295 diff = end - thisline;
7296 end = newline + diff;
7297 diff = line - thisline;
7298 line = newline + diff;
7299 thisline = newline;
7300 }
7301 linesize = newlinesize;
7302 }
7303
7304 /* insert value inside the line */
7305 memmove(line + val_len, var_end, end - var_end + 1);
7306 memcpy(line, value, val_len);
7307 end += val_len - (var_end - line);
7308 line += val_len;
7309 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007310 else {
7311 line++;
7312 }
7313 }
William Lallemandb2f07452015-05-12 14:27:13 +02007314
William Lallemandf9873ba2015-05-05 17:37:14 +02007315 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007316 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007317 err_code |= ERR_ALERT | ERR_FATAL;
7318 }
7319
7320 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007321 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007322 err_code |= ERR_ALERT | ERR_FATAL;
7323 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007324
7325 /* empty line */
7326 if (!**args)
7327 continue;
7328
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007329 if (*line) {
7330 /* we had to stop due to too many args.
7331 * Let's terminate the string, print the offending part then cut the
7332 * last arg.
7333 */
7334 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7335 line++;
7336 *line = '\0';
7337
Christopher Faulet767a84b2017-11-24 16:50:31 +01007338 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7339 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007340 err_code |= ERR_ALERT | ERR_FATAL;
7341 args[arg] = line;
7342 }
7343
Willy Tarreau540abe42007-05-02 20:50:16 +02007344 /* zero out remaining args and ensure that at least one entry
7345 * is zeroed out.
7346 */
7347 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007348 args[arg] = line;
7349 }
7350
Willy Tarreau3842f002009-06-14 11:39:52 +02007351 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007352 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007353 char *tmp;
7354
Willy Tarreau3842f002009-06-14 11:39:52 +02007355 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007356 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007357 for (arg=0; *args[arg+1]; arg++)
7358 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007359 *tmp = '\0'; // fix the next arg to \0
7360 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007361 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007362 else if (!strcmp(args[0], "default")) {
7363 kwm = KWM_DEF;
7364 for (arg=0; *args[arg+1]; arg++)
7365 args[arg] = args[arg+1]; // shift args after inversion
7366 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007367
William Lallemand0f99e342011-10-12 17:50:54 +02007368 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7369 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007370 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007371 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007372 }
7373
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007374 /* detect section start */
7375 list_for_each_entry(ics, &sections, list) {
7376 if (strcmp(args[0], ics->section_name) == 0) {
7377 cursection = ics->section_name;
7378 cs = ics;
7379 break;
7380 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007381 }
7382
William Lallemandd2ff56d2017-10-16 11:06:50 +02007383 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007384 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007385 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007386 } else {
7387 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007388
William Lallemandd2ff56d2017-10-16 11:06:50 +02007389 if (pcs != cs && pcs && pcs->post_section_parser) {
7390 err_code |= pcs->post_section_parser();
7391 if (err_code & ERR_ABORT)
7392 goto err;
7393 }
7394
7395 err_code |= cs->section_parser(file, linenum, args, kwm);
7396 if (err_code & ERR_ABORT)
7397 goto err;
7398 }
7399 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007400 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007401
7402 if (pcs == cs && pcs && pcs->post_section_parser)
7403 err_code |= pcs->post_section_parser();
7404
7405err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007406 free(cfg_scope);
7407 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007408 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007409 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007410 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007411 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007412}
7413
Willy Tarreau64ab6072014-09-16 12:17:36 +02007414/* This function propagates processes from frontend <from> to backend <to> so
7415 * that it is always guaranteed that a backend pointed to by a frontend is
7416 * bound to all of its processes. After that, if the target is a "listen"
7417 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007418 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007419 * checked first to ensure that <to> is already bound to all processes of
7420 * <from>, there is no risk of looping and we ensure to follow the shortest
7421 * path to the destination.
7422 *
7423 * It is possible to set <to> to NULL for the first call so that the function
7424 * takes care of visiting the initial frontend in <from>.
7425 *
7426 * It is important to note that the function relies on the fact that all names
7427 * have already been resolved.
7428 */
7429void propagate_processes(struct proxy *from, struct proxy *to)
7430{
7431 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007432
7433 if (to) {
7434 /* check whether we need to go down */
7435 if (from->bind_proc &&
7436 (from->bind_proc & to->bind_proc) == from->bind_proc)
7437 return;
7438
7439 if (!from->bind_proc && !to->bind_proc)
7440 return;
7441
7442 to->bind_proc = from->bind_proc ?
7443 (to->bind_proc | from->bind_proc) : 0;
7444
7445 /* now propagate down */
7446 from = to;
7447 }
7448
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007449 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007450 return;
7451
Willy Tarreauf6b70012014-12-18 14:00:43 +01007452 if (from->state == PR_STSTOPPED)
7453 return;
7454
Willy Tarreau64ab6072014-09-16 12:17:36 +02007455 /* default_backend */
7456 if (from->defbe.be)
7457 propagate_processes(from, from->defbe.be);
7458
7459 /* use_backend */
7460 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007461 if (rule->dynamic)
7462 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007463 to = rule->be.backend;
7464 propagate_processes(from, to);
7465 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007466}
7467
Willy Tarreaubb925012009-07-23 13:36:36 +02007468/*
7469 * Returns the error code, 0 if OK, or any combination of :
7470 * - ERR_ABORT: must abort ASAP
7471 * - ERR_FATAL: we can continue parsing but not start the service
7472 * - ERR_WARN: a warning has been emitted
7473 * - ERR_ALERT: an alert has been emitted
7474 * Only the two first ones can stop processing, the two others are just
7475 * indicators.
7476 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007477int check_config_validity()
7478{
7479 int cfgerr = 0;
7480 struct proxy *curproxy = NULL;
7481 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007482 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007483 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007484 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007485 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007486 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06007487 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007488
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007489 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007490 /*
7491 * Now, check for the integrity of all that we have collected.
7492 */
7493
7494 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007495 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007496
Willy Tarreau193b8c62012-11-22 00:17:38 +01007497 if (!global.tune.max_http_hdr)
7498 global.tune.max_http_hdr = MAX_HTTP_HDR;
7499
7500 if (!global.tune.cookie_len)
7501 global.tune.cookie_len = CAPTURE_LEN;
7502
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007503 if (!global.tune.requri_len)
7504 global.tune.requri_len = REQURI_LEN;
7505
Willy Tarreaubafbe012017-11-24 17:34:44 +01007506 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007507
Willy Tarreaubafbe012017-11-24 17:34:44 +01007508 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007509
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007510 /* Post initialisation of the users and groups lists. */
7511 err_code = userlist_postinit();
7512 if (err_code != ERR_NONE)
7513 goto out;
7514
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007515 /* first, we will invert the proxy list order */
7516 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007517 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007518 struct proxy *next;
7519
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007520 next = proxies_list->next;
7521 proxies_list->next = curproxy;
7522 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007523 if (!next)
7524 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007525 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007526 }
7527
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007528 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007529 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007530 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007531 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007532 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007533 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007534 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007535 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007536
Willy Tarreau050536d2012-10-04 08:47:34 +02007537 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007538 /* proxy ID not set, use automatic numbering with first
7539 * spare entry starting with next_pxid.
7540 */
7541 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7542 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7543 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007544 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007545 next_pxid++;
7546
Willy Tarreau55ea7572007-06-17 19:56:27 +02007547
Willy Tarreaubaaee002006-06-26 02:48:02 +02007548 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007549 /* ensure we don't keep listeners uselessly bound */
7550 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007551 free((void *)curproxy->table.peers.name);
7552 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007553 continue;
7554 }
7555
Willy Tarreau102df612014-05-07 23:56:38 +02007556 /* Check multi-process mode compatibility for the current proxy */
7557
7558 if (curproxy->bind_proc) {
7559 /* an explicit bind-process was specified, let's check how many
7560 * processes remain.
7561 */
David Carliere6c39412015-07-02 07:00:17 +00007562 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007563
7564 curproxy->bind_proc &= nbits(global.nbproc);
7565 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007566 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 +02007567 curproxy->bind_proc = 1;
7568 }
7569 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007570 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 +02007571 curproxy->bind_proc = 0;
7572 }
7573 }
7574
Willy Tarreau3d209582014-05-09 17:06:11 +02007575 /* check and reduce the bind-proc of each listener */
7576 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7577 unsigned long mask;
7578
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007579 /* HTTP frontends with "h2" as ALPN/NPN will work in
7580 * HTTP/2 and absolutely require buffers 16kB or larger.
7581 */
7582#ifdef USE_OPENSSL
7583 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7584#ifdef OPENSSL_NPN_NEGOTIATED
7585 /* check NPN */
7586 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007587 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",
7588 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007589 cfgerr++;
7590 }
7591#endif
7592#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7593 /* check ALPN */
7594 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007595 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",
7596 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007597 cfgerr++;
7598 }
7599#endif
7600 } /* HTTP && bufsize < 16384 */
7601#endif
7602
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007603 /* detect and address thread affinity inconsistencies */
7604 nbproc = 0;
7605 if (bind_conf->bind_proc)
7606 nbproc = my_ffsl(bind_conf->bind_proc);
7607
7608 mask = bind_conf->bind_thread[nbproc - 1];
Willy Tarreau0c026f42018-08-01 19:12:20 +02007609 if (mask && !(mask & all_threads_mask)) {
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007610 unsigned long new_mask = 0;
7611
7612 while (mask) {
Willy Tarreau0c026f42018-08-01 19:12:20 +02007613 new_mask |= mask & all_threads_mask;
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007614 mask >>= global.nbthread;
7615 }
7616
7617 for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
7618 if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
7619 bind_conf->bind_thread[nbproc] = new_mask;
7620 }
7621 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",
7622 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
7623 }
7624
7625 /* detect process and nbproc affinity inconsistencies */
Willy Tarreau3d209582014-05-09 17:06:11 +02007626 if (!bind_conf->bind_proc)
7627 continue;
7628
7629 mask = nbits(global.nbproc);
7630 if (curproxy->bind_proc)
7631 mask &= curproxy->bind_proc;
7632 /* mask cannot be null here thanks to the previous checks */
7633
David Carliere6c39412015-07-02 07:00:17 +00007634 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007635 bind_conf->bind_proc &= mask;
7636
7637 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007638 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",
7639 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007640 bind_conf->bind_proc = mask & ~(mask - 1);
7641 }
7642 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007643 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",
7644 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007645 bind_conf->bind_proc = 0;
7646 }
7647 }
7648
Willy Tarreauff01a212009-03-15 13:46:16 +01007649 switch (curproxy->mode) {
7650 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007651 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007652 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007653 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7654 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007655 cfgerr++;
7656 }
7657
7658 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007659 ha_warning("config : servers will be ignored for %s '%s'.\n",
7660 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007661 break;
7662
7663 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007664 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007665 break;
7666
7667 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007668 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007669 break;
7670 }
7671
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007672 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007673 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7674 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007675 err_code |= ERR_WARN;
7676 }
7677
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007678 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007679 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007680 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007681 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7682 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007683 cfgerr++;
7684 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007685#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007686 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007687 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7688 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007689 cfgerr++;
7690 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007691#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007692 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007693 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7694 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007695 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007696 }
7697 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007698 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007699 /* If no LB algo is set in a backend, and we're not in
7700 * transparent mode, dispatch mode nor proxy mode, we
7701 * want to use balance roundrobin by default.
7702 */
7703 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7704 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007705 }
7706 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007707
Willy Tarreau1620ec32011-08-06 17:05:02 +02007708 if (curproxy->options & PR_O_DISPATCH)
7709 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7710 else if (curproxy->options & PR_O_HTTP_PROXY)
7711 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7712 else if (curproxy->options & PR_O_TRANSP)
7713 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007714
Willy Tarreau1620ec32011-08-06 17:05:02 +02007715 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7716 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007717 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7718 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007719 err_code |= ERR_WARN;
7720 curproxy->options &= ~PR_O_DISABLE404;
7721 }
7722 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007723 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7724 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007725 err_code |= ERR_WARN;
7726 curproxy->options &= ~PR_O2_CHK_SNDST;
7727 }
Willy Tarreauef781042010-01-27 11:53:01 +01007728 }
7729
Simon Horman98637e52014-06-20 12:30:16 +09007730 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7731 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007732 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7733 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007734 cfgerr++;
7735 }
7736 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007737 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7738 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007739 cfgerr++;
7740 }
7741 }
7742
Simon Horman64e34162015-02-06 11:11:57 +09007743 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007744 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007745 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7746 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7747 "'email-alert myhostname', or 'email-alert to' "
7748 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7749 "to be present).\n",
7750 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007751 err_code |= ERR_WARN;
7752 free_email_alert(curproxy);
7753 }
7754 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007755 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007756 }
7757
Simon Horman98637e52014-06-20 12:30:16 +09007758 if (curproxy->check_command) {
7759 int clear = 0;
7760 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007761 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7762 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007763 err_code |= ERR_WARN;
7764 clear = 1;
7765 }
7766 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007767 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7768 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007769 cfgerr++;
7770 }
7771 if (clear) {
7772 free(curproxy->check_command);
7773 curproxy->check_command = NULL;
7774 }
7775 }
7776
7777 if (curproxy->check_path) {
7778 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007779 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7780 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007781 err_code |= ERR_WARN;
7782 free(curproxy->check_path);
7783 curproxy->check_path = NULL;
7784 }
7785 }
7786
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007787 /* if a default backend was specified, let's find it */
7788 if (curproxy->defbe.name) {
7789 struct proxy *target;
7790
Willy Tarreauafb39922015-05-26 12:04:09 +02007791 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007792 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007793 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7794 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007795 cfgerr++;
7796 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007797 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7798 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007799 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007800 } else if (target->mode != curproxy->mode &&
7801 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7802
Christopher Faulet767a84b2017-11-24 16:50:31 +01007803 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7804 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7805 curproxy->conf.file, curproxy->conf.line,
7806 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7807 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007808 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007809 } else {
7810 free(curproxy->defbe.name);
7811 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007812 /* Update tot_fe_maxconn for a further fullconn's computation */
7813 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007814 /* Emit a warning if this proxy also has some servers */
7815 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007816 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7817 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007818 err_code |= ERR_WARN;
7819 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007820 }
7821 }
7822
Emeric Brun3f783572017-01-12 11:21:28 +01007823 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7824 /* Case of listen without default backend
7825 * The curproxy will be its own default backend
7826 * so we update tot_fe_maxconn for a further
7827 * fullconn's computation */
7828 curproxy->tot_fe_maxconn += curproxy->maxconn;
7829 }
7830
Willy Tarreau55ea7572007-06-17 19:56:27 +02007831 /* find the target proxy for 'use_backend' rules */
7832 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007833 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007834 struct logformat_node *node;
7835 char *pxname;
7836
7837 /* Try to parse the string as a log format expression. If the result
7838 * of the parsing is only one entry containing a simple string, then
7839 * it's a standard string corresponding to a static rule, thus the
7840 * parsing is cancelled and be.name is restored to be resolved.
7841 */
7842 pxname = rule->be.name;
7843 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007844 curproxy->conf.args.ctx = ARGC_UBK;
7845 curproxy->conf.args.file = rule->file;
7846 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007847 err = NULL;
7848 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007849 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7850 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007851 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007852 cfgerr++;
7853 continue;
7854 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007855 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7856
7857 if (!LIST_ISEMPTY(&rule->be.expr)) {
7858 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7859 rule->dynamic = 1;
7860 free(pxname);
7861 continue;
7862 }
7863 /* simple string: free the expression and fall back to static rule */
7864 free(node->arg);
7865 free(node);
7866 }
7867
7868 rule->dynamic = 0;
7869 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007870
Willy Tarreauafb39922015-05-26 12:04:09 +02007871 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007872 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007873 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7874 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007875 cfgerr++;
7876 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007877 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7878 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007879 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007880 } else if (target->mode != curproxy->mode &&
7881 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7882
Christopher Faulet767a84b2017-11-24 16:50:31 +01007883 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7884 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7885 curproxy->conf.file, curproxy->conf.line,
7886 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7887 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007888 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007889 } else {
7890 free((void *)rule->be.name);
7891 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007892 /* For each target of switching rules, we update
7893 * their tot_fe_maxconn, except if a previous rule point
7894 * on the same backend or on the default backend */
7895 if (rule->be.backend != curproxy->defbe.be) {
7896 struct switching_rule *swrule;
7897
7898 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7899 if (rule == swrule) {
7900 target->tot_fe_maxconn += curproxy->maxconn;
7901 break;
7902 }
7903 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7904 /* there is multiple ref of this backend */
7905 break;
7906 }
7907 }
7908 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007909 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007910 }
7911
Willy Tarreau64ab6072014-09-16 12:17:36 +02007912 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007913 list_for_each_entry(srule, &curproxy->server_rules, list) {
7914 struct server *target = findserver(curproxy, srule->srv.name);
7915
7916 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007917 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7918 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007919 cfgerr++;
7920 continue;
7921 }
7922 free((void *)srule->srv.name);
7923 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007924 }
7925
Emeric Brunb982a3d2010-01-04 15:45:53 +01007926 /* find the target table for 'stick' rules */
7927 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7928 struct proxy *target;
7929
Emeric Brun1d33b292010-01-04 15:47:17 +01007930 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7931 if (mrule->flags & STK_IS_STORE)
7932 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7933
Emeric Brunb982a3d2010-01-04 15:45:53 +01007934 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007935 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007936 else
7937 target = curproxy;
7938
7939 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007940 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7941 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007942 cfgerr++;
7943 }
7944 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007945 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7946 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007947 cfgerr++;
7948 }
Willy Tarreau12785782012-04-27 21:37:17 +02007949 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007950 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7951 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007952 cfgerr++;
7953 }
7954 else {
7955 free((void *)mrule->table.name);
7956 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007957 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007958 }
7959 }
7960
7961 /* find the target table for 'store response' rules */
7962 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7963 struct proxy *target;
7964
Emeric Brun1d33b292010-01-04 15:47:17 +01007965 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7966
Emeric Brunb982a3d2010-01-04 15:45:53 +01007967 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007968 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007969 else
7970 target = curproxy;
7971
7972 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007973 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7974 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007975 cfgerr++;
7976 }
7977 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007978 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7979 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007980 cfgerr++;
7981 }
Willy Tarreau12785782012-04-27 21:37:17 +02007982 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007983 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7984 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007985 cfgerr++;
7986 }
7987 else {
7988 free((void *)mrule->table.name);
7989 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007990 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007991 }
7992 }
7993
Christopher Faulete4e830d2017-09-18 14:51:41 +02007994 /* check validity for 'tcp-request' layer 4 rules */
7995 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
7996 err = NULL;
7997 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007998 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007999 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01008000 cfgerr++;
8001 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02008002 }
8003
Christopher Faulete4e830d2017-09-18 14:51:41 +02008004 /* check validity for 'tcp-request' layer 5 rules */
8005 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
8006 err = NULL;
8007 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008008 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008009 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008010 cfgerr++;
8011 }
8012 }
8013
Christopher Faulete4e830d2017-09-18 14:51:41 +02008014 /* check validity for 'tcp-request' layer 6 rules */
8015 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8016 err = NULL;
8017 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008018 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008019 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008020 cfgerr++;
8021 }
8022 }
8023
Christopher Faulete4e830d2017-09-18 14:51:41 +02008024 /* check validity for 'http-request' layer 7 rules */
8025 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
8026 err = NULL;
8027 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008028 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008029 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008030 cfgerr++;
8031 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008032 }
8033
Christopher Faulete4e830d2017-09-18 14:51:41 +02008034 /* check validity for 'http-response' layer 7 rules */
8035 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
8036 err = NULL;
8037 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008038 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008039 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02008040 cfgerr++;
8041 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008042 }
8043
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008044 /* move any "block" rules at the beginning of the http-request rules */
8045 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8046 /* insert block_rules into http_req_rules at the beginning */
8047 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8048 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8049 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8050 curproxy->http_req_rules.n = curproxy->block_rules.n;
8051 LIST_INIT(&curproxy->block_rules);
8052 }
8053
Emeric Brun32da3c42010-09-23 18:39:19 +02008054 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008055 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008056
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008057 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008058 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8059 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008060 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008061 break;
8062 }
8063 }
8064
8065 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008066 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8067 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008068 free((void *)curproxy->table.peers.name);
8069 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008070 cfgerr++;
8071 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008072 else if (curpeers->state == PR_STSTOPPED) {
8073 /* silently disable this peers section */
8074 curproxy->table.peers.p = NULL;
8075 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008076 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008077 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8078 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008079 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008080 cfgerr++;
8081 }
8082 }
8083
Simon Horman9dc49962015-01-30 11:22:59 +09008084
8085 if (curproxy->email_alert.mailers.name) {
8086 struct mailers *curmailers = mailers;
8087
8088 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008089 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008090 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008091 }
Simon Horman9dc49962015-01-30 11:22:59 +09008092 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008093 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8094 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008095 free_email_alert(curproxy);
8096 cfgerr++;
8097 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008098 else {
8099 err = NULL;
8100 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008101 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008102 free(err);
8103 cfgerr++;
8104 }
8105 }
Simon Horman9dc49962015-01-30 11:22:59 +09008106 }
8107
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008108 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008109 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008110 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008111 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8112 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008113 cfgerr++;
8114 goto out_uri_auth_compat;
8115 }
8116
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008117 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008118 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008119 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008120 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008121
Willy Tarreau95fa4692010-02-01 13:05:50 +01008122 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8123 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008124
8125 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008126 uri_auth_compat_req[i++] = "realm";
8127 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8128 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008129
Willy Tarreau95fa4692010-02-01 13:05:50 +01008130 uri_auth_compat_req[i++] = "unless";
8131 uri_auth_compat_req[i++] = "{";
8132 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8133 uri_auth_compat_req[i++] = "}";
8134 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008135
Willy Tarreauff011f22011-01-06 17:51:27 +01008136 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8137 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008138 cfgerr++;
8139 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008140 }
8141
Willy Tarreauff011f22011-01-06 17:51:27 +01008142 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008143
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008144 if (curproxy->uri_auth->auth_realm) {
8145 free(curproxy->uri_auth->auth_realm);
8146 curproxy->uri_auth->auth_realm = NULL;
8147 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008148
8149 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008150 }
8151out_uri_auth_compat:
8152
Dragan Dosen43885c72015-10-01 13:18:13 +02008153 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008154 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008155 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8156 if (!curproxy->conf.logformat_sd_string) {
8157 /* set the default logformat_sd_string */
8158 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8159 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008160 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008161 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008162 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008163
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008164 /* compile the log format */
8165 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008166 if (curproxy->conf.logformat_string != default_http_log_format &&
8167 curproxy->conf.logformat_string != default_tcp_log_format &&
8168 curproxy->conf.logformat_string != clf_http_log_format)
8169 free(curproxy->conf.logformat_string);
8170 curproxy->conf.logformat_string = NULL;
8171 free(curproxy->conf.lfs_file);
8172 curproxy->conf.lfs_file = NULL;
8173 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008174
8175 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8176 free(curproxy->conf.logformat_sd_string);
8177 curproxy->conf.logformat_sd_string = NULL;
8178 free(curproxy->conf.lfsd_file);
8179 curproxy->conf.lfsd_file = NULL;
8180 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008181 }
8182
Willy Tarreau62a61232013-04-12 18:13:46 +02008183 if (curproxy->conf.logformat_string) {
8184 curproxy->conf.args.ctx = ARGC_LOG;
8185 curproxy->conf.args.file = curproxy->conf.lfs_file;
8186 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008187 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008188 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008189 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008190 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8191 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008192 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008193 cfgerr++;
8194 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008195 curproxy->conf.args.file = NULL;
8196 curproxy->conf.args.line = 0;
8197 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008198
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008199 if (curproxy->conf.logformat_sd_string) {
8200 curproxy->conf.args.ctx = ARGC_LOGSD;
8201 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8202 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008203 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008204 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 +01008205 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008206 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8207 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008208 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008209 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008210 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &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++;
8215 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008216 curproxy->conf.args.file = NULL;
8217 curproxy->conf.args.line = 0;
8218 }
8219
Willy Tarreau62a61232013-04-12 18:13:46 +02008220 if (curproxy->conf.uniqueid_format_string) {
8221 curproxy->conf.args.ctx = ARGC_UIF;
8222 curproxy->conf.args.file = curproxy->conf.uif_file;
8223 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008224 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008225 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 +01008226 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008227 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8228 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008229 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008230 cfgerr++;
8231 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008232 curproxy->conf.args.file = NULL;
8233 curproxy->conf.args.line = 0;
8234 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008235
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008236 /* only now we can check if some args remain unresolved.
8237 * This must be done after the users and groups resolution.
8238 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008239 cfgerr += smp_resolve_args(curproxy);
8240 if (!cfgerr)
8241 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008242
Willy Tarreau2738a142006-07-08 17:28:09 +02008243 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008244 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008245 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008246 (!curproxy->timeout.connect ||
8247 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008248 ha_warning("config : missing timeouts for %s '%s'.\n"
8249 " | While not properly invalid, you will certainly encounter various problems\n"
8250 " | with such a configuration. To fix this, please ensure that all following\n"
8251 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8252 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008253 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008254 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008255
Willy Tarreau1fa31262007-12-03 00:36:16 +01008256 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8257 * We must still support older configurations, so let's find out whether those
8258 * parameters have been set or must be copied from contimeouts.
8259 */
8260 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008261 if (!curproxy->timeout.tarpit ||
8262 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008263 /* tarpit timeout not set. We search in the following order:
8264 * default.tarpit, curr.connect, default.connect.
8265 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008266 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008267 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008268 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008269 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008270 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008271 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008272 }
8273 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008274 (!curproxy->timeout.queue ||
8275 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008276 /* queue timeout not set. We search in the following order:
8277 * default.queue, curr.connect, default.connect.
8278 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008279 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008280 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008281 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008282 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008283 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008284 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008285 }
8286 }
8287
Willy Tarreau1620ec32011-08-06 17:05:02 +02008288 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008289 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008290 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008291 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008292 }
8293
Willy Tarreau215663d2014-06-13 18:30:23 +02008294 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8295 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008296 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8297 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008298 err_code |= ERR_WARN;
8299 }
8300
Willy Tarreau193b8c62012-11-22 00:17:38 +01008301 /* ensure that cookie capture length is not too large */
8302 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008303 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8304 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008305 err_code |= ERR_WARN;
8306 curproxy->capture_len = global.tune.cookie_len - 1;
8307 }
8308
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008309 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008310 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008311 curproxy->req_cap_pool = create_pool("ptrcap",
8312 curproxy->nb_req_cap * sizeof(char *),
8313 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008314 }
8315
8316 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008317 curproxy->rsp_cap_pool = create_pool("ptrcap",
8318 curproxy->nb_rsp_cap * sizeof(char *),
8319 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008320 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008321
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008322 switch (curproxy->load_server_state_from_file) {
8323 case PR_SRV_STATE_FILE_UNSPEC:
8324 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8325 break;
8326 case PR_SRV_STATE_FILE_GLOBAL:
8327 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008328 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",
8329 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008330 err_code |= ERR_WARN;
8331 }
8332 break;
8333 }
8334
Willy Tarreaubaaee002006-06-26 02:48:02 +02008335 /* first, we will invert the servers list order */
8336 newsrv = NULL;
8337 while (curproxy->srv) {
8338 struct server *next;
8339
8340 next = curproxy->srv->next;
8341 curproxy->srv->next = newsrv;
8342 newsrv = curproxy->srv;
8343 if (!next)
8344 break;
8345 curproxy->srv = next;
8346 }
8347
Willy Tarreau17edc812014-01-03 12:14:34 +01008348 /* Check that no server name conflicts. This causes trouble in the stats.
8349 * We only emit a warning for the first conflict affecting each server,
8350 * in order to avoid combinatory explosion if all servers have the same
8351 * name. We do that only for servers which do not have an explicit ID,
8352 * because these IDs were made also for distinguishing them and we don't
8353 * want to annoy people who correctly manage them.
8354 */
8355 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8356 struct server *other_srv;
8357
8358 if (newsrv->puid)
8359 continue;
8360
8361 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8362 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008363 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",
8364 newsrv->conf.file, newsrv->conf.line,
8365 proxy_type_str(curproxy), curproxy->id,
8366 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008367 break;
8368 }
8369 }
8370 }
8371
Willy Tarreaudd701652010-05-25 23:03:02 +02008372 /* assign automatic UIDs to servers which don't have one yet */
8373 next_id = 1;
8374 newsrv = curproxy->srv;
8375 while (newsrv != NULL) {
8376 if (!newsrv->puid) {
8377 /* server ID not set, use automatic numbering with first
8378 * spare entry starting with next_svid.
8379 */
8380 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8381 newsrv->conf.id.key = newsrv->puid = next_id;
8382 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8383 }
8384 next_id++;
8385 newsrv = newsrv->next;
8386 }
8387
Willy Tarreau20697042007-11-15 23:26:18 +01008388 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008389 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008390
Willy Tarreau62c3be22012-01-20 13:12:32 +01008391 /*
8392 * If this server supports a maxconn parameter, it needs a dedicated
8393 * tasks to fill the emptied slots when a connection leaves.
8394 * Also, resolve deferred tracking dependency if needed.
8395 */
8396 newsrv = curproxy->srv;
8397 while (newsrv != NULL) {
8398 if (newsrv->minconn > newsrv->maxconn) {
8399 /* Only 'minconn' was specified, or it was higher than or equal
8400 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8401 * this will avoid further useless expensive computations.
8402 */
8403 newsrv->maxconn = newsrv->minconn;
8404 } else if (newsrv->maxconn && !newsrv->minconn) {
8405 /* minconn was not specified, so we set it to maxconn */
8406 newsrv->minconn = newsrv->maxconn;
8407 }
8408
Willy Tarreau17d45382016-12-22 21:16:08 +01008409 /* this will also properly set the transport layer for prod and checks */
8410 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8411 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8412 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8413 }
Emeric Brun94324a42012-10-11 14:00:19 +02008414
Willy Tarreau2f075e92013-12-03 11:11:34 +01008415 /* set the check type on the server */
8416 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8417
Willy Tarreau62c3be22012-01-20 13:12:32 +01008418 if (newsrv->trackit) {
8419 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008420 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008421 char *pname, *sname;
8422
8423 pname = newsrv->trackit;
8424 sname = strrchr(pname, '/');
8425
8426 if (sname)
8427 *sname++ = '\0';
8428 else {
8429 sname = pname;
8430 pname = NULL;
8431 }
8432
8433 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008434 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008435 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008436 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8437 proxy_type_str(curproxy), curproxy->id,
8438 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008439 cfgerr++;
8440 goto next_srv;
8441 }
8442 } else
8443 px = curproxy;
8444
8445 srv = findserver(px, sname);
8446 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008447 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8448 proxy_type_str(curproxy), curproxy->id,
8449 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008450 cfgerr++;
8451 goto next_srv;
8452 }
8453
Willy Tarreau32091232014-05-16 13:52:00 +02008454 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8455 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8456 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008457 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8458 "tracking as it does not have any check nor agent enabled.\n",
8459 proxy_type_str(curproxy), curproxy->id,
8460 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008461 cfgerr++;
8462 goto next_srv;
8463 }
8464
8465 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8466
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008467 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008468 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8469 "belongs to a tracking chain looping back to %s/%s.\n",
8470 proxy_type_str(curproxy), curproxy->id,
8471 newsrv->id, px->id, srv->id, px->id,
8472 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008473 cfgerr++;
8474 goto next_srv;
8475 }
8476
8477 if (curproxy != px &&
8478 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008479 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8480 "tracking: disable-on-404 option inconsistency.\n",
8481 proxy_type_str(curproxy), curproxy->id,
8482 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008483 cfgerr++;
8484 goto next_srv;
8485 }
8486
Willy Tarreau62c3be22012-01-20 13:12:32 +01008487 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008488 newsrv->tracknext = srv->trackers;
8489 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008490
8491 free(newsrv->trackit);
8492 newsrv->trackit = NULL;
8493 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008494
Willy Tarreau62c3be22012-01-20 13:12:32 +01008495 next_srv:
8496 newsrv = newsrv->next;
8497 }
8498
Olivier Houchard4e694042017-03-14 20:01:29 +01008499 /*
8500 * Try to generate dynamic cookies for servers now.
8501 * It couldn't be done earlier, since at the time we parsed
8502 * the server line, we may not have known yet that we
8503 * should use dynamic cookies, or the secret key may not
8504 * have been provided yet.
8505 */
8506 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8507 newsrv = curproxy->srv;
8508 while (newsrv != NULL) {
8509 srv_set_dyncookie(newsrv);
8510 newsrv = newsrv->next;
8511 }
8512
8513 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008514 /* We have to initialize the server lookup mechanism depending
8515 * on what LB algorithm was choosen.
8516 */
8517
8518 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8519 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8520 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008521 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8522 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8523 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02008524 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
8525 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8526 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02008527 } else {
8528 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8529 fwrr_init_server_groups(curproxy);
8530 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008531 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008532
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008533 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008534 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8535 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8536 fwlc_init_server_tree(curproxy);
8537 } else {
8538 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8539 fas_init_server_tree(curproxy);
8540 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008541 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008542
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008543 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008544 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8545 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8546 chash_init_server_tree(curproxy);
8547 } else {
8548 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8549 init_server_map(curproxy);
8550 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008551 break;
8552 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008553 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008554
8555 if (curproxy->options & PR_O_LOGASAP)
8556 curproxy->to_log &= ~LW_BYTES;
8557
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008558 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008559 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8560 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008561 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8562 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008563 err_code |= ERR_WARN;
8564 }
8565
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008566 if (curproxy->mode != PR_MODE_HTTP) {
8567 int optnum;
8568
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008569 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008570 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8571 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008572 err_code |= ERR_WARN;
8573 curproxy->uri_auth = NULL;
8574 }
8575
Willy Tarreaude7dc882017-03-10 11:49:21 +01008576 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008577 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8578 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008579 err_code |= ERR_WARN;
8580 }
8581
8582 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008583 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8584 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008585 err_code |= ERR_WARN;
8586 }
8587
8588 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008589 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8590 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008591 err_code |= ERR_WARN;
8592 }
8593
8594 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008595 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8596 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008597 err_code |= ERR_WARN;
8598 }
8599
8600 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008601 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8602 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008603 err_code |= ERR_WARN;
8604 }
8605
Willy Tarreau87cf5142011-08-19 22:57:24 +02008606 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008607 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8608 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008609 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008610 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008611 }
8612
8613 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008614 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8615 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008616 err_code |= ERR_WARN;
8617 curproxy->options &= ~PR_O_ORGTO;
8618 }
8619
8620 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8621 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8622 (curproxy->cap & cfg_opts[optnum].cap) &&
8623 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008624 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8625 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008626 err_code |= ERR_WARN;
8627 curproxy->options &= ~cfg_opts[optnum].val;
8628 }
8629 }
8630
8631 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8632 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8633 (curproxy->cap & cfg_opts2[optnum].cap) &&
8634 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008635 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8636 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008637 err_code |= ERR_WARN;
8638 curproxy->options2 &= ~cfg_opts2[optnum].val;
8639 }
8640 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008641
Willy Tarreau29fbe512015-08-20 19:35:14 +02008642#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008643 if (curproxy->conn_src.bind_hdr_occ) {
8644 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008645 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8646 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008647 err_code |= ERR_WARN;
8648 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008649#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008650 }
8651
Willy Tarreaubaaee002006-06-26 02:48:02 +02008652 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008653 * ensure that we're not cross-dressing a TCP server into HTTP.
8654 */
8655 newsrv = curproxy->srv;
8656 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008657 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008658 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8659 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008660 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008661 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008662
Willy Tarreau0cec3312011-10-31 13:49:26 +01008663 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008664 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8665 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008666 err_code |= ERR_WARN;
8667 }
8668
Willy Tarreauc93cd162014-05-13 15:54:22 +02008669 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008670 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8671 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008672 err_code |= ERR_WARN;
8673 }
8674
Willy Tarreau29fbe512015-08-20 19:35:14 +02008675#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008676 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8677 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008678 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8679 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008680 err_code |= ERR_WARN;
8681 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008682#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008683
Willy Tarreau46deab62018-04-28 07:18:15 +02008684 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
8685 curproxy->options &= ~PR_O_REUSE_MASK;
8686
Willy Tarreau4c183462017-01-06 12:21:38 +01008687 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8688 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8689 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8690 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8691 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008692 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",
8693 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008694 err_code |= ERR_WARN;
8695 }
8696
8697
8698 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008699 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",
8700 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008701 err_code |= ERR_WARN;
8702 }
8703 }
8704
Willy Tarreau21d2af32008-02-14 20:25:24 +01008705 newsrv = newsrv->next;
8706 }
8707
Willy Tarreaue42bd962014-09-16 16:21:19 +02008708 /* check if we have a frontend with "tcp-request content" looking at L7
8709 * with no inspect-delay
8710 */
8711 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008712 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8713 if (arule->action == ACT_TCP_CAPTURE &&
8714 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008715 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008716 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8717 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008718 break;
8719 }
8720
Christopher Faulete4e830d2017-09-18 14:51:41 +02008721 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008722 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8723 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8724 " This means that these rules will randomly find their contents. This can be fixed by"
8725 " setting the tcp-request inspect-delay.\n",
8726 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008727 err_code |= ERR_WARN;
8728 }
8729 }
8730
Christopher Fauletd7c91962015-04-30 11:48:27 +02008731 /* Check filter configuration, if any */
8732 cfgerr += flt_check(curproxy);
8733
Willy Tarreauc1a21672009-08-16 22:37:44 +02008734 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008735 if (!curproxy->accept)
8736 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008737
Willy Tarreauc1a21672009-08-16 22:37:44 +02008738 if (curproxy->tcp_req.inspect_delay ||
8739 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008740 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008741
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008742 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008743 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008744 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008745 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008746
8747 /* both TCP and HTTP must check switching rules */
8748 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008749
8750 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008751 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008752 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8753 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 +01008754 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008755 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8756 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008757 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008758 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008759 }
8760
8761 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008762 if (curproxy->tcp_req.inspect_delay ||
8763 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8764 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8765
Emeric Brun97679e72010-09-23 17:56:44 +02008766 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8767 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8768
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008769 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008770 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008771 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008772 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008773
8774 /* If the backend does requires RDP cookie persistence, we have to
8775 * enable the corresponding analyser.
8776 */
8777 if (curproxy->options2 & PR_O2_RDPC_PRST)
8778 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008779
8780 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008781 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008782 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8783 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 +01008784 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008785 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8786 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008787 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008788 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008789 }
Christopher Fauleta717b992018-04-10 14:43:00 +02008790
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008791 /* Check the mux protocols, if any, for each listener and server
Christopher Fauleta717b992018-04-10 14:43:00 +02008792 * attached to the current proxy */
8793 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8794 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8795
8796 if (!bind_conf->mux_proto)
8797 continue;
8798 if (!(bind_conf->mux_proto->mode & mode)) {
8799 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n",
8800 proxy_type_str(curproxy), curproxy->id,
8801 (int)bind_conf->mux_proto->token.len,
8802 bind_conf->mux_proto->token.ptr,
8803 bind_conf->arg, bind_conf->file, bind_conf->line);
8804 cfgerr++;
8805 }
8806 }
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008807 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8808 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8809
8810 if (!newsrv->mux_proto)
8811 continue;
8812 if (!(newsrv->mux_proto->mode & mode)) {
8813 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n",
8814 proxy_type_str(curproxy), curproxy->id,
8815 (int)newsrv->mux_proto->token.len,
8816 newsrv->mux_proto->token.ptr,
8817 newsrv->id, newsrv->conf.file, newsrv->conf.line);
8818 cfgerr++;
8819 }
8820 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008821 }
8822
8823 /***********************************************************/
8824 /* At this point, target names have already been resolved. */
8825 /***********************************************************/
8826
8827 /* Check multi-process mode compatibility */
8828
8829 if (global.nbproc > 1 && global.stats_fe) {
8830 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8831 unsigned long mask;
8832
8833 mask = nbits(global.nbproc);
8834 if (global.stats_fe->bind_proc)
8835 mask &= global.stats_fe->bind_proc;
8836
8837 if (bind_conf->bind_proc)
8838 mask &= bind_conf->bind_proc;
8839
8840 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008841 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008842 break;
8843 }
8844 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008845 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 +02008846 }
8847 }
8848
8849 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008850 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008851 if (curproxy->bind_proc)
8852 continue;
8853
8854 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8855 unsigned long mask;
8856
Willy Tarreaue428b082015-05-04 21:57:58 +02008857 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008858 curproxy->bind_proc |= mask;
8859 }
8860
8861 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008862 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008863 }
8864
8865 if (global.stats_fe) {
8866 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8867 unsigned long mask;
8868
Cyril Bonté06181952016-02-24 00:14:54 +01008869 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008870 global.stats_fe->bind_proc |= mask;
8871 }
8872 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008873 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008874 }
8875
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008876 /* propagate bindings from frontends to backends. Don't do it if there
8877 * are any fatal errors as we must not call it with unresolved proxies.
8878 */
8879 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008880 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008881 if (curproxy->cap & PR_CAP_FE)
8882 propagate_processes(curproxy, NULL);
8883 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008884 }
8885
8886 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008887 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008888 if (curproxy->bind_proc)
8889 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008890 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008891 }
8892
8893 /*******************************************************/
8894 /* At this step, all proxies have a non-null bind_proc */
8895 /*******************************************************/
8896
8897 /* perform the final checks before creating tasks */
8898
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008899 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008900 struct listener *listener;
8901 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008902
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008903 /* Configure SSL for each bind line.
8904 * Note: if configuration fails at some point, the ->ctx member
8905 * remains NULL so that listeners can later detach.
8906 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008907 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008908 if (bind_conf->xprt->prepare_bind_conf &&
8909 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008910 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008911 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008912
Willy Tarreaue6b98942007-10-29 01:09:36 +01008913 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008914 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008915 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008916 int nbproc;
8917
8918 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008919 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008920 nbits(global.nbproc));
8921
8922 if (!nbproc) /* no intersection between listener and frontend */
8923 nbproc = 1;
8924
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008925 if (!listener->luid) {
8926 /* listener ID not set, use automatic numbering with first
8927 * spare entry starting with next_luid.
8928 */
8929 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8930 listener->conf.id.key = listener->luid = next_id;
8931 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008932 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008933 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008934
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008935 /* enable separate counters */
8936 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008937 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008938 if (!listener->name)
8939 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008940 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008941
Willy Tarreaue6b98942007-10-29 01:09:36 +01008942 if (curproxy->options & PR_O_TCP_NOLING)
8943 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008944 if (!listener->maxconn)
8945 listener->maxconn = curproxy->maxconn;
8946 if (!listener->backlog)
8947 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008948 if (!listener->maxaccept)
8949 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8950
8951 /* we want to have an optimal behaviour on single process mode to
8952 * maximize the work at once, but in multi-process we want to keep
8953 * some fairness between processes, so we target half of the max
8954 * number of events to be balanced over all the processes the proxy
8955 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8956 * used to disable the limit.
8957 */
8958 if (listener->maxaccept > 0) {
8959 if (nbproc > 1)
8960 listener->maxaccept = (listener->maxaccept + 1) / 2;
8961 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8962 }
8963
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008964 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008965 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008966 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008967
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008968 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008969 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008970
Willy Tarreau620408f2016-10-21 16:37:51 +02008971 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8972 listener->options |= LI_O_TCP_L5_RULES;
8973
Willy Tarreaude3041d2010-05-31 10:56:17 +02008974 if (curproxy->mon_mask.s_addr)
8975 listener->options |= LI_O_CHK_MONNET;
8976
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008977 /* smart accept mode is automatic in HTTP mode */
8978 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008979 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008980 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8981 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008982 }
8983
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008984 /* Release unused SSL configs */
8985 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008986 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8987 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008988 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008989
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008990 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008991 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008992 int count, maxproc = 0;
8993
8994 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008995 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008996 if (count > maxproc)
8997 maxproc = count;
8998 }
8999 /* backends have 0, frontends have 1 or more */
9000 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01009001 ha_warning("Proxy '%s': in multi-process mode, stats will be"
9002 " limited to process assigned to the current request.\n",
9003 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02009004
Willy Tarreau102df612014-05-07 23:56:38 +02009005 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009006 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
9007 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009008 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009009 }
Willy Tarreau102df612014-05-07 23:56:38 +02009010 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009011 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
9012 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009013 }
9014 }
Willy Tarreau918ff602011-07-25 16:33:49 +02009015
9016 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02009017 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02009018 if (curproxy->task) {
9019 curproxy->task->context = curproxy;
9020 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02009021 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009022 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
9023 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02009024 cfgerr++;
9025 }
Willy Tarreaub369a042014-09-16 13:21:03 +02009026 }
9027
Willy Tarreaufbb78422011-06-05 15:38:35 +02009028 /* automatically compute fullconn if not set. We must not do it in the
9029 * loop above because cross-references are not yet fully resolved.
9030 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009031 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009032 /* If <fullconn> is not set, let's set it to 10% of the sum of
9033 * the possible incoming frontend's maxconns.
9034 */
9035 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009036 /* we have the sum of the maxconns in <total>. We only
9037 * keep 10% of that sum to set the default fullconn, with
9038 * a hard minimum of 1 (to avoid a divide by zero).
9039 */
Emeric Brun3f783572017-01-12 11:21:28 +01009040 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02009041 if (!curproxy->fullconn)
9042 curproxy->fullconn = 1;
9043 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01009044 }
9045
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009046 /*
9047 * Recount currently required checks.
9048 */
9049
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009050 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009051 int optnum;
9052
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009053 for (optnum = 0; cfg_opts[optnum].name; optnum++)
9054 if (curproxy->options & cfg_opts[optnum].val)
9055 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009056
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009057 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
9058 if (curproxy->options2 & cfg_opts2[optnum].val)
9059 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009060 }
9061
Willy Tarreau0fca4832015-05-01 19:12:05 +02009062 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009063 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02009064 if (curproxy->table.peers.p)
9065 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
9066
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009067 if (cfg_peers) {
9068 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02009069 struct peer *p, *pb;
9070
Willy Tarreau1e273012015-05-01 19:15:17 +02009071 /* Remove all peers sections which don't have a valid listener,
9072 * which are not used by any table, or which are bound to more
9073 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009074 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009075 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009076 while (*last) {
9077 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009078
9079 if (curpeers->state == PR_STSTOPPED) {
9080 /* the "disabled" keyword was present */
9081 if (curpeers->peers_fe)
9082 stop_proxy(curpeers->peers_fe);
9083 curpeers->peers_fe = NULL;
9084 }
9085 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009086 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9087 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009088 }
David Carliere6c39412015-07-02 07:00:17 +00009089 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009090 /* either it's totally stopped or too much used */
9091 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009092 ha_alert("Peers section '%s': peers referenced by sections "
9093 "running in different processes (%d different ones). "
9094 "Check global.nbproc and all tables' bind-process "
9095 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009096 cfgerr++;
9097 }
9098 stop_proxy(curpeers->peers_fe);
9099 curpeers->peers_fe = NULL;
9100 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009101 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009102 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009103 last = &curpeers->next;
9104 continue;
9105 }
9106
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009107 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009108 p = curpeers->remote;
9109 while (p) {
9110 pb = p->next;
9111 free(p->id);
9112 free(p);
9113 p = pb;
9114 }
9115
9116 /* Destroy and unlink this curpeers section.
9117 * Note: curpeers is backed up into *last.
9118 */
9119 free(curpeers->id);
9120 curpeers = curpeers->next;
9121 free(*last);
9122 *last = curpeers;
9123 }
9124 }
9125
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009126 /* initialize stick-tables on backend capable proxies. This must not
9127 * be done earlier because the data size may be discovered while parsing
9128 * other proxies.
9129 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009130 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009131 if (curproxy->state == PR_STSTOPPED)
9132 continue;
9133
9134 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009135 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009136 cfgerr++;
9137 }
9138 }
9139
Simon Horman0d16a402015-01-30 11:22:58 +09009140 if (mailers) {
9141 struct mailers *curmailers = mailers, **last;
9142 struct mailer *m, *mb;
9143
9144 /* Remove all mailers sections which don't have a valid listener.
9145 * This can happen when a mailers section is never referenced.
9146 */
9147 last = &mailers;
9148 while (*last) {
9149 curmailers = *last;
9150 if (curmailers->users) {
9151 last = &curmailers->next;
9152 continue;
9153 }
9154
Christopher Faulet767a84b2017-11-24 16:50:31 +01009155 ha_warning("Removing incomplete section 'mailers %s'.\n",
9156 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009157
9158 m = curmailers->mailer_list;
9159 while (m) {
9160 mb = m->next;
9161 free(m->id);
9162 free(m);
9163 m = mb;
9164 }
9165
9166 /* Destroy and unlink this curmailers section.
9167 * Note: curmailers is backed up into *last.
9168 */
9169 free(curmailers->id);
9170 curmailers = curmailers->next;
9171 free(*last);
9172 *last = curmailers;
9173 }
9174 }
9175
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009176 /* Update server_state_file_name to backend name if backend is supposed to use
9177 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009178 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009179 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9180 curproxy->server_state_file_name == NULL)
9181 curproxy->server_state_file_name = strdup(curproxy->id);
9182 }
9183
Willy Tarreaubafbe012017-11-24 17:34:44 +01009184 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009185 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009186 MEM_F_SHARED);
9187
Ben Draut054fbee2018-04-13 15:43:04 -06009188 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
9189 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
9190 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
9191 curr_resolvers->id, curr_resolvers->conf.file,
9192 curr_resolvers->conf.line);
9193 err_code |= ERR_WARN;
9194 }
9195 }
9196
William Lallemand48b4bb42017-10-23 14:36:34 +02009197 list_for_each_entry(postparser, &postparsers, list) {
9198 if (postparser->func)
9199 cfgerr += postparser->func();
9200 }
9201
Willy Tarreaubb925012009-07-23 13:36:36 +02009202 if (cfgerr > 0)
9203 err_code |= ERR_ALERT | ERR_FATAL;
9204 out:
9205 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009206}
9207
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009208/*
9209 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9210 * parsing sessions.
9211 */
9212void cfg_register_keywords(struct cfg_kw_list *kwl)
9213{
9214 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9215}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009216
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009217/*
9218 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9219 */
9220void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9221{
9222 LIST_DEL(&kwl->list);
9223 LIST_INIT(&kwl->list);
9224}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009225
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009226/* this function register new section in the haproxy configuration file.
9227 * <section_name> is the name of this new section and <section_parser>
9228 * is the called parser. If two section declaration have the same name,
9229 * only the first declared is used.
9230 */
9231int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009232 int (*section_parser)(const char *, int, char **, int),
9233 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009234{
9235 struct cfg_section *cs;
9236
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009237 list_for_each_entry(cs, &sections, list) {
9238 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009239 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009240 return 0;
9241 }
9242 }
9243
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009244 cs = calloc(1, sizeof(*cs));
9245 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009246 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009247 return 0;
9248 }
9249
9250 cs->section_name = section_name;
9251 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009252 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009253
9254 LIST_ADDQ(&sections, &cs->list);
9255
9256 return 1;
9257}
9258
William Lallemand48b4bb42017-10-23 14:36:34 +02009259/* this function register a new function which will be called once the haproxy
9260 * configuration file has been parsed. It's useful to check dependencies
9261 * between sections or to resolve items once everything is parsed.
9262 */
9263int cfg_register_postparser(char *name, int (*func)())
9264{
9265 struct cfg_postparser *cp;
9266
9267 cp = calloc(1, sizeof(*cp));
9268 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009269 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009270 return 0;
9271 }
9272 cp->name = name;
9273 cp->func = func;
9274
9275 LIST_ADDQ(&postparsers, &cp->list);
9276
9277 return 1;
9278}
9279
Willy Tarreaubaaee002006-06-26 02:48:02 +02009280/*
David Carlier845efb52015-09-25 11:49:18 +01009281 * free all config section entries
9282 */
9283void cfg_unregister_sections(void)
9284{
9285 struct cfg_section *cs, *ics;
9286
9287 list_for_each_entry_safe(cs, ics, &sections, list) {
9288 LIST_DEL(&cs->list);
9289 free(cs);
9290 }
9291}
9292
Christopher Faulet7110b402016-10-26 11:09:44 +02009293void cfg_backup_sections(struct list *backup_sections)
9294{
9295 struct cfg_section *cs, *ics;
9296
9297 list_for_each_entry_safe(cs, ics, &sections, list) {
9298 LIST_DEL(&cs->list);
9299 LIST_ADDQ(backup_sections, &cs->list);
9300 }
9301}
9302
9303void cfg_restore_sections(struct list *backup_sections)
9304{
9305 struct cfg_section *cs, *ics;
9306
9307 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9308 LIST_DEL(&cs->list);
9309 LIST_ADDQ(&sections, &cs->list);
9310 }
9311}
9312
Willy Tarreau659fbf02016-05-26 17:55:28 +02009313__attribute__((constructor))
9314static void cfgparse_init(void)
9315{
9316 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009317 cfg_register_section("listen", cfg_parse_listen, NULL);
9318 cfg_register_section("frontend", cfg_parse_listen, NULL);
9319 cfg_register_section("backend", cfg_parse_listen, NULL);
9320 cfg_register_section("defaults", cfg_parse_listen, NULL);
9321 cfg_register_section("global", cfg_parse_global, NULL);
9322 cfg_register_section("userlist", cfg_parse_users, NULL);
9323 cfg_register_section("peers", cfg_parse_peers, NULL);
9324 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9325 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9326 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009327}
9328
David Carlier845efb52015-09-25 11:49:18 +01009329/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009330 * Local variables:
9331 * c-indent-level: 8
9332 * c-basic-offset: 8
9333 * End:
9334 */