blob: b44e6fa8806e5db85406dcbf7ff3ff641d36b872 [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 Tarreau6b2e11b2009-10-01 07:52:15 +020069#include <proto/lb_chash.h>
Willy Tarreauf09c6602012-02-13 17:12:08 +010070#include <proto/lb_fas.h>
Willy Tarreauf89c1872009-10-01 11:19:37 +020071#include <proto/lb_fwlc.h>
72#include <proto/lb_fwrr.h>
73#include <proto/lb_map.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020074#include <proto/listener.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020075#include <proto/log.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020076#include <proto/protocol.h>
Willy Tarreaue6b98942007-10-29 01:09:36 +010077#include <proto/proto_http.h>
Willy Tarreau2b5652f2006-12-31 17:46:05 +010078#include <proto/proxy.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020079#include <proto/peers.h>
Willy Tarreaucd3b0942012-04-27 21:52:18 +020080#include <proto/sample.h>
Willy Tarreau9903f0e2015-04-04 18:50:31 +020081#include <proto/session.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020082#include <proto/server.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020083#include <proto/stream.h>
Emeric Brunb982a3d2010-01-04 15:45:53 +010084#include <proto/stick_table.h>
Willy Tarreau39713102016-11-25 15:49:32 +010085#include <proto/task.h>
86#include <proto/tcp_rules.h>
Olivier Houchard673867c2018-05-25 16:58:52 +020087#include <proto/connection.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020088
89
Willy Tarreauf3c69202006-07-09 16:42:34 +020090/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
91 * ssl-hello-chk option to ensure that the remote server speaks SSL.
92 *
93 * Check RFC 2246 (TLSv1.0) sections A.3 and A.4 for details.
94 */
95const char sslv3_client_hello_pkt[] = {
96 "\x16" /* ContentType : 0x16 = Hanshake */
97 "\x03\x00" /* ProtocolVersion : 0x0300 = SSLv3 */
98 "\x00\x79" /* ContentLength : 0x79 bytes after this one */
99 "\x01" /* HanshakeType : 0x01 = CLIENT HELLO */
100 "\x00\x00\x75" /* HandshakeLength : 0x75 bytes after this one */
101 "\x03\x00" /* Hello Version : 0x0300 = v3 */
102 "\x00\x00\x00\x00" /* Unix GMT Time (s) : filled with <now> (@0x0B) */
103 "HAPROXYSSLCHK\nHAPROXYSSLCHK\n" /* Random : must be exactly 28 bytes */
104 "\x00" /* Session ID length : empty (no session ID) */
105 "\x00\x4E" /* Cipher Suite Length : 78 bytes after this one */
106 "\x00\x01" "\x00\x02" "\x00\x03" "\x00\x04" /* 39 most common ciphers : */
107 "\x00\x05" "\x00\x06" "\x00\x07" "\x00\x08" /* 0x01...0x1B, 0x2F...0x3A */
108 "\x00\x09" "\x00\x0A" "\x00\x0B" "\x00\x0C" /* This covers RSA/DH, */
109 "\x00\x0D" "\x00\x0E" "\x00\x0F" "\x00\x10" /* various bit lengths, */
110 "\x00\x11" "\x00\x12" "\x00\x13" "\x00\x14" /* SHA1/MD5, DES/3DES/AES... */
111 "\x00\x15" "\x00\x16" "\x00\x17" "\x00\x18"
112 "\x00\x19" "\x00\x1A" "\x00\x1B" "\x00\x2F"
113 "\x00\x30" "\x00\x31" "\x00\x32" "\x00\x33"
114 "\x00\x34" "\x00\x35" "\x00\x36" "\x00\x37"
115 "\x00\x38" "\x00\x39" "\x00\x3A"
116 "\x01" /* Compression Length : 0x01 = 1 byte for types */
117 "\x00" /* Compression Type : 0x00 = NULL compression */
118};
119
Willy Tarreau3842f002009-06-14 11:39:52 +0200120/* various keyword modifiers */
121enum kw_mod {
122 KWM_STD = 0, /* normal */
123 KWM_NO, /* "no" prefixed before the keyword */
124 KWM_DEF, /* "default" prefixed before the keyword */
125};
126
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100127/* permit to store configuration section */
128struct cfg_section {
129 struct list list;
130 char *section_name;
131 int (*section_parser)(const char *, int, char **, int);
William Lallemandd2ff56d2017-10-16 11:06:50 +0200132 int (*post_section_parser)();
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100133};
134
135/* Used to chain configuration sections definitions. This list
136 * stores struct cfg_section
137 */
138struct list sections = LIST_HEAD_INIT(sections);
139
William Lallemand48b4bb42017-10-23 14:36:34 +0200140/* store post configuration parsing */
141
142struct cfg_postparser {
143 struct list list;
144 char *name;
145 int (*func)();
146};
147
148struct list postparsers = LIST_HEAD_INIT(postparsers);
149
Willy Tarreau13943ab2006-12-31 00:24:10 +0100150/* some of the most common options which are also the easiest to handle */
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100151struct cfg_opt {
Willy Tarreau13943ab2006-12-31 00:24:10 +0100152 const char *name;
153 unsigned int val;
154 unsigned int cap;
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100155 unsigned int checks;
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100156 unsigned int mode;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100157};
158
159/* proxy->options */
160static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100161{
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100162 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
163 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
164 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
165 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
166 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
167 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100168 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau9fbe18e2015-05-01 22:42:08 +0200169 { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau0f228a02015-05-01 15:37:53 +0200170 { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreau9420b122013-12-15 18:58:25 +0100171 { "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100172 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
173 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
174 { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100175 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100176#ifdef TPROXY
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100177 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100178#else
179 { "transparent", 0, 0, 0, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100180#endif
181
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100182 { NULL, 0, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100183};
184
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100185/* proxy->options2 */
186static const struct cfg_opt cfg_opts2[] =
187{
188#ifdef CONFIG_HAP_LINUX_SPLICE
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100189 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
190 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
191 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100192#else
193 { "splice-request", 0, 0, 0, 0 },
194 { "splice-response", 0, 0, 0, 0 },
195 { "splice-auto", 0, 0, 0, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100196#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100197 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
198 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
199 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
200 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
201 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0, 0 },
202 { "socket-stats", PR_O2_SOCKSTAT, PR_CAP_FE, 0, 0 },
203 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0, 0 },
204 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0, 0 },
205 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Jamie Gloudon801a0a32012-08-25 00:18:33 -0400206 { "independent-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100207 { "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreaue52564c2010-04-27 22:19:14 +0200208 { "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau96e31212011-05-30 18:10:30 +0200209 { "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100210 { NULL, 0, 0, 0 }
211};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200212
Willy Tarreau6daf3432008-01-22 16:44:08 +0100213static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200214static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
215int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100216int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100217char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200218
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200219/* List head of all known configuration keywords */
220static struct cfg_kw_list cfg_keywords = {
221 .list = LIST_HEAD_INIT(cfg_keywords.list)
222};
223
Willy Tarreaubaaee002006-06-26 02:48:02 +0200224/*
225 * converts <str> to a list of listeners which are dynamically allocated.
226 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
227 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
228 * - <port> is a numerical port from 1 to 65535 ;
229 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
230 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200231 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
232 * not NULL, it must be a valid pointer to either NULL or a freeable area that
233 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200234 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200235int 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 +0200236{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100237 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200238 int port, end;
239
240 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200241
Willy Tarreaubaaee002006-06-26 02:48:02 +0200242 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100243 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200244 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100245 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200246
247 str = next;
248 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100249 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200250 *next++ = 0;
251 }
252
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100253 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200254 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200255 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100256 if (!ss2)
257 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200258
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100259 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100260 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200261 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100262 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200263 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200264
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100265 if (!port || !end) {
266 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
267 goto fail;
268 }
269
Emeric Bruned760922010-10-22 17:59:25 +0200270 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200271 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200272 goto fail;
273 }
274
275 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200276 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200277 goto fail;
278 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200279 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100280 else if (ss2->ss_family == AF_UNSPEC) {
281 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100282 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100283
284 /* We want to attach to an already bound fd whose number
285 * is in the addr part of ss2 when cast to sockaddr_in.
286 * Note that by definition there is a single listener.
287 * We still have to determine the address family to
288 * register the correct protocol.
289 */
290 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
291 addr_len = sizeof(*ss2);
292 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
293 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
294 goto fail;
295 }
296
297 port = end = get_host_port(ss2);
298 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200299
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100300 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100301 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200302 memprintf(err, "%s for address '%s'.\n", *err, str);
303 goto fail;
304 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200305 } /* end while(next) */
306 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200307 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200308 fail:
309 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200310 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200311}
312
William Lallemand6e62fb62015-04-28 16:55:23 +0200313/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100314 * Report an error in <msg> when there are too many arguments. This version is
315 * intended to be used by keyword parsers so that the message will be included
316 * into the general error message. The index is the current keyword in args.
317 * Return 0 if the number of argument is correct, otherwise build a message and
318 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
319 * message may also be null, it will simply not be produced (useful to check only).
320 * <msg> and <err_code> are only affected on error.
321 */
322int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
323{
324 int i;
325
326 if (!*args[index + maxarg + 1])
327 return 0;
328
329 if (msg) {
330 *msg = NULL;
331 memprintf(msg, "%s", args[0]);
332 for (i = 1; i <= index; i++)
333 memprintf(msg, "%s %s", *msg, args[i]);
334
335 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
336 }
337 if (err_code)
338 *err_code |= ERR_ALERT | ERR_FATAL;
339
340 return 1;
341}
342
343/*
344 * same as too_many_args_idx with a 0 index
345 */
346int too_many_args(int maxarg, char **args, char **msg, int *err_code)
347{
348 return too_many_args_idx(maxarg, 0, args, msg, err_code);
349}
350
351/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200352 * Report a fatal Alert when there is too much arguments
353 * The index is the current keyword in args
354 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
355 * Fill err_code with an ERR_ALERT and an ERR_FATAL
356 */
357int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
358{
359 char *kw = NULL;
360 int i;
361
362 if (!*args[index + maxarg + 1])
363 return 0;
364
365 memprintf(&kw, "%s", args[0]);
366 for (i = 1; i <= index; i++) {
367 memprintf(&kw, "%s %s", kw, args[i]);
368 }
369
Christopher Faulet767a84b2017-11-24 16:50:31 +0100370 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 +0200371 free(kw);
372 *err_code |= ERR_ALERT | ERR_FATAL;
373 return 1;
374}
375
376/*
377 * same as alertif_too_many_args_idx with a 0 index
378 */
379int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
380{
381 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
382}
383
Willy Tarreau620408f2016-10-21 16:37:51 +0200384/* Report a warning if a rule is placed after a 'tcp-request session' rule.
385 * Return 1 if the warning has been emitted, otherwise 0.
386 */
387int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
388{
389 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100390 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
391 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200392 return 1;
393 }
394 return 0;
395}
396
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200397/* Report a warning if a rule is placed after a 'tcp-request content' rule.
398 * Return 1 if the warning has been emitted, otherwise 0.
399 */
400int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
401{
402 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100403 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
404 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200405 return 1;
406 }
407 return 0;
408}
409
Willy Tarreau721d8e02017-12-01 18:25:08 +0100410/* Report a warning if a rule is placed after a 'monitor fail' rule.
411 * Return 1 if the warning has been emitted, otherwise 0.
412 */
413int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
414{
415 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
416 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
417 file, line, arg);
418 return 1;
419 }
420 return 0;
421}
422
Willy Tarreau61d18892009-03-31 10:49:21 +0200423/* Report a warning if a rule is placed after a 'block' rule.
424 * Return 1 if the warning has been emitted, otherwise 0.
425 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100426int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200427{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200428 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100429 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
430 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200431 return 1;
432 }
433 return 0;
434}
435
Willy Tarreau5002f572014-04-23 01:32:02 +0200436/* Report a warning if a rule is placed after an 'http_request' rule.
437 * Return 1 if the warning has been emitted, otherwise 0.
438 */
439int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
440{
441 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100442 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
443 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200444 return 1;
445 }
446 return 0;
447}
448
Willy Tarreau61d18892009-03-31 10:49:21 +0200449/* Report a warning if a rule is placed after a reqrewrite rule.
450 * Return 1 if the warning has been emitted, otherwise 0.
451 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100452int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200453{
454 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100455 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
456 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200457 return 1;
458 }
459 return 0;
460}
461
462/* Report a warning if a rule is placed after a reqadd rule.
463 * Return 1 if the warning has been emitted, otherwise 0.
464 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100465int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200466{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100467 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100468 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
469 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200470 return 1;
471 }
472 return 0;
473}
474
475/* Report a warning if a rule is placed after a redirect rule.
476 * Return 1 if the warning has been emitted, otherwise 0.
477 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100478int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200479{
480 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100481 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
482 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200483 return 1;
484 }
485 return 0;
486}
487
488/* Report a warning if a rule is placed after a 'use_backend' rule.
489 * Return 1 if the warning has been emitted, otherwise 0.
490 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100491int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200492{
493 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100494 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
495 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200496 return 1;
497 }
498 return 0;
499}
500
Willy Tarreauee445d92014-04-23 01:39:04 +0200501/* Report a warning if a rule is placed after a 'use-server' rule.
502 * Return 1 if the warning has been emitted, otherwise 0.
503 */
504int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
505{
506 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100507 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
508 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200509 return 1;
510 }
511 return 0;
512}
513
Willy Tarreaud39ad442016-11-25 15:16:12 +0100514/* report a warning if a redirect rule is dangerously placed */
515int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200516{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100517 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200518 warnif_rule_after_use_server(proxy, file, line, arg);
519}
520
Willy Tarreaud39ad442016-11-25 15:16:12 +0100521/* report a warning if a reqadd rule is dangerously placed */
522int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200523{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100524 return warnif_rule_after_redirect(proxy, file, line, arg) ||
525 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200526}
527
Willy Tarreaud39ad442016-11-25 15:16:12 +0100528/* report a warning if a reqxxx rule is dangerously placed */
529int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200530{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100531 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
532 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200533}
534
535/* report a warning if an http-request rule is dangerously placed */
536int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
537{
Willy Tarreau61d18892009-03-31 10:49:21 +0200538 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100539 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200540}
541
Willy Tarreaud39ad442016-11-25 15:16:12 +0100542/* report a warning if a block rule is dangerously placed */
543int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200544{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100545 return warnif_rule_after_http_req(proxy, file, line, arg) ||
546 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200547}
548
Willy Tarreau721d8e02017-12-01 18:25:08 +0100549/* report a warning if a block rule is dangerously placed */
550int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200551{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100552 return warnif_rule_after_block(proxy, file, line, arg) ||
553 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200554}
555
Willy Tarreau721d8e02017-12-01 18:25:08 +0100556/* report a warning if a "tcp request content" rule is dangerously placed */
557int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
558{
559 return warnif_rule_after_monitor(proxy, file, line, arg) ||
560 warnif_misplaced_monitor(proxy, file, line, arg);
561}
562
Willy Tarreaud39ad442016-11-25 15:16:12 +0100563/* report a warning if a "tcp request session" rule is dangerously placed */
564int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200565{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100566 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
567 warnif_misplaced_tcp_cont(proxy, file, line, arg);
568}
569
570/* report a warning if a "tcp request connection" rule is dangerously placed */
571int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
572{
573 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
574 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200575}
576
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100577/* Report it if a request ACL condition uses some keywords that are incompatible
578 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
579 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
580 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100581 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100582static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100583{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100584 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200585 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100586
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100587 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100588 return 0;
589
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100590 acl = acl_cond_conflicts(cond, where);
591 if (acl) {
592 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100593 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
594 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100595 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100596 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
597 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100598 return ERR_WARN;
599 }
600 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100601 return 0;
602
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100603 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100604 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
605 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100606 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100607 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
608 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100609 return ERR_WARN;
610}
611
Christopher Faulet62519022017-10-16 15:49:32 +0200612/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100613 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100614 * two such numbers delimited by a dash ('-'). On success, it returns
615 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200616 *
617 * Note: this function can also be used to parse a thread number or a set of
618 * threads.
619 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100620int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200621{
Christopher Faulet26028f62017-11-22 15:01:51 +0100622 if (autoinc) {
623 *autoinc = 0;
624 if (strncmp(arg, "auto:", 5) == 0) {
625 arg += 5;
626 *autoinc = 1;
627 }
628 }
629
Christopher Faulet62519022017-10-16 15:49:32 +0200630 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100631 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200632 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100633 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200634 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100635 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200636 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100637 char *dash;
638 unsigned int low, high;
639
Christopher Faulet5ab51772017-11-22 11:21:58 +0100640 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100641 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100642 return -1;
643 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100644
645 low = high = str2uic(arg);
646 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100647 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
648
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100649 if (high < low) {
650 unsigned int swap = low;
651 low = high;
652 high = swap;
653 }
654
Christopher Faulet5ab51772017-11-22 11:21:58 +0100655 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100656 memprintf(err, "'%s' is not a valid number/range."
657 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100658 arg, LONGBITS);
659 return 1;
660 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100661
662 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100663 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200664 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100665
Christopher Faulet5ab51772017-11-22 11:21:58 +0100666 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200667}
668
David Carlier7e351ee2017-12-01 09:14:02 +0000669#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200670/* Parse cpu sets. Each CPU set is either a unique number between 0 and
671 * <LONGBITS> or a range with two such numbers delimited by a dash
672 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
673 * returns 0. otherwise it returns 1 with an error message in <err>.
674 */
675static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
676{
677 int cur_arg = 0;
678
679 *cpu_set = 0;
680 while (*args[cur_arg]) {
681 char *dash;
682 unsigned int low, high;
683
684 if (!isdigit((int)*args[cur_arg])) {
685 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
686 return -1;
687 }
688
689 low = high = str2uic(args[cur_arg]);
690 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100691 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200692
693 if (high < low) {
694 unsigned int swap = low;
695 low = high;
696 high = swap;
697 }
698
699 if (high >= LONGBITS) {
700 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
701 return 1;
702 }
703
704 while (low <= high)
705 *cpu_set |= 1UL << low++;
706
707 cur_arg++;
708 }
709 return 0;
710}
David Carlier7e351ee2017-12-01 09:14:02 +0000711#endif
712
Willy Tarreaubaaee002006-06-26 02:48:02 +0200713/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200714 * parse a line in a <global> section. Returns the error code, 0 if OK, or
715 * any combination of :
716 * - ERR_ABORT: must abort ASAP
717 * - ERR_FATAL: we can continue parsing but not start the service
718 * - ERR_WARN: a warning has been emitted
719 * - ERR_ALERT: an alert has been emitted
720 * Only the two first ones can stop processing, the two others are just
721 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200722 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200723int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200724{
Willy Tarreau058e9072009-07-20 09:30:05 +0200725 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200726 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200727
728 if (!strcmp(args[0], "global")) { /* new section */
729 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200730 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200731 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200732 }
733 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200734 if (alertif_too_many_args(0, file, linenum, args, &err_code))
735 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200736 global.mode |= MODE_DAEMON;
737 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200738 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200739 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200740 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200741 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100742 if (!strcmp(args[1], "no-exit-on-failure")) {
743 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200744 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100745 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 +0200746 err_code |= ERR_ALERT | ERR_FATAL;
747 goto out;
748 }
749 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200750 global.mode |= MODE_MWORKER;
751 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200752 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200753 if (alertif_too_many_args(0, file, linenum, args, &err_code))
754 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200755 global.mode |= MODE_DEBUG;
756 }
757 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200758 if (alertif_too_many_args(0, file, linenum, args, &err_code))
759 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100760 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200761 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200762 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200763 if (alertif_too_many_args(0, file, linenum, args, &err_code))
764 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100765 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200766 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200767 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200768 if (alertif_too_many_args(0, file, linenum, args, &err_code))
769 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100770 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200771 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100772 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200773 if (alertif_too_many_args(0, file, linenum, args, &err_code))
774 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100775 global.tune.options &= ~GTUNE_USE_SPLICE;
776 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200777 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200778 if (alertif_too_many_args(0, file, linenum, args, &err_code))
779 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200780 global.tune.options &= ~GTUNE_USE_GAI;
781 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000782 else if (!strcmp(args[0], "noreuseport")) {
783 if (alertif_too_many_args(0, file, linenum, args, &err_code))
784 goto out;
785 global.tune.options &= ~GTUNE_USE_REUSEPORT;
786 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200787 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200788 if (alertif_too_many_args(0, file, linenum, args, &err_code))
789 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200790 global.mode |= MODE_QUIET;
791 }
Olivier Houchard1599b802018-05-24 18:59:04 +0200792 else if (!strcmp(args[0], "tune.runqueue-depth")) {
793 if (alertif_too_many_args(1, file, linenum, args, &err_code))
794 goto out;
795 if (global.tune.runqueue_depth != 0) {
796 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
797 err_code |= ERR_ALERT;
798 goto out;
799 }
800 if (*(args[1]) == 0) {
801 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
802 err_code |= ERR_ALERT | ERR_FATAL;
803 goto out;
804 }
805 global.tune.runqueue_depth = atol(args[1]);
806
807 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200808 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200809 if (alertif_too_many_args(1, file, linenum, args, &err_code))
810 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200811 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100812 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200813 err_code |= ERR_ALERT;
814 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200815 }
816 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100817 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200818 err_code |= ERR_ALERT | ERR_FATAL;
819 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200820 }
821 global.tune.maxpollevents = atol(args[1]);
822 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100823 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200824 if (alertif_too_many_args(1, file, linenum, args, &err_code))
825 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100826 if (global.tune.maxaccept != 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 Tarreaua0250ba2008-01-06 11:22:57 +0100830 }
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 Tarreaua0250ba2008-01-06 11:22:57 +0100835 }
836 global.tune.maxaccept = atol(args[1]);
837 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200838 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200839 if (alertif_too_many_args(1, file, linenum, args, &err_code))
840 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200841 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100842 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200843 err_code |= ERR_ALERT | ERR_FATAL;
844 goto out;
845 }
846 global.tune.chksize = atol(args[1]);
847 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100848 else if (!strcmp(args[0], "tune.recv_enough")) {
849 if (alertif_too_many_args(1, file, linenum, args, &err_code))
850 goto out;
851 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100852 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100853 err_code |= ERR_ALERT | ERR_FATAL;
854 goto out;
855 }
856 global.tune.recv_enough = atol(args[1]);
857 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100858 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200859 if (alertif_too_many_args(1, file, linenum, args, &err_code))
860 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100861 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100862 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100863 err_code |= ERR_ALERT | ERR_FATAL;
864 goto out;
865 }
866 global.tune.buf_limit = atol(args[1]);
867 if (global.tune.buf_limit) {
868 if (global.tune.buf_limit < 3)
869 global.tune.buf_limit = 3;
870 if (global.tune.buf_limit <= global.tune.reserved_bufs)
871 global.tune.buf_limit = global.tune.reserved_bufs + 1;
872 }
873 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100874 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200875 if (alertif_too_many_args(1, file, linenum, args, &err_code))
876 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100877 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100878 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100879 err_code |= ERR_ALERT | ERR_FATAL;
880 goto out;
881 }
882 global.tune.reserved_bufs = atol(args[1]);
883 if (global.tune.reserved_bufs < 2)
884 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100885 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
886 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100887 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200888 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200889 if (alertif_too_many_args(1, file, linenum, args, &err_code))
890 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200891 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100892 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200893 err_code |= ERR_ALERT | ERR_FATAL;
894 goto out;
895 }
896 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200897 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100898 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200899 err_code |= ERR_ALERT | ERR_FATAL;
900 goto out;
901 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200902 }
903 else if (!strcmp(args[0], "tune.maxrewrite")) {
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.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200912 if (global.tune.maxrewrite < 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 Tarreau27097842015-09-28 13:53:23 +0200914 err_code |= ERR_ALERT | ERR_FATAL;
915 goto out;
916 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200917 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100918 else if (!strcmp(args[0], "tune.idletimer")) {
919 unsigned int idle;
920 const char *res;
921
William Lallemand1a748ae2015-05-19 16:37:23 +0200922 if (alertif_too_many_args(1, file, linenum, args, &err_code))
923 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100924 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100925 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 +0100926 err_code |= ERR_ALERT | ERR_FATAL;
927 goto out;
928 }
929
930 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
931 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100932 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100933 file, linenum, *res, args[0]);
934 err_code |= ERR_ALERT | ERR_FATAL;
935 goto out;
936 }
937
938 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100939 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 +0100940 err_code |= ERR_ALERT | ERR_FATAL;
941 goto out;
942 }
943 global.tune.idle_timer = idle;
944 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100945 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200946 if (alertif_too_many_args(1, file, linenum, args, &err_code))
947 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100948 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100949 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100950 err_code |= ERR_ALERT;
951 goto out;
952 }
953 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100954 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100955 err_code |= ERR_ALERT | ERR_FATAL;
956 goto out;
957 }
958 global.tune.client_rcvbuf = atol(args[1]);
959 }
960 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
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.server_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.server_rcvbuf = atol(args[1]);
974 }
975 else if (!strcmp(args[0], "tune.sndbuf.client")) {
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.client_sndbuf != 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.client_sndbuf = atol(args[1]);
989 }
990 else if (!strcmp(args[0], "tune.sndbuf.server")) {
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.server_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.server_sndbuf = atol(args[1]);
1004 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001005 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001006 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1007 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001008 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001009 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001010 err_code |= ERR_ALERT | ERR_FATAL;
1011 goto out;
1012 }
1013 global.tune.pipesize = atol(args[1]);
1014 }
Willy Tarreau193b8c62012-11-22 00:17:38 +01001015 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001016 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1017 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001018 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001019 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001020 err_code |= ERR_ALERT | ERR_FATAL;
1021 goto out;
1022 }
1023 global.tune.cookie_len = atol(args[1]) + 1;
1024 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001025 else if (!strcmp(args[0], "tune.http.logurilen")) {
1026 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1027 goto out;
1028 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001029 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001030 err_code |= ERR_ALERT | ERR_FATAL;
1031 goto out;
1032 }
1033 global.tune.requri_len = atol(args[1]) + 1;
1034 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001035 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001036 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1037 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001038 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001039 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001040 err_code |= ERR_ALERT | ERR_FATAL;
1041 goto out;
1042 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001043 global.tune.max_http_hdr = atoi(args[1]);
1044 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001045 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1046 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001047 err_code |= ERR_ALERT | ERR_FATAL;
1048 goto out;
1049 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001050 }
William Lallemandf3747832012-11-09 12:33:10 +01001051 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001052 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1053 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001054 if (*args[1]) {
1055 global.tune.comp_maxlevel = atoi(args[1]);
1056 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001057 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1058 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001059 err_code |= ERR_ALERT | ERR_FATAL;
1060 goto out;
1061 }
1062 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001063 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1064 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001065 err_code |= ERR_ALERT | ERR_FATAL;
1066 goto out;
1067 }
1068 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001069 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1070 if (*args[1]) {
1071 global.tune.pattern_cache = atoi(args[1]);
1072 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001073 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1074 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001075 err_code |= ERR_ALERT | ERR_FATAL;
1076 goto out;
1077 }
1078 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001079 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1080 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001081 err_code |= ERR_ALERT | ERR_FATAL;
1082 goto out;
1083 }
1084 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001085 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001086 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1087 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001088 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001089 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001090 err_code |= ERR_ALERT;
1091 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001092 }
1093 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001094 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001095 err_code |= ERR_ALERT | ERR_FATAL;
1096 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001097 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001098 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001099 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 +01001100 err_code |= ERR_WARN;
1101 goto out;
1102 }
1103
Willy Tarreaubaaee002006-06-26 02:48:02 +02001104 }
1105 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001106 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1107 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001108 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001109 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001110 err_code |= ERR_ALERT;
1111 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001112 }
1113 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001114 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001115 err_code |= ERR_ALERT | ERR_FATAL;
1116 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001117 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001118 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001119 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 +01001120 err_code |= ERR_WARN;
1121 goto out;
1122 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001123 }
Simon Horman98637e52014-06-20 12:30:16 +09001124 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001125 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1126 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001127 global.external_check = 1;
1128 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001129 /* user/group name handling */
1130 else if (!strcmp(args[0], "user")) {
1131 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001132 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1133 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001134 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001135 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001136 err_code |= ERR_ALERT;
1137 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001138 }
1139 errno = 0;
1140 ha_user = getpwnam(args[1]);
1141 if (ha_user != NULL) {
1142 global.uid = (int)ha_user->pw_uid;
1143 }
1144 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001145 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 +02001146 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001147 }
1148 }
1149 else if (!strcmp(args[0], "group")) {
1150 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001151 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1152 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001153 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001154 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001155 err_code |= ERR_ALERT;
1156 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001157 }
1158 errno = 0;
1159 ha_group = getgrnam(args[1]);
1160 if (ha_group != NULL) {
1161 global.gid = (int)ha_group->gr_gid;
1162 }
1163 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001164 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 +02001165 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001166 }
1167 }
1168 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001169 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001170 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1171 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001172 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001173 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001174 err_code |= ERR_ALERT | ERR_FATAL;
1175 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001176 }
1177 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001178 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1180 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001181 err_code |= ERR_ALERT | ERR_FATAL;
1182 goto out;
1183 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001184 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001185 else if (!strcmp(args[0], "nbthread")) {
1186 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1187 goto out;
1188 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001189 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001190 err_code |= ERR_ALERT | ERR_FATAL;
1191 goto out;
1192 }
1193 global.nbthread = atol(args[1]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001194#ifndef USE_THREAD
1195 if (global.nbthread > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001196 ha_alert("HAProxy is not compiled with threads support, please check build options for USE_THREAD.\n");
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001197 global.nbthread = 1;
1198 err_code |= ERR_ALERT | ERR_FATAL;
1199 goto out;
1200 }
1201#endif
Willy Tarreau421f02e2018-01-20 18:19:22 +01001202 if (global.nbthread < 1 || global.nbthread > MAX_THREADS) {
1203 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1204 file, linenum, args[0], MAX_THREADS, global.nbthread);
1205 err_code |= ERR_ALERT | ERR_FATAL;
1206 goto out;
1207 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001208 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001209 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001210 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1211 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001212 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001213 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001214 err_code |= ERR_ALERT;
1215 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001216 }
1217 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001218 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001219 err_code |= ERR_ALERT | ERR_FATAL;
1220 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001221 }
1222 global.maxconn = atol(args[1]);
1223#ifdef SYSTEM_MAXCONN
1224 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001225 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 +02001226 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001227 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001228 }
1229#endif /* SYSTEM_MAXCONN */
1230 }
Emeric Brun850efd52014-01-29 12:24:34 +01001231 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001232 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1233 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001234 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001235 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001236 err_code |= ERR_ALERT | ERR_FATAL;
1237 goto out;
1238 }
1239 if (strcmp(args[1],"none") == 0)
1240 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1241 else if (strcmp(args[1],"required") == 0)
1242 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1243 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001244 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001245 err_code |= ERR_ALERT | ERR_FATAL;
1246 goto out;
1247 }
1248 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001249 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001250 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1251 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001252 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001253 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001254 err_code |= ERR_ALERT;
1255 goto out;
1256 }
1257 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001258 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001259 err_code |= ERR_ALERT | ERR_FATAL;
1260 goto out;
1261 }
1262 global.cps_lim = atol(args[1]);
1263 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001264 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001265 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1266 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001267 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001268 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001269 err_code |= ERR_ALERT;
1270 goto out;
1271 }
1272 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001273 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001274 err_code |= ERR_ALERT | ERR_FATAL;
1275 goto out;
1276 }
1277 global.sps_lim = atol(args[1]);
1278 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001279 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001280 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1281 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001282 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001283 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001284 err_code |= ERR_ALERT;
1285 goto out;
1286 }
1287 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001288 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001289 err_code |= ERR_ALERT | ERR_FATAL;
1290 goto out;
1291 }
1292 global.ssl_lim = atol(args[1]);
1293 }
William Lallemandd85f9172012-11-09 17:05:39 +01001294 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001295 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1296 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001297 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001298 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 +01001299 err_code |= ERR_ALERT | ERR_FATAL;
1300 goto out;
1301 }
1302 global.comp_rate_lim = atoi(args[1]) * 1024;
1303 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001304 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001305 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1306 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001307 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001308 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001309 err_code |= ERR_ALERT;
1310 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001311 }
1312 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001313 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001314 err_code |= ERR_ALERT | ERR_FATAL;
1315 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001316 }
1317 global.maxpipes = atol(args[1]);
1318 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001319 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001320 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1321 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001322 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001323 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001324 err_code |= ERR_ALERT | ERR_FATAL;
1325 goto out;
1326 }
William Lallemande3a7d992012-11-20 11:25:20 +01001327 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001328 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001329 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001330 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1331 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001332 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001333 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 +01001334 err_code |= ERR_ALERT | ERR_FATAL;
1335 goto out;
1336 }
1337 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001338 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001339 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 +01001340 err_code |= ERR_ALERT | ERR_FATAL;
1341 goto out;
1342 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001343 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001344
Willy Tarreaubaaee002006-06-26 02:48:02 +02001345 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001346 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1347 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001348 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001349 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001350 err_code |= ERR_ALERT;
1351 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001352 }
1353 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001354 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001355 err_code |= ERR_ALERT | ERR_FATAL;
1356 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001357 }
1358 global.rlimit_nofile = atol(args[1]);
1359 }
1360 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001361 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1362 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001363 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001364 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001365 err_code |= ERR_ALERT;
1366 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001367 }
1368 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001369 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001370 err_code |= ERR_ALERT | ERR_FATAL;
1371 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001372 }
1373 global.chroot = strdup(args[1]);
1374 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001375 else if (!strcmp(args[0], "description")) {
1376 int i, len=0;
1377 char *d;
1378
1379 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001380 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1381 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001382 err_code |= ERR_ALERT | ERR_FATAL;
1383 goto out;
1384 }
1385
Willy Tarreau348acfe2014-04-14 15:00:39 +02001386 for (i = 1; *args[i]; i++)
1387 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001388
1389 if (global.desc)
1390 free(global.desc);
1391
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001392 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001393
Willy Tarreau348acfe2014-04-14 15:00:39 +02001394 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1395 for (i = 2; *args[i]; i++)
1396 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001397 }
1398 else if (!strcmp(args[0], "node")) {
1399 int i;
1400 char c;
1401
William Lallemand1a748ae2015-05-19 16:37:23 +02001402 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1403 goto out;
1404
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001405 for (i=0; args[1][i]; i++) {
1406 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001407 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1408 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001409 break;
1410 }
1411
1412 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001413 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1414 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1415 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001416 err_code |= ERR_ALERT | ERR_FATAL;
1417 goto out;
1418 }
1419
1420 if (global.node)
1421 free(global.node);
1422
1423 global.node = strdup(args[1]);
1424 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001425 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001426 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1427 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001428 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001429 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001430 err_code |= ERR_ALERT;
1431 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001432 }
1433 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001434 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 +02001435 err_code |= ERR_ALERT | ERR_FATAL;
1436 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001437 }
1438 global.pidfile = strdup(args[1]);
1439 }
Emeric Bruned760922010-10-22 17:59:25 +02001440 else if (!strcmp(args[0], "unix-bind")) {
1441 int cur_arg = 1;
1442 while (*(args[cur_arg])) {
1443 if (!strcmp(args[cur_arg], "prefix")) {
1444 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001445 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001446 err_code |= ERR_ALERT;
1447 cur_arg += 2;
1448 continue;
1449 }
1450
1451 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001452 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 +02001453 err_code |= ERR_ALERT | ERR_FATAL;
1454 goto out;
1455 }
1456 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1457 cur_arg += 2;
1458 continue;
1459 }
1460
1461 if (!strcmp(args[cur_arg], "mode")) {
1462
1463 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1464 cur_arg += 2;
1465 continue;
1466 }
1467
1468 if (!strcmp(args[cur_arg], "uid")) {
1469
1470 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1471 cur_arg += 2;
1472 continue;
1473 }
1474
1475 if (!strcmp(args[cur_arg], "gid")) {
1476
1477 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1478 cur_arg += 2;
1479 continue;
1480 }
1481
1482 if (!strcmp(args[cur_arg], "user")) {
1483 struct passwd *user;
1484
1485 user = getpwnam(args[cur_arg + 1]);
1486 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001487 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1488 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001489 err_code |= ERR_ALERT | ERR_FATAL;
1490 goto out;
1491 }
1492
1493 global.unix_bind.ux.uid = user->pw_uid;
1494 cur_arg += 2;
1495 continue;
1496 }
1497
1498 if (!strcmp(args[cur_arg], "group")) {
1499 struct group *group;
1500
1501 group = getgrnam(args[cur_arg + 1]);
1502 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001503 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1504 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001505 err_code |= ERR_ALERT | ERR_FATAL;
1506 goto out;
1507 }
1508
1509 global.unix_bind.ux.gid = group->gr_gid;
1510 cur_arg += 2;
1511 continue;
1512 }
1513
Christopher Faulet767a84b2017-11-24 16:50:31 +01001514 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1515 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001516 err_code |= ERR_ALERT | ERR_FATAL;
1517 goto out;
1518 }
1519 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001520 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1521 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1522 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001523 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001524 goto out;
1525 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001526 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001527 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1528 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001529
1530 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001531 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001532 err_code |= ERR_ALERT;
1533 goto out;
1534 }
1535
1536 if (*(args[1]))
1537 name = args[1];
1538 else
1539 name = hostname;
1540
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001541 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001542 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001543 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001544 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1545 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001546 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001547 err_code |= ERR_ALERT;
1548 goto out;
1549 }
1550
1551 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001552 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001553 err_code |= ERR_FATAL;
1554 goto out;
1555 }
1556
1557 global.server_state_base = strdup(args[1]);
1558 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001559 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1560 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001561 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001562 err_code |= ERR_ALERT;
1563 goto out;
1564 }
1565
1566 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001567 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001568 err_code |= ERR_FATAL;
1569 goto out;
1570 }
1571
1572 global.server_state_file = strdup(args[1]);
1573 }
Kevinm48936af2010-12-22 16:08:21 +00001574 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001575 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1576 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001577 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001578 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001579 err_code |= ERR_ALERT | ERR_FATAL;
1580 goto out;
1581 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001582 chunk_destroy(&global.log_tag);
1583 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001584 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001585 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001586 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1587 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001588 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001589 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001590 err_code |= ERR_ALERT;
1591 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001592 }
1593 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001594 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001595 err_code |= ERR_ALERT | ERR_FATAL;
1596 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001597 }
1598 global.spread_checks = atol(args[1]);
1599 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001600 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 +02001601 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001602 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001603 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001604 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1605 const char *err;
1606 unsigned int val;
1607
William Lallemand1a748ae2015-05-19 16:37:23 +02001608 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1609 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001610 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001611 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001612 err_code |= ERR_ALERT | ERR_FATAL;
1613 goto out;
1614 }
1615
1616 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1617 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001618 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 +02001619 err_code |= ERR_ALERT | ERR_FATAL;
1620 }
1621 global.max_spread_checks = val;
1622 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001623 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001624 err_code |= ERR_ALERT | ERR_FATAL;
1625 }
1626 }
Christopher Faulet62519022017-10-16 15:49:32 +02001627 else if (strcmp(args[0], "cpu-map") == 0) {
1628 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001629#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001630 char *slash;
1631 unsigned long proc = 0, thread = 0, cpus;
1632 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001633
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001634 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001635 ha_alert("parsing [%s:%d] : %s expects a process number "
1636 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1637 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1638 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001639 err_code |= ERR_ALERT | ERR_FATAL;
1640 goto out;
1641 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001642
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001643 if ((slash = strchr(args[1], '/')) != NULL)
1644 *slash = 0;
1645
Christopher Faulet26028f62017-11-22 15:01:51 +01001646 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001647 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001648 err_code |= ERR_ALERT | ERR_FATAL;
1649 goto out;
1650 }
1651
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001652 if (slash) {
1653 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001654 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001655 err_code |= ERR_ALERT | ERR_FATAL;
1656 goto out;
1657 }
1658 *slash = '/';
1659
1660 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001661 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1662 "a process range _AND_ a thread range\n",
1663 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001664 err_code |= ERR_ALERT | ERR_FATAL;
1665 goto out;
1666 }
1667 }
1668
Christopher Faulet62519022017-10-16 15:49:32 +02001669 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001670 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001671 err_code |= ERR_ALERT | ERR_FATAL;
1672 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001673 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001674
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001675 if (autoinc &&
1676 my_popcountl(proc) != my_popcountl(cpus) &&
1677 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001678 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1679 "must have the same size to be automatically bound\n",
1680 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001681 err_code |= ERR_ALERT | ERR_FATAL;
1682 goto out;
1683 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001684
Christopher Faulet26028f62017-11-22 15:01:51 +01001685 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001686 /* No mapping for this process */
1687 if (!(proc & (1UL << i)))
1688 continue;
1689
1690 /* Mapping at the process level */
1691 if (!thread) {
1692 if (!autoinc)
1693 global.cpu_map.proc[i] = cpus;
1694 else {
1695 n += my_ffsl(cpus >> n);
1696 global.cpu_map.proc[i] = (1UL << (n-1));
1697 }
1698 continue;
1699 }
1700
1701 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001702 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001703 /* Np mapping for this thread */
1704 if (!(thread & (1UL << j)))
1705 continue;
1706
1707 if (!autoinc)
1708 global.cpu_map.thread[i][j] = cpus;
1709 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001710 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001711 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001712 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001713 }
1714 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001715#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001716 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1717 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001718 err_code |= ERR_ALERT | ERR_FATAL;
1719 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001720#endif /* ! USE_CPU_AFFINITY */
1721 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001722 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1723 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1724 goto out;
1725
1726 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001727 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001728 err_code |= ERR_ALERT | ERR_FATAL;
1729 goto out;
1730 }
1731
1732 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1733 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001734 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 +01001735 err_code |= ERR_ALERT | ERR_FATAL;
1736 goto out;
1737 }
1738 }
1739 else if (!strcmp(args[0], "unsetenv")) {
1740 int arg;
1741
1742 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001743 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001744 err_code |= ERR_ALERT | ERR_FATAL;
1745 goto out;
1746 }
1747
1748 for (arg = 1; *args[arg]; arg++) {
1749 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001750 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 +01001751 err_code |= ERR_ALERT | ERR_FATAL;
1752 goto out;
1753 }
1754 }
1755 }
1756 else if (!strcmp(args[0], "resetenv")) {
1757 extern char **environ;
1758 char **env = environ;
1759
1760 /* args contain variable names to keep, one per argument */
1761 while (*env) {
1762 int arg;
1763
1764 /* look for current variable in among all those we want to keep */
1765 for (arg = 1; *args[arg]; arg++) {
1766 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1767 (*env)[strlen(args[arg])] == '=')
1768 break;
1769 }
1770
1771 /* delete this variable */
1772 if (!*args[arg]) {
1773 char *delim = strchr(*env, '=');
1774
1775 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001776 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 +01001777 err_code |= ERR_ALERT | ERR_FATAL;
1778 goto out;
1779 }
1780
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001781 memcpy(trash.area, *env, delim - *env);
1782 trash.area[delim - *env] = 0;
Willy Tarreau1d549722016-02-16 12:41:57 +01001783
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001784 if (unsetenv(trash.area) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001785 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 +01001786 err_code |= ERR_ALERT | ERR_FATAL;
1787 goto out;
1788 }
1789 }
1790 else
1791 env++;
1792 }
1793 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001794 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001795 struct cfg_kw_list *kwl;
1796 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001797 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001798
1799 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1800 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1801 if (kwl->kw[index].section != CFG_GLOBAL)
1802 continue;
1803 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001804 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001805 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001806 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001807 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001808 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001809 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001810 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001811 err_code |= ERR_WARN;
1812 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001813 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001814 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001815 }
1816 }
1817 }
1818
Christopher Faulet767a84b2017-11-24 16:50:31 +01001819 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001820 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001821 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001822
Willy Tarreau058e9072009-07-20 09:30:05 +02001823 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001824 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001825 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001826}
1827
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001828void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001829{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001830 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001831 defproxy.mode = PR_MODE_TCP;
1832 defproxy.state = PR_STNEW;
1833 defproxy.maxconn = cfg_maxpconn;
1834 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001835 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001836 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001837
Simon Horman66183002013-02-23 10:16:43 +09001838 defproxy.defsrv.check.inter = DEF_CHKINTR;
1839 defproxy.defsrv.check.fastinter = 0;
1840 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001841 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1842 defproxy.defsrv.agent.fastinter = 0;
1843 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001844 defproxy.defsrv.check.rise = DEF_RISETIME;
1845 defproxy.defsrv.check.fall = DEF_FALLTIME;
1846 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1847 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001848 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001849 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001850 defproxy.defsrv.maxqueue = 0;
1851 defproxy.defsrv.minconn = 0;
1852 defproxy.defsrv.maxconn = 0;
1853 defproxy.defsrv.slowstart = 0;
1854 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1855 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1856 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001857
1858 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001859 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001860}
1861
Willy Tarreauade5ec42010-01-28 19:33:49 +01001862
Willy Tarreau63af98d2014-05-18 08:11:41 +02001863/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1864 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1865 * ERR_FATAL in case of error.
1866 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001867static int create_cond_regex_rule(const char *file, int line,
1868 struct proxy *px, int dir, int action, int flags,
1869 const char *cmd, const char *reg, const char *repl,
1870 const char **cond_start)
1871{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001872 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001873 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001874 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001875 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001876 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001877 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001878 int cs;
1879 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001880
1881 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001882 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001883 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001884 goto err;
1885 }
1886
1887 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001888 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001889 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001890 goto err;
1891 }
1892
Christopher Faulet898566e2016-10-26 11:06:28 +02001893 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001894 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001895
Willy Tarreau5321c422010-01-28 20:35:13 +01001896 if (cond_start &&
1897 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001898 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001899 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1900 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001901 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001902 goto err;
1903 }
1904 }
1905 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001906 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1907 file, line, cmd, *cond_start);
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
Willy Tarreau63af98d2014-05-18 08:11:41 +02001912 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001913 (dir == SMP_OPT_DIR_REQ) ?
1914 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1915 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1916 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001917
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001918 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001919 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001920 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001921 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001922 goto err;
1923 }
1924
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001925 cs = !(flags & REG_ICASE);
1926 cap = !(flags & REG_NOSUB);
1927 error = NULL;
1928 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001929 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001930 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001931 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001932 goto err;
1933 }
1934
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001935 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001936 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001937 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001938 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1939 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001940 ret_code |= ERR_ALERT | ERR_FATAL;
1941 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001942 }
1943
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001944 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001945 ret_code |= ERR_WARN;
1946
1947 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001948
Willy Tarreau63af98d2014-05-18 08:11:41 +02001949 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001950 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001951 err:
1952 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001953 free(errmsg);
1954 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001955}
1956
Willy Tarreaubaaee002006-06-26 02:48:02 +02001957/*
William Lallemand51097192015-04-14 16:35:22 +02001958 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001959 * Returns the error code, 0 if OK, or any combination of :
1960 * - ERR_ABORT: must abort ASAP
1961 * - ERR_FATAL: we can continue parsing but not start the service
1962 * - ERR_WARN: a warning has been emitted
1963 * - ERR_ALERT: an alert has been emitted
1964 * Only the two first ones can stop processing, the two others are just
1965 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001966 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001967int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1968{
1969 static struct peers *curpeers = NULL;
1970 struct peer *newpeer = NULL;
1971 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001972 struct bind_conf *bind_conf;
1973 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001974 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001975 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001976
1977 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001978 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001979 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001980 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001981 goto out;
1982 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001983
William Lallemand6e62fb62015-04-28 16:55:23 +02001984 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1985 goto out;
1986
Emeric Brun32da3c42010-09-23 18:39:19 +02001987 err = invalid_char(args[1]);
1988 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001989 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1990 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001991 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001992 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02001993 }
1994
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02001995 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02001996 /*
1997 * If there are two proxies with the same name only following
1998 * combinations are allowed:
1999 */
2000 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002001 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2002 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002003 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002004 }
2005 }
2006
Vincent Bernat02779b62016-04-03 13:48:43 +02002007 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002008 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002009 err_code |= ERR_ALERT | ERR_ABORT;
2010 goto out;
2011 }
2012
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002013 curpeers->next = cfg_peers;
2014 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002015 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002016 curpeers->conf.line = linenum;
2017 curpeers->last_change = now.tv_sec;
2018 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002019 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002020 }
2021 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002022 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002023 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002024 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002025
2026 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002027 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2028 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002029 err_code |= ERR_ALERT | ERR_FATAL;
2030 goto out;
2031 }
2032
2033 err = invalid_char(args[1]);
2034 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002035 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2036 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002037 err_code |= ERR_ALERT | ERR_FATAL;
2038 goto out;
2039 }
2040
Vincent Bernat02779b62016-04-03 13:48:43 +02002041 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002042 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002043 err_code |= ERR_ALERT | ERR_ABORT;
2044 goto out;
2045 }
2046
2047 /* the peers are linked backwards first */
2048 curpeers->count++;
2049 newpeer->next = curpeers->remote;
2050 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002051 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002052 newpeer->conf.line = linenum;
2053
2054 newpeer->last_change = now.tv_sec;
2055 newpeer->id = strdup(args[1]);
2056
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002057 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002058 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002059 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002060 err_code |= ERR_ALERT | ERR_FATAL;
2061 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002062 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002063
2064 proto = protocol_by_family(sk->ss_family);
2065 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002066 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2067 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002068 err_code |= ERR_ALERT | ERR_FATAL;
2069 goto out;
2070 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002071
2072 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002073 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2074 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002075 err_code |= ERR_ALERT | ERR_FATAL;
2076 goto out;
2077 }
2078
Willy Tarreau2aa38802013-02-20 19:20:59 +01002079 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002080 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port 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 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002085
Emeric Brun32da3c42010-09-23 18:39:19 +02002086 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002087 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002088 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002089 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002090 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002091
Emeric Brun32da3c42010-09-23 18:39:19 +02002092 if (strcmp(newpeer->id, localpeer) == 0) {
2093 /* Current is local peer, it define a frontend */
2094 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002095 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002096
2097 if (!curpeers->peers_fe) {
2098 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002099 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002100 err_code |= ERR_ALERT | ERR_ABORT;
2101 goto out;
2102 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002103
Willy Tarreau237250c2011-07-29 01:49:03 +02002104 init_new_proxy(curpeers->peers_fe);
2105 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002106 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002107 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2108 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002109 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002110
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002111 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002112
Willy Tarreau902636f2013-03-10 19:44:48 +01002113 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2114 if (errmsg && *errmsg) {
2115 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002116 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002117 }
2118 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002119 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2120 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002121 err_code |= ERR_FATAL;
2122 goto out;
2123 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002124
2125 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002126 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002127 l->maxconn = curpeers->peers_fe->maxconn;
2128 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002129 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002130 l->analysers |= curpeers->peers_fe->fe_req_ana;
2131 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002132 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2133 global.maxsock += l->maxconn;
2134 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002135 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002136 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002137 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2138 file, linenum, args[0], args[1],
2139 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002140 err_code |= ERR_FATAL;
2141 goto out;
2142 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002143 }
2144 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002145 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2146 curpeers->state = PR_STSTOPPED;
2147 }
2148 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2149 curpeers->state = PR_STNEW;
2150 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002151 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002152 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002153 err_code |= ERR_ALERT | ERR_FATAL;
2154 goto out;
2155 }
2156
2157out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002158 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002159 return err_code;
2160}
2161
Baptiste Assmann325137d2015-04-13 23:40:55 +02002162/*
2163 * Parse a <resolvers> section.
2164 * Returns the error code, 0 if OK, or any combination of :
2165 * - ERR_ABORT: must abort ASAP
2166 * - ERR_FATAL: we can continue parsing but not start the service
2167 * - ERR_WARN: a warning has been emitted
2168 * - ERR_ALERT: an alert has been emitted
2169 * Only the two first ones can stop processing, the two others are just
2170 * indicators.
2171 */
2172int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2173{
2174 static struct dns_resolvers *curr_resolvers = NULL;
2175 struct dns_nameserver *newnameserver = NULL;
2176 const char *err;
2177 int err_code = 0;
2178 char *errmsg = NULL;
2179
2180 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2181 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002182 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002183 err_code |= ERR_ALERT | ERR_ABORT;
2184 goto out;
2185 }
2186
2187 err = invalid_char(args[1]);
2188 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002189 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2190 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002191 err_code |= ERR_ALERT | ERR_ABORT;
2192 goto out;
2193 }
2194
2195 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2196 /* Error if two resolvers owns the same name */
2197 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002198 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2199 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002200 err_code |= ERR_ALERT | ERR_ABORT;
2201 }
2202 }
2203
Vincent Bernat02779b62016-04-03 13:48:43 +02002204 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002205 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002206 err_code |= ERR_ALERT | ERR_ABORT;
2207 goto out;
2208 }
2209
2210 /* default values */
2211 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2212 curr_resolvers->conf.file = strdup(file);
2213 curr_resolvers->conf.line = linenum;
2214 curr_resolvers->id = strdup(args[1]);
2215 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002216 /* default maximum response size */
2217 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002218 /* default hold period for nx, other, refuse and timeout is 30s */
2219 curr_resolvers->hold.nx = 30000;
2220 curr_resolvers->hold.other = 30000;
2221 curr_resolvers->hold.refused = 30000;
2222 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002223 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002224 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002225 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002226 curr_resolvers->timeout.resolve = 1000;
2227 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002228 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002229 curr_resolvers->nb_nameservers = 0;
2230 LIST_INIT(&curr_resolvers->nameservers);
2231 LIST_INIT(&curr_resolvers->resolutions.curr);
2232 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002233 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002234 }
2235 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2236 struct sockaddr_storage *sk;
2237 int port1, port2;
2238 struct protocol *proto;
2239
2240 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002241 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2242 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002243 err_code |= ERR_ALERT | ERR_FATAL;
2244 goto out;
2245 }
2246
2247 err = invalid_char(args[1]);
2248 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002249 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2250 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002251 err_code |= ERR_ALERT | ERR_FATAL;
2252 goto out;
2253 }
2254
Christopher Faulet67957bd2017-09-27 11:00:59 +02002255 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002256 /* Error if two resolvers owns the same name */
2257 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002258 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 -06002259 file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002260 err_code |= ERR_ALERT | ERR_FATAL;
2261 }
2262 }
2263
Vincent Bernat02779b62016-04-03 13:48:43 +02002264 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002265 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002266 err_code |= ERR_ALERT | ERR_ABORT;
2267 goto out;
2268 }
2269
2270 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002271 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002272 newnameserver->resolvers = curr_resolvers;
2273 newnameserver->conf.file = strdup(file);
2274 newnameserver->conf.line = linenum;
2275 newnameserver->id = strdup(args[1]);
2276
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002277 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002278 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002279 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002280 err_code |= ERR_ALERT | ERR_FATAL;
2281 goto out;
2282 }
2283
2284 proto = protocol_by_family(sk->ss_family);
2285 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002286 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002287 file, linenum, args[0], args[1]);
2288 err_code |= ERR_ALERT | ERR_FATAL;
2289 goto out;
2290 }
2291
2292 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002293 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2294 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002295 err_code |= ERR_ALERT | ERR_FATAL;
2296 goto out;
2297 }
2298
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002299 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002300 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2301 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002302 err_code |= ERR_ALERT | ERR_FATAL;
2303 goto out;
2304 }
2305
Baptiste Assmann325137d2015-04-13 23:40:55 +02002306 newnameserver->addr = *sk;
2307 }
Ben Draut44e609b2018-05-29 15:40:08 -06002308 else if (strcmp(args[0], "parse-resolv-conf") == 0) {
2309 const char *whitespace = "\r\n\t ";
2310 char *resolv_line = NULL;
2311 int resolv_linenum = 0;
2312 FILE *f = NULL;
2313 char *address = NULL;
2314 struct sockaddr_storage *sk = NULL;
2315 struct protocol *proto;
2316 int duplicate_name = 0;
2317
2318 if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
2319 ha_alert("parsing [%s:%d] : out of memory.\n",
2320 file, linenum);
2321 err_code |= ERR_ALERT | ERR_FATAL;
2322 goto resolv_out;
2323 }
2324
2325 if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
2326 ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n",
2327 file, linenum);
2328 err_code |= ERR_ALERT | ERR_FATAL;
2329 goto resolv_out;
2330 }
2331
2332 sk = calloc(1, sizeof(*sk));
2333 if (sk == NULL) {
2334 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n",
2335 resolv_linenum);
2336 err_code |= ERR_ALERT | ERR_FATAL;
2337 goto resolv_out;
2338 }
2339
2340 while (fgets(resolv_line, LINESIZE, f) != NULL) {
2341 resolv_linenum++;
2342 if (strncmp(resolv_line, "nameserver", 10) != 0)
2343 continue;
2344
2345 address = strtok(resolv_line + 10, whitespace);
2346 if (address == resolv_line + 10)
2347 continue;
2348
2349 if (address == NULL) {
2350 ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
2351 resolv_linenum);
2352 err_code |= ERR_WARN;
2353 continue;
2354 }
2355
2356 duplicate_name = 0;
2357 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
2358 if (strcmp(newnameserver->id, address) == 0) {
2359 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",
2360 resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line);
2361 err_code |= ERR_WARN;
2362 duplicate_name = 1;
2363 }
2364 }
2365
2366 if (duplicate_name)
2367 continue;
2368
2369 memset(sk, 0, sizeof(*sk));
2370 sk = str2ip2(address, sk, 1);
2371 if (!sk) {
2372 ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, namerserver will be excluded.\n",
2373 resolv_linenum, address);
2374 err_code |= ERR_WARN;
2375 continue;
2376 }
2377
2378 set_host_port(sk, 53);
2379
2380 proto = protocol_by_family(sk->ss_family);
2381 if (!proto || !proto->connect) {
2382 ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
2383 resolv_linenum, address);
2384 err_code |= ERR_WARN;
2385 continue;
2386 }
2387
2388 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
2389 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2390 err_code |= ERR_ALERT | ERR_FATAL;
2391 goto resolv_out;
2392 }
2393
2394 newnameserver->conf.file = strdup("/etc/resolv.conf");
2395 if (newnameserver->conf.file == 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->id = strdup(address);
2402 if (newnameserver->id == 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->resolvers = curr_resolvers;
2409 newnameserver->conf.line = resolv_linenum;
2410 newnameserver->addr = *sk;
2411
2412 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
2413 }
2414
2415resolv_out:
2416 free(sk);
2417 free(resolv_line);
2418 if (f != NULL)
2419 fclose(f);
2420 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002421 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2422 const char *res;
2423 unsigned int time;
2424
2425 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002426 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2427 file, linenum, args[0]);
2428 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002429 err_code |= ERR_ALERT | ERR_FATAL;
2430 goto out;
2431 }
2432 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2433 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002434 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2435 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002436 err_code |= ERR_ALERT | ERR_FATAL;
2437 goto out;
2438 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002439 if (strcmp(args[1], "nx") == 0)
2440 curr_resolvers->hold.nx = time;
2441 else if (strcmp(args[1], "other") == 0)
2442 curr_resolvers->hold.other = time;
2443 else if (strcmp(args[1], "refused") == 0)
2444 curr_resolvers->hold.refused = time;
2445 else if (strcmp(args[1], "timeout") == 0)
2446 curr_resolvers->hold.timeout = time;
2447 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002448 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002449 else if (strcmp(args[1], "obsolete") == 0)
2450 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002451 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002452 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2453 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002454 err_code |= ERR_ALERT | ERR_FATAL;
2455 goto out;
2456 }
2457
2458 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002459 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002460 int i = 0;
2461
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002462 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002463 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2464 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002465 err_code |= ERR_ALERT | ERR_FATAL;
2466 goto out;
2467 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002468
2469 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002470 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002471 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2472 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002473 err_code |= ERR_ALERT | ERR_FATAL;
2474 goto out;
2475 }
2476
2477 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002478 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002479 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002480 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2481 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002482 err_code |= ERR_WARN;
2483 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002484 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002485 else if (strcmp(args[0], "resolve_retries") == 0) {
2486 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002487 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2488 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002489 err_code |= ERR_ALERT | ERR_FATAL;
2490 goto out;
2491 }
2492 curr_resolvers->resolve_retries = atoi(args[1]);
2493 }
2494 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002495 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002496 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2497 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002498 err_code |= ERR_ALERT | ERR_FATAL;
2499 goto out;
2500 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002501 else if (strcmp(args[1], "retry") == 0 ||
2502 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002503 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002504 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002505
2506 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002507 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2508 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002509 err_code |= ERR_ALERT | ERR_FATAL;
2510 goto out;
2511 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002512 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002513 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002514 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2515 file, linenum, *res, 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 if (args[1][2] == 't')
2520 curr_resolvers->timeout.retry = tout;
2521 else
2522 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002523 }
2524 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002525 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2526 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002527 err_code |= ERR_ALERT | ERR_FATAL;
2528 goto out;
2529 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002530 } /* neither "nameserver" nor "resolvers" */
2531 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002532 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002533 err_code |= ERR_ALERT | ERR_FATAL;
2534 goto out;
2535 }
2536
2537 out:
2538 free(errmsg);
2539 return err_code;
2540}
Simon Horman0d16a402015-01-30 11:22:58 +09002541
2542/*
William Lallemand51097192015-04-14 16:35:22 +02002543 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002544 * Returns the error code, 0 if OK, or any combination of :
2545 * - ERR_ABORT: must abort ASAP
2546 * - ERR_FATAL: we can continue parsing but not start the service
2547 * - ERR_WARN: a warning has been emitted
2548 * - ERR_ALERT: an alert has been emitted
2549 * Only the two first ones can stop processing, the two others are just
2550 * indicators.
2551 */
2552int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2553{
2554 static struct mailers *curmailers = NULL;
2555 struct mailer *newmailer = NULL;
2556 const char *err;
2557 int err_code = 0;
2558 char *errmsg = NULL;
2559
2560 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2561 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002562 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002563 err_code |= ERR_ALERT | ERR_ABORT;
2564 goto out;
2565 }
2566
2567 err = invalid_char(args[1]);
2568 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002569 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2570 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002571 err_code |= ERR_ALERT | ERR_ABORT;
2572 goto out;
2573 }
2574
2575 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2576 /*
2577 * If there are two proxies with the same name only following
2578 * combinations are allowed:
2579 */
2580 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002581 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2582 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002583 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002584 }
2585 }
2586
Vincent Bernat02779b62016-04-03 13:48:43 +02002587 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002588 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002589 err_code |= ERR_ALERT | ERR_ABORT;
2590 goto out;
2591 }
2592
2593 curmailers->next = mailers;
2594 mailers = curmailers;
2595 curmailers->conf.file = strdup(file);
2596 curmailers->conf.line = linenum;
2597 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002598 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2599 * But need enough time so that timeouts don't occur
2600 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002601 }
2602 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2603 struct sockaddr_storage *sk;
2604 int port1, port2;
2605 struct protocol *proto;
2606
2607 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002608 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2609 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002610 err_code |= ERR_ALERT | ERR_FATAL;
2611 goto out;
2612 }
2613
2614 err = invalid_char(args[1]);
2615 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002616 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2617 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002618 err_code |= ERR_ALERT | ERR_FATAL;
2619 goto out;
2620 }
2621
Vincent Bernat02779b62016-04-03 13:48:43 +02002622 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002623 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002624 err_code |= ERR_ALERT | ERR_ABORT;
2625 goto out;
2626 }
2627
2628 /* the mailers are linked backwards first */
2629 curmailers->count++;
2630 newmailer->next = curmailers->mailer_list;
2631 curmailers->mailer_list = newmailer;
2632 newmailer->mailers = curmailers;
2633 newmailer->conf.file = strdup(file);
2634 newmailer->conf.line = linenum;
2635
2636 newmailer->id = strdup(args[1]);
2637
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002638 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002639 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002640 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002641 err_code |= ERR_ALERT | ERR_FATAL;
2642 goto out;
2643 }
2644
2645 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002646 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002647 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2648 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002649 err_code |= ERR_ALERT | ERR_FATAL;
2650 goto out;
2651 }
2652
2653 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002654 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2655 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002656 err_code |= ERR_ALERT | ERR_FATAL;
2657 goto out;
2658 }
2659
2660 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002661 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port 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 newmailer->addr = *sk;
2668 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002669 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002670 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002671 }
2672 else if (strcmp(args[0], "timeout") == 0) {
2673 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002674 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2675 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002676 err_code |= ERR_ALERT | ERR_FATAL;
2677 goto out;
2678 }
2679 else if (strcmp(args[1], "mail") == 0) {
2680 const char *res;
2681 unsigned int timeout_mail;
2682 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002683 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2684 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002685 err_code |= ERR_ALERT | ERR_FATAL;
2686 goto out;
2687 }
2688 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2689 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002690 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2691 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002692 err_code |= ERR_ALERT | ERR_FATAL;
2693 goto out;
2694 }
2695 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002696 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 +01002697 err_code |= ERR_ALERT | ERR_FATAL;
2698 goto out;
2699 }
2700 curmailers->timeout.mail = timeout_mail;
2701 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002702 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002703 file, linenum, args[0], args[1]);
2704 err_code |= ERR_ALERT | ERR_FATAL;
2705 goto out;
2706 }
2707 }
Simon Horman0d16a402015-01-30 11:22:58 +09002708 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002709 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002710 err_code |= ERR_ALERT | ERR_FATAL;
2711 goto out;
2712 }
2713
2714out:
2715 free(errmsg);
2716 return err_code;
2717}
2718
Simon Horman9dc49962015-01-30 11:22:59 +09002719static void free_email_alert(struct proxy *p)
2720{
2721 free(p->email_alert.mailers.name);
2722 p->email_alert.mailers.name = NULL;
2723 free(p->email_alert.from);
2724 p->email_alert.from = NULL;
2725 free(p->email_alert.to);
2726 p->email_alert.to = NULL;
2727 free(p->email_alert.myhostname);
2728 p->email_alert.myhostname = NULL;
2729}
2730
Willy Tarreau3842f002009-06-14 11:39:52 +02002731int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002732{
2733 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002734 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002735 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002736 int rc;
2737 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002738 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002739 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002740 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002741 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002742 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002743
Willy Tarreau977b8e42006-12-29 14:19:17 +01002744 if (!strcmp(args[0], "listen"))
2745 rc = PR_CAP_LISTEN;
2746 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002747 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002748 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002749 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002750 else
2751 rc = PR_CAP_NONE;
2752
2753 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002754 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002755 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2756 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2757 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002758 err_code |= ERR_ALERT | ERR_ABORT;
2759 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002760 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002761
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002762 err = invalid_char(args[1]);
2763 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002764 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2765 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002766 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002767 }
2768
Willy Tarreau8f50b682015-05-26 11:45:02 +02002769 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2770 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002771 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2772 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2773 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002774 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002775 }
2776
Vincent Bernat02779b62016-04-03 13:48:43 +02002777 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002778 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002779 err_code |= ERR_ALERT | ERR_ABORT;
2780 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002781 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002782
Willy Tarreau97cb7802010-01-03 20:23:58 +01002783 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002784 curproxy->next = proxies_list;
2785 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002786 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2787 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002788 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002789 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002790 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002791 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002792
William Lallemand6e62fb62015-04-28 16:55:23 +02002793 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2794 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002795 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002796 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002797 }
2798
2799 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002800 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002801 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002802
Willy Tarreaubaaee002006-06-26 02:48:02 +02002803 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002804 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002805 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002806 curproxy->no_options = defproxy.no_options;
2807 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002808 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002809 curproxy->except_net = defproxy.except_net;
2810 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002811 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002812 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002813
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002814 if (defproxy.fwdfor_hdr_len) {
2815 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2816 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2817 }
2818
Willy Tarreaub86db342009-11-30 11:50:16 +01002819 if (defproxy.orgto_hdr_len) {
2820 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2821 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2822 }
2823
Mark Lamourinec2247f02012-01-04 13:02:01 -05002824 if (defproxy.server_id_hdr_len) {
2825 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2826 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2827 }
2828
Willy Tarreau977b8e42006-12-29 14:19:17 +01002829 if (curproxy->cap & PR_CAP_FE) {
2830 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002831 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002832 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002833
2834 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002835 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2836 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002837
2838 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2839 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002840
Willy Tarreau977b8e42006-12-29 14:19:17 +01002841 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002842 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002843 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002844 curproxy->fullconn = defproxy.fullconn;
2845 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002846 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002847 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002848
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002849 if (defproxy.check_req) {
2850 curproxy->check_req = calloc(1, defproxy.check_len);
2851 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2852 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002853 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002854
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002855 if (defproxy.expect_str) {
2856 curproxy->expect_str = strdup(defproxy.expect_str);
2857 if (defproxy.expect_regex) {
2858 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002859 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2860 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002861 }
2862 }
2863
Willy Tarreau67402132012-05-31 20:40:20 +02002864 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002865 if (defproxy.cookie_name)
2866 curproxy->cookie_name = strdup(defproxy.cookie_name);
2867 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002868
2869 if (defproxy.dyncookie_key)
2870 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002871 if (defproxy.cookie_domain)
2872 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002873
Willy Tarreau31936852010-10-06 16:59:56 +02002874 if (defproxy.cookie_maxidle)
2875 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2876
2877 if (defproxy.cookie_maxlife)
2878 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2879
Emeric Brun647caf12009-06-30 17:57:00 +02002880 if (defproxy.rdp_cookie_name)
2881 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2882 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2883
Willy Tarreau01732802007-11-01 22:48:15 +01002884 if (defproxy.url_param_name)
2885 curproxy->url_param_name = strdup(defproxy.url_param_name);
2886 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002887
Benoitaffb4812009-03-25 13:02:10 +01002888 if (defproxy.hh_name)
2889 curproxy->hh_name = strdup(defproxy.hh_name);
2890 curproxy->hh_len = defproxy.hh_len;
2891 curproxy->hh_match_domain = defproxy.hh_match_domain;
2892
Willy Tarreauef9a3602012-12-08 22:29:20 +01002893 if (defproxy.conn_src.iface_name)
2894 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2895 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002896 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002897#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002898 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002899#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002900 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002901 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002902
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002903 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002904 if (defproxy.capture_name)
2905 curproxy->capture_name = strdup(defproxy.capture_name);
2906 curproxy->capture_namelen = defproxy.capture_namelen;
2907 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002908 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002909
Willy Tarreau977b8e42006-12-29 14:19:17 +01002910 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002911 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002912 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002913 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002914 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002915 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002916 curproxy->mon_net = defproxy.mon_net;
2917 curproxy->mon_mask = defproxy.mon_mask;
2918 if (defproxy.monitor_uri)
2919 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2920 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002921 if (defproxy.defbe.name)
2922 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002923
2924 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002925 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2926 if (curproxy->conf.logformat_string &&
2927 curproxy->conf.logformat_string != default_http_log_format &&
2928 curproxy->conf.logformat_string != default_tcp_log_format &&
2929 curproxy->conf.logformat_string != clf_http_log_format)
2930 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2931
2932 if (defproxy.conf.lfs_file) {
2933 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2934 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2935 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002936
2937 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2938 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2939 if (curproxy->conf.logformat_sd_string &&
2940 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2941 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2942
2943 if (defproxy.conf.lfsd_file) {
2944 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2945 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2946 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002947 }
2948
2949 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002950 curproxy->timeout.connect = defproxy.timeout.connect;
2951 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002952 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002953 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002954 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002955 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002956 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002957 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002958 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002959 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002960 }
2961
Willy Tarreaubaaee002006-06-26 02:48:02 +02002962 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002963 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002964
2965 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002966 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002967 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002968 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002969 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002970 LIST_INIT(&node->list);
2971 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2972 }
2973
Willy Tarreau62a61232013-04-12 18:13:46 +02002974 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2975 if (curproxy->conf.uniqueid_format_string)
2976 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2977
Dragan Dosen43885c72015-10-01 13:18:13 +02002978 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002979
Willy Tarreau62a61232013-04-12 18:13:46 +02002980 if (defproxy.conf.uif_file) {
2981 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2982 curproxy->conf.uif_line = defproxy.conf.uif_line;
2983 }
William Lallemanda73203e2012-03-12 12:48:57 +01002984
2985 /* copy default header unique id */
2986 if (defproxy.header_unique_id)
2987 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2988
William Lallemand82fe75c2012-10-23 10:25:10 +02002989 /* default compression options */
2990 if (defproxy.comp != NULL) {
2991 curproxy->comp = calloc(1, sizeof(struct comp));
2992 curproxy->comp->algos = defproxy.comp->algos;
2993 curproxy->comp->types = defproxy.comp->types;
2994 }
2995
Willy Tarreaubaaee002006-06-26 02:48:02 +02002996 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002997 curproxy->conf.used_listener_id = EB_ROOT;
2998 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002999
Simon Horman98637e52014-06-20 12:30:16 +09003000 if (defproxy.check_path)
3001 curproxy->check_path = strdup(defproxy.check_path);
3002 if (defproxy.check_command)
3003 curproxy->check_command = strdup(defproxy.check_command);
3004
Simon Horman9dc49962015-01-30 11:22:59 +09003005 if (defproxy.email_alert.mailers.name)
3006 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
3007 if (defproxy.email_alert.from)
3008 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
3009 if (defproxy.email_alert.to)
3010 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
3011 if (defproxy.email_alert.myhostname)
3012 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003013 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003014 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003015
Willy Tarreau93893792009-07-23 13:19:11 +02003016 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003017 }
3018 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3019 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003020 /* FIXME-20070101: we should do this too at the end of the
3021 * config parsing to free all default values.
3022 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003023 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3024 err_code |= ERR_ABORT;
3025 goto out;
3026 }
3027
Willy Tarreaua534fea2008-08-03 12:19:50 +02003028 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003029 free(defproxy.check_command);
3030 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003031 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003032 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003033 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003034 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003035 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003036 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003037 free(defproxy.capture_name);
3038 free(defproxy.monitor_uri);
3039 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003040 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003041 free(defproxy.fwdfor_hdr_name);
3042 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003043 free(defproxy.orgto_hdr_name);
3044 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003045 free(defproxy.server_id_hdr_name);
3046 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003047 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003048 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003049 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003050 free(defproxy.expect_regex);
3051 defproxy.expect_regex = NULL;
3052 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003053
Willy Tarreau62a61232013-04-12 18:13:46 +02003054 if (defproxy.conf.logformat_string != default_http_log_format &&
3055 defproxy.conf.logformat_string != default_tcp_log_format &&
3056 defproxy.conf.logformat_string != clf_http_log_format)
3057 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003058
Willy Tarreau62a61232013-04-12 18:13:46 +02003059 free(defproxy.conf.uniqueid_format_string);
3060 free(defproxy.conf.lfs_file);
3061 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003062 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003063 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003064
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003065 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3066 free(defproxy.conf.logformat_sd_string);
3067 free(defproxy.conf.lfsd_file);
3068
Willy Tarreaua534fea2008-08-03 12:19:50 +02003069 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003070 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003071
Willy Tarreaubaaee002006-06-26 02:48:02 +02003072 /* we cannot free uri_auth because it might already be used */
3073 init_default_instance();
3074 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003075 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3076 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003077 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003078 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003079 }
3080 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003081 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003082 err_code |= ERR_ALERT | ERR_FATAL;
3083 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003084 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003085
3086 /* update the current file and line being parsed */
3087 curproxy->conf.args.file = curproxy->conf.file;
3088 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003089
3090 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003091 if (!strcmp(args[0], "server") ||
3092 !strcmp(args[0], "default-server") ||
3093 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003094 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3095 if (err_code & ERR_FATAL)
3096 goto out;
3097 }
3098 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003099 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003100 int cur_arg;
3101
Willy Tarreaubaaee002006-06-26 02:48:02 +02003102 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003103 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003104 err_code |= ERR_ALERT | ERR_FATAL;
3105 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003106 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003107 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003108 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003109
Willy Tarreau24709282013-03-10 21:32:12 +01003110 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003111 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3112 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003113 err_code |= ERR_ALERT | ERR_FATAL;
3114 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003115 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003116
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003117 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003118
3119 /* use default settings for unix sockets */
3120 bind_conf->ux.uid = global.unix_bind.ux.uid;
3121 bind_conf->ux.gid = global.unix_bind.ux.gid;
3122 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003123
3124 /* NOTE: the following line might create several listeners if there
3125 * are comma-separated IPs or port ranges. So all further processing
3126 * will have to be applied to all listeners created after last_listen.
3127 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003128 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3129 if (errmsg && *errmsg) {
3130 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003131 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003132 }
3133 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003134 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3135 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003136 err_code |= ERR_ALERT | ERR_FATAL;
3137 goto out;
3138 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003139
Willy Tarreau4348fad2012-09-20 16:48:07 +02003140 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3141 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003142 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003143 }
3144
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003145 cur_arg = 2;
3146 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003147 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003148 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003149 char *err;
3150
Willy Tarreau26982662012-09-12 23:17:10 +02003151 kw = bind_find_kw(args[cur_arg]);
3152 if (kw) {
3153 char *err = NULL;
3154 int code;
3155
3156 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003157 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3158 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003159 cur_arg += 1 + kw->skip ;
3160 err_code |= ERR_ALERT | ERR_FATAL;
3161 goto out;
3162 }
3163
Willy Tarreau4348fad2012-09-20 16:48:07 +02003164 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003165 err_code |= code;
3166
3167 if (code) {
3168 if (err && *err) {
3169 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003170 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003171 }
3172 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003173 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3174 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003175 if (code & ERR_FATAL) {
3176 free(err);
3177 cur_arg += 1 + kw->skip;
3178 goto out;
3179 }
3180 }
3181 free(err);
3182 cur_arg += 1 + kw->skip;
3183 continue;
3184 }
3185
Willy Tarreau8638f482012-09-18 18:01:17 +02003186 err = NULL;
3187 if (!bind_dumped) {
3188 bind_dump_kws(&err);
3189 indent_msg(&err, 4);
3190 bind_dumped = 1;
3191 }
3192
Christopher Faulet767a84b2017-11-24 16:50:31 +01003193 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3194 file, linenum, args[0], args[1], args[cur_arg],
3195 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003196 free(err);
3197
Willy Tarreau93893792009-07-23 13:19:11 +02003198 err_code |= ERR_ALERT | ERR_FATAL;
3199 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003200 }
Willy Tarreau93893792009-07-23 13:19:11 +02003201 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003202 }
3203 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003204 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003205 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3206 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003207 err_code |= ERR_ALERT | ERR_FATAL;
3208 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003209 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003210 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003211 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003212
Willy Tarreaubaaee002006-06-26 02:48:02 +02003213 /* flush useless bits */
3214 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003215 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003216 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003217 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003218 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003219 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003220
William Lallemanddf1425a2015-04-28 20:17:49 +02003221 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3222 goto out;
3223
Willy Tarreau1c47f852006-07-09 08:22:27 +02003224 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003225 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3226 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003227 err_code |= ERR_ALERT | ERR_FATAL;
3228 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003229 }
3230
Willy Tarreaua534fea2008-08-03 12:19:50 +02003231 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003232 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003233 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003234 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003235 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3236
Willy Tarreau93893792009-07-23 13:19:11 +02003237 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003238 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003239 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003240 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3241 goto out;
3242
Willy Tarreaubaaee002006-06-26 02:48:02 +02003243 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3244 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3245 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3246 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003247 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003248 err_code |= ERR_ALERT | ERR_FATAL;
3249 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003250 }
3251 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003252 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003253 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003254
3255 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003256 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003257 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003258 err_code |= ERR_ALERT | ERR_FATAL;
3259 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003260 }
3261
William Lallemanddf1425a2015-04-28 20:17:49 +02003262 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3263 goto out;
3264
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003265 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003266 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3267 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003268 err_code |= ERR_ALERT | ERR_FATAL;
3269 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003270 }
3271
3272 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003273 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003274 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003275
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003276 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003277 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3278 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003279 err_code |= ERR_ALERT | ERR_FATAL;
3280 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003281 }
3282
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003283 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3284 if (node) {
3285 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003286 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3287 file, linenum, proxy_type_str(curproxy), curproxy->id,
3288 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003289 err_code |= ERR_ALERT | ERR_FATAL;
3290 goto out;
3291 }
3292 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003293 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003294 else if (!strcmp(args[0], "description")) {
3295 int i, len=0;
3296 char *d;
3297
Cyril Bonté99ed3272010-01-24 23:29:44 +01003298 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003299 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003300 file, linenum, args[0]);
3301 err_code |= ERR_ALERT | ERR_FATAL;
3302 goto out;
3303 }
3304
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003305 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003306 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3307 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003308 return -1;
3309 }
3310
Willy Tarreau348acfe2014-04-14 15:00:39 +02003311 for (i = 1; *args[i]; i++)
3312 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003313
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003314 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003315 curproxy->desc = d;
3316
Willy Tarreau348acfe2014-04-14 15:00:39 +02003317 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3318 for (i = 2; *args[i]; i++)
3319 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003320
3321 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003322 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003323 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3324 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003325 curproxy->state = PR_STSTOPPED;
3326 }
3327 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003328 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3329 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003330 curproxy->state = PR_STNEW;
3331 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003332 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3333 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003334 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003335
3336 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003337 if (strcmp(args[cur_arg], "all") == 0) {
3338 set = 0;
3339 break;
3340 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003341 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003342 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003343 err_code |= ERR_ALERT | ERR_FATAL;
3344 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003345 }
3346 cur_arg++;
3347 }
3348 curproxy->bind_proc = set;
3349 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003350 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003351 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003352 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003353 err_code |= ERR_ALERT | ERR_FATAL;
3354 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003355 }
3356
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003357 err = invalid_char(args[1]);
3358 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003359 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3360 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003361 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003362 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003363 }
3364
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003365 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003366 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3367 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003368 err_code |= ERR_ALERT | ERR_FATAL;
3369 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003370 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003371 }
3372 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3373
3374 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3375 err_code |= ERR_WARN;
3376
3377 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003378 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3379 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003380 err_code |= ERR_ALERT | ERR_FATAL;
3381 goto out;
3382 }
3383 free(curproxy->dyncookie_key);
3384 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003385 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003386 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3387 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003388
Willy Tarreau977b8e42006-12-29 14:19:17 +01003389 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003390 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003391
Willy Tarreaubaaee002006-06-26 02:48:02 +02003392 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003393 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3394 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003395 err_code |= ERR_ALERT | ERR_FATAL;
3396 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003397 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003398
Willy Tarreau67402132012-05-31 20:40:20 +02003399 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003400 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003401 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003402 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003403 curproxy->cookie_name = strdup(args[1]);
3404 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003405
Willy Tarreaubaaee002006-06-26 02:48:02 +02003406 cur_arg = 2;
3407 while (*(args[cur_arg])) {
3408 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003409 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003410 }
3411 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003412 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003413 }
3414 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003415 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003416 }
3417 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003418 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003419 }
3420 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003421 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003422 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003423 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003424 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003425 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003426 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003427 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003428 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003429 else if (!strcmp(args[cur_arg], "httponly")) {
3430 curproxy->ck_opts |= PR_CK_HTTPONLY;
3431 }
3432 else if (!strcmp(args[cur_arg], "secure")) {
3433 curproxy->ck_opts |= PR_CK_SECURE;
3434 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003435 else if (!strcmp(args[cur_arg], "domain")) {
3436 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003437 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3438 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003439 err_code |= ERR_ALERT | ERR_FATAL;
3440 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003441 }
3442
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003443 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003444 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003445 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3446 " dots nor does not start with a dot."
3447 " RFC forbids it, this configuration may not work properly.\n",
3448 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003449 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003450 }
3451
3452 err = invalid_domainchar(args[cur_arg + 1]);
3453 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003454 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3455 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003456 err_code |= ERR_ALERT | ERR_FATAL;
3457 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003458 }
3459
Willy Tarreau68a897b2009-12-03 23:28:34 +01003460 if (!curproxy->cookie_domain) {
3461 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3462 } else {
3463 /* one domain was already specified, add another one by
3464 * building the string which will be returned along with
3465 * the cookie.
3466 */
3467 char *new_ptr;
3468 int new_len = strlen(curproxy->cookie_domain) +
3469 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3470 new_ptr = malloc(new_len);
3471 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3472 free(curproxy->cookie_domain);
3473 curproxy->cookie_domain = new_ptr;
3474 }
Willy Tarreau31936852010-10-06 16:59:56 +02003475 cur_arg++;
3476 }
3477 else if (!strcmp(args[cur_arg], "maxidle")) {
3478 unsigned int maxidle;
3479 const char *res;
3480
3481 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003482 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3483 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003484 err_code |= ERR_ALERT | ERR_FATAL;
3485 goto out;
3486 }
3487
3488 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3489 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003490 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3491 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003492 err_code |= ERR_ALERT | ERR_FATAL;
3493 goto out;
3494 }
3495 curproxy->cookie_maxidle = maxidle;
3496 cur_arg++;
3497 }
3498 else if (!strcmp(args[cur_arg], "maxlife")) {
3499 unsigned int maxlife;
3500 const char *res;
3501
3502 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003503 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3504 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003505 err_code |= ERR_ALERT | ERR_FATAL;
3506 goto out;
3507 }
3508
3509 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3510 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003511 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3512 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003513 err_code |= ERR_ALERT | ERR_FATAL;
3514 goto out;
3515 }
3516 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003517 cur_arg++;
3518 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003519 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003520
3521 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3522 err_code |= ERR_WARN;
3523 curproxy->ck_opts |= PR_CK_DYNAMIC;
3524 }
3525
Willy Tarreaubaaee002006-06-26 02:48:02 +02003526 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003527 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3528 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003529 err_code |= ERR_ALERT | ERR_FATAL;
3530 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003531 }
3532 cur_arg++;
3533 }
Willy Tarreau67402132012-05-31 20:40:20 +02003534 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003535 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3536 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003537 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003538 }
3539
Willy Tarreau67402132012-05-31 20:40:20 +02003540 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003541 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3542 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003543 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003544 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003545
Willy Tarreau67402132012-05-31 20:40:20 +02003546 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003547 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3548 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003549 err_code |= ERR_ALERT | ERR_FATAL;
3550 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003551 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003552 else if (!strcmp(args[0], "email-alert")) {
3553 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003554 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3555 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003556 err_code |= ERR_ALERT | ERR_FATAL;
3557 goto out;
3558 }
3559
3560 if (!strcmp(args[1], "from")) {
3561 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003562 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3563 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003564 err_code |= ERR_ALERT | ERR_FATAL;
3565 goto out;
3566 }
3567 free(curproxy->email_alert.from);
3568 curproxy->email_alert.from = strdup(args[2]);
3569 }
3570 else if (!strcmp(args[1], "mailers")) {
3571 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003572 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3573 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003574 err_code |= ERR_ALERT | ERR_FATAL;
3575 goto out;
3576 }
3577 free(curproxy->email_alert.mailers.name);
3578 curproxy->email_alert.mailers.name = strdup(args[2]);
3579 }
3580 else if (!strcmp(args[1], "myhostname")) {
3581 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003582 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3583 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003584 err_code |= ERR_ALERT | ERR_FATAL;
3585 goto out;
3586 }
3587 free(curproxy->email_alert.myhostname);
3588 curproxy->email_alert.myhostname = strdup(args[2]);
3589 }
Simon Horman64e34162015-02-06 11:11:57 +09003590 else if (!strcmp(args[1], "level")) {
3591 curproxy->email_alert.level = get_log_level(args[2]);
3592 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003593 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3594 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003595 err_code |= ERR_ALERT | ERR_FATAL;
3596 goto out;
3597 }
3598 }
Simon Horman9dc49962015-01-30 11:22:59 +09003599 else if (!strcmp(args[1], "to")) {
3600 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003601 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3602 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003603 err_code |= ERR_ALERT | ERR_FATAL;
3604 goto out;
3605 }
3606 free(curproxy->email_alert.to);
3607 curproxy->email_alert.to = strdup(args[2]);
3608 }
3609 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003610 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3611 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003612 err_code |= ERR_ALERT | ERR_FATAL;
3613 goto out;
3614 }
Simon Horman64e34162015-02-06 11:11:57 +09003615 /* Indicate that the email_alert is at least partially configured */
3616 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003617 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003618 else if (!strcmp(args[0], "external-check")) {
3619 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003620 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3621 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003622 err_code |= ERR_ALERT | ERR_FATAL;
3623 goto out;
3624 }
3625
3626 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003627 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003628 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003629 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003630 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3631 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003632 err_code |= ERR_ALERT | ERR_FATAL;
3633 goto out;
3634 }
3635 free(curproxy->check_command);
3636 curproxy->check_command = strdup(args[2]);
3637 }
3638 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003639 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003640 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003641 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003642 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3643 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003644 err_code |= ERR_ALERT | ERR_FATAL;
3645 goto out;
3646 }
3647 free(curproxy->check_path);
3648 curproxy->check_path = strdup(args[2]);
3649 }
3650 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003651 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3652 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003653 err_code |= ERR_ALERT | ERR_FATAL;
3654 goto out;
3655 }
3656 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003657 else if (!strcmp(args[0], "persist")) { /* persist */
3658 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003659 ha_alert("parsing [%s:%d] : missing persist method.\n",
3660 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003661 err_code |= ERR_ALERT | ERR_FATAL;
3662 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003663 }
3664
3665 if (!strncmp(args[1], "rdp-cookie", 10)) {
3666 curproxy->options2 |= PR_O2_RDPC_PRST;
3667
Emeric Brunb982a3d2010-01-04 15:45:53 +01003668 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003669 const char *beg, *end;
3670
3671 beg = args[1] + 11;
3672 end = strchr(beg, ')');
3673
William Lallemanddf1425a2015-04-28 20:17:49 +02003674 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3675 goto out;
3676
Emeric Brun647caf12009-06-30 17:57:00 +02003677 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003678 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3679 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003680 err_code |= ERR_ALERT | ERR_FATAL;
3681 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003682 }
3683
3684 free(curproxy->rdp_cookie_name);
3685 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3686 curproxy->rdp_cookie_len = end-beg;
3687 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003688 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003689 free(curproxy->rdp_cookie_name);
3690 curproxy->rdp_cookie_name = strdup("msts");
3691 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3692 }
3693 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003694 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3695 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003696 err_code |= ERR_ALERT | ERR_FATAL;
3697 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003698 }
3699 }
3700 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003701 ha_alert("parsing [%s:%d] : unknown persist method.\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 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003707 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003708 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 +02003709 err_code |= ERR_ALERT | ERR_FATAL;
3710 goto out;
3711 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003712 else if (!strcmp(args[0], "load-server-state-from-file")) {
3713 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3714 err_code |= ERR_WARN;
3715 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3716 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3717 }
3718 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3719 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3720 }
3721 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3722 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3723 }
3724 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003725 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3726 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003727 err_code |= ERR_ALERT | ERR_FATAL;
3728 goto out;
3729 }
3730 }
3731 else if (!strcmp(args[0], "server-state-file-name")) {
3732 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3733 err_code |= ERR_WARN;
3734 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003735 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3736 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003737 err_code |= ERR_ALERT | ERR_FATAL;
3738 goto out;
3739 }
3740 else if (!strcmp(args[1], "use-backend-name"))
3741 curproxy->server_state_file_name = strdup(curproxy->id);
3742 else
3743 curproxy->server_state_file_name = strdup(args[1]);
3744 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003745 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003746 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003747 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003748
Willy Tarreaubaaee002006-06-26 02:48:02 +02003749 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003750 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003751 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 +01003752 err_code |= ERR_ALERT | ERR_FATAL;
3753 goto out;
3754 }
3755
William Lallemand1a748ae2015-05-19 16:37:23 +02003756 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3757 goto out;
3758
Willy Tarreaubaaee002006-06-26 02:48:02 +02003759 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003760 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3761 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003762 err_code |= ERR_ALERT | ERR_FATAL;
3763 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003764 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003765 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003766 curproxy->capture_name = strdup(args[2]);
3767 curproxy->capture_namelen = strlen(curproxy->capture_name);
3768 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003769 curproxy->to_log |= LW_COOKIE;
3770 }
3771 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3772 struct cap_hdr *hdr;
3773
3774 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003775 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 +02003776 err_code |= ERR_ALERT | ERR_FATAL;
3777 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003778 }
3779
William Lallemand1a748ae2015-05-19 16:37:23 +02003780 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3781 goto out;
3782
Willy Tarreaubaaee002006-06-26 02:48:02 +02003783 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003784 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3785 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003786 err_code |= ERR_ALERT | ERR_FATAL;
3787 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003788 }
3789
Vincent Bernat02779b62016-04-03 13:48:43 +02003790 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003791 hdr->next = curproxy->req_cap;
3792 hdr->name = strdup(args[3]);
3793 hdr->namelen = strlen(args[3]);
3794 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003795 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003796 hdr->index = curproxy->nb_req_cap++;
3797 curproxy->req_cap = hdr;
3798 curproxy->to_log |= LW_REQHDR;
3799 }
3800 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3801 struct cap_hdr *hdr;
3802
3803 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003804 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 +02003805 err_code |= ERR_ALERT | ERR_FATAL;
3806 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003807 }
3808
William Lallemand1a748ae2015-05-19 16:37:23 +02003809 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3810 goto out;
3811
Willy Tarreaubaaee002006-06-26 02:48:02 +02003812 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003813 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3814 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003815 err_code |= ERR_ALERT | ERR_FATAL;
3816 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003817 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003818 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003819 hdr->next = curproxy->rsp_cap;
3820 hdr->name = strdup(args[3]);
3821 hdr->namelen = strlen(args[3]);
3822 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003823 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003824 hdr->index = curproxy->nb_rsp_cap++;
3825 curproxy->rsp_cap = hdr;
3826 curproxy->to_log |= LW_RSPHDR;
3827 }
3828 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003829 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3830 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003831 err_code |= ERR_ALERT | ERR_FATAL;
3832 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003833 }
3834 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003835 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003836 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003837 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003838
William Lallemanddf1425a2015-04-28 20:17:49 +02003839 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3840 goto out;
3841
Willy Tarreaubaaee002006-06-26 02:48:02 +02003842 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003843 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3844 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003845 err_code |= ERR_ALERT | ERR_FATAL;
3846 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003847 }
3848 curproxy->conn_retries = atol(args[1]);
3849 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003850 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003851 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003852
3853 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003854 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003855 err_code |= ERR_ALERT | ERR_FATAL;
3856 goto out;
3857 }
3858
Willy Tarreau20b0de52012-12-24 15:45:22 +01003859 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003860 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003861 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3862 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3863 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3864 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003865 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3866 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003867 err_code |= ERR_WARN;
3868 }
3869
Willy Tarreauff011f22011-01-06 17:51:27 +01003870 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003871
Willy Tarreauff011f22011-01-06 17:51:27 +01003872 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003873 err_code |= ERR_ALERT | ERR_ABORT;
3874 goto out;
3875 }
3876
Willy Tarreau5002f572014-04-23 01:32:02 +02003877 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003878 err_code |= warnif_cond_conflicts(rule->cond,
3879 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3880 file, linenum);
3881
Willy Tarreauff011f22011-01-06 17:51:27 +01003882 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003883 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003884 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003885 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003886
3887 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003888 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003889 err_code |= ERR_ALERT | ERR_FATAL;
3890 goto out;
3891 }
3892
3893 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003894 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003895 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3896 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003897 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3898 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003899 err_code |= ERR_WARN;
3900 }
3901
3902 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3903
3904 if (!rule) {
3905 err_code |= ERR_ALERT | ERR_ABORT;
3906 goto out;
3907 }
3908
3909 err_code |= warnif_cond_conflicts(rule->cond,
3910 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3911 file, linenum);
3912
3913 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3914 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003915 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3916 /* set the header name and length into the proxy structure */
3917 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3918 err_code |= ERR_WARN;
3919
3920 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003921 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3922 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003923 err_code |= ERR_ALERT | ERR_FATAL;
3924 goto out;
3925 }
3926
3927 /* set the desired header name */
3928 free(curproxy->server_id_hdr_name);
3929 curproxy->server_id_hdr_name = strdup(args[1]);
3930 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3931 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003932 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003933 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003934
Willy Tarreaub099aca2008-10-12 17:26:37 +02003935 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003936 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003937 err_code |= ERR_ALERT | ERR_FATAL;
3938 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003939 }
3940
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003941 /* emulate "block" using "http-request block". Since these rules are supposed to
3942 * be processed before all http-request rules, we put them into their own list
3943 * and will insert them at the end.
3944 */
3945 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3946 if (!rule) {
3947 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003948 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003949 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003950 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3951 err_code |= warnif_cond_conflicts(rule->cond,
3952 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3953 file, linenum);
3954 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003955
3956 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003957 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 +02003958
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003959 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003960 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003961 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003962
Cyril Bonté99ed3272010-01-24 23:29:44 +01003963 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003964 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003965 err_code |= ERR_ALERT | ERR_FATAL;
3966 goto out;
3967 }
3968
Willy Tarreaube4653b2015-05-28 15:26:58 +02003969 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003970 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3971 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003972 err_code |= ERR_ALERT | ERR_FATAL;
3973 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003974 }
3975
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003976 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003977 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003978 err_code |= warnif_cond_conflicts(rule->cond,
3979 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3980 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003981 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003982 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003983 struct switching_rule *rule;
3984
Willy Tarreaub099aca2008-10-12 17:26:37 +02003985 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003986 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003987 err_code |= ERR_ALERT | ERR_FATAL;
3988 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003989 }
3990
Willy Tarreau55ea7572007-06-17 19:56:27 +02003991 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003992 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003993
3994 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003995 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003996 err_code |= ERR_ALERT | ERR_FATAL;
3997 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003998 }
3999
Willy Tarreauf51658d2014-04-23 01:21:56 +02004000 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004001 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004002 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4003 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02004004 err_code |= ERR_ALERT | ERR_FATAL;
4005 goto out;
4006 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004007
Willy Tarreauf51658d2014-04-23 01:21:56 +02004008 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004009 }
Willy Tarreau4f862642017-02-28 09:34:39 +01004010 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004011 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
4012 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004013 err_code |= ERR_ALERT | ERR_FATAL;
4014 goto out;
4015 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004016
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004017 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004018 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004019 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004020 goto out;
4021 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004022 rule->cond = cond;
4023 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004024 rule->line = linenum;
4025 rule->file = strdup(file);
4026 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004027 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004028 goto out;
4029 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004030 LIST_INIT(&rule->list);
4031 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4032 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004033 else if (strcmp(args[0], "use-server") == 0) {
4034 struct server_rule *rule;
4035
4036 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004037 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004038 err_code |= ERR_ALERT | ERR_FATAL;
4039 goto out;
4040 }
4041
4042 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4043 err_code |= ERR_WARN;
4044
4045 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004046 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004047 err_code |= ERR_ALERT | ERR_FATAL;
4048 goto out;
4049 }
4050
4051 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004052 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4053 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004054 err_code |= ERR_ALERT | ERR_FATAL;
4055 goto out;
4056 }
4057
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004058 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004059 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4060 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004061 err_code |= ERR_ALERT | ERR_FATAL;
4062 goto out;
4063 }
4064
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004065 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004066
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004067 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004068 rule->cond = cond;
4069 rule->srv.name = strdup(args[1]);
4070 LIST_INIT(&rule->list);
4071 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4072 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4073 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004074 else if ((!strcmp(args[0], "force-persist")) ||
4075 (!strcmp(args[0], "ignore-persist"))) {
4076 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004077
4078 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004079 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004080 err_code |= ERR_ALERT | ERR_FATAL;
4081 goto out;
4082 }
4083
Cyril Bonté4288c5a2018-03-12 22:02:59 +01004084 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01004085 err_code |= ERR_WARN;
4086
Willy Tarreauef6494c2010-01-28 17:12:36 +01004087 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004088 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4089 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004090 err_code |= ERR_ALERT | ERR_FATAL;
4091 goto out;
4092 }
4093
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004094 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004095 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4096 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004097 err_code |= ERR_ALERT | ERR_FATAL;
4098 goto out;
4099 }
4100
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004101 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4102 * where force-persist is applied.
4103 */
4104 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004105
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004106 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004107 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004108 if (!strcmp(args[0], "force-persist")) {
4109 rule->type = PERSIST_TYPE_FORCE;
4110 } else {
4111 rule->type = PERSIST_TYPE_IGNORE;
4112 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004113 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004114 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004115 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004116 else if (!strcmp(args[0], "stick-table")) {
4117 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004118 struct proxy *other;
4119
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004120 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004121 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004122 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4123 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004124 err_code |= ERR_ALERT | ERR_FATAL;
4125 goto out;
4126 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004127
Emeric Brun32da3c42010-09-23 18:39:19 +02004128 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004129 curproxy->table.type = (unsigned int)-1;
4130 while (*args[myidx]) {
4131 const char *err;
4132
4133 if (strcmp(args[myidx], "size") == 0) {
4134 myidx++;
4135 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004136 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4137 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004138 err_code |= ERR_ALERT | ERR_FATAL;
4139 goto out;
4140 }
4141 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004142 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4143 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004144 err_code |= ERR_ALERT | ERR_FATAL;
4145 goto out;
4146 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004147 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004148 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004149 else if (strcmp(args[myidx], "peers") == 0) {
4150 myidx++;
Godbach50523162013-12-11 19:48:57 +08004151 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004152 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4153 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004154 err_code |= ERR_ALERT | ERR_FATAL;
4155 goto out;
Godbach50523162013-12-11 19:48:57 +08004156 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004157 curproxy->table.peers.name = strdup(args[myidx++]);
4158 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004159 else if (strcmp(args[myidx], "expire") == 0) {
4160 myidx++;
4161 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004162 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4163 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004164 err_code |= ERR_ALERT | ERR_FATAL;
4165 goto out;
4166 }
4167 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4168 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004169 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4170 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004171 err_code |= ERR_ALERT | ERR_FATAL;
4172 goto out;
4173 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004174 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004175 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4176 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004177 err_code |= ERR_ALERT | ERR_FATAL;
4178 goto out;
4179 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004180 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004181 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004182 }
4183 else if (strcmp(args[myidx], "nopurge") == 0) {
4184 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004185 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004186 }
4187 else if (strcmp(args[myidx], "type") == 0) {
4188 myidx++;
4189 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004190 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4191 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004192 err_code |= ERR_ALERT | ERR_FATAL;
4193 goto out;
4194 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004195 /* myidx already points to next arg */
4196 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004197 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004198 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004199 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004200
4201 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004202 nw = args[myidx];
4203 while (*nw) {
4204 /* the "store" keyword supports a comma-separated list */
4205 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004206 sa = NULL; /* store arg */
4207 while (*nw && *nw != ',') {
4208 if (*nw == '(') {
4209 *nw = 0;
4210 sa = ++nw;
4211 while (*nw != ')') {
4212 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004213 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4214 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004215 err_code |= ERR_ALERT | ERR_FATAL;
4216 goto out;
4217 }
4218 nw++;
4219 }
4220 *nw = '\0';
4221 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004222 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004223 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004224 if (*nw)
4225 *nw++ = '\0';
4226 type = stktable_get_data_type(cw);
4227 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004228 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4229 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004230 err_code |= ERR_ALERT | ERR_FATAL;
4231 goto out;
4232 }
Willy Tarreauac782882010-06-20 10:41:54 +02004233
4234 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4235 switch (err) {
4236 case PE_NONE: break;
4237 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004238 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4239 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004240 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004241 break;
4242
4243 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004244 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4245 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004246 err_code |= ERR_ALERT | ERR_FATAL;
4247 goto out;
4248
4249 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004250 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4251 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004252 err_code |= ERR_ALERT | ERR_FATAL;
4253 goto out;
4254
4255 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004256 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4257 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004258 err_code |= ERR_ALERT | ERR_FATAL;
4259 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004260 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004261 }
4262 myidx++;
4263 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004264 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004265 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4266 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004267 err_code |= ERR_ALERT | ERR_FATAL;
4268 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004269 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004270 }
4271
4272 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004273 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4274 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004275 err_code |= ERR_ALERT | ERR_FATAL;
4276 goto out;
4277 }
4278
4279 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004280 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4281 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004282 err_code |= ERR_ALERT | ERR_FATAL;
4283 goto out;
4284 }
4285 }
4286 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004287 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004288 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004289 int myidx = 0;
4290 const char *name = NULL;
4291 int flags;
4292
4293 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004294 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004295 err_code |= ERR_ALERT | ERR_FATAL;
4296 goto out;
4297 }
4298
4299 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4300 err_code |= ERR_WARN;
4301 goto out;
4302 }
4303
4304 myidx++;
4305 if ((strcmp(args[myidx], "store") == 0) ||
4306 (strcmp(args[myidx], "store-request") == 0)) {
4307 myidx++;
4308 flags = STK_IS_STORE;
4309 }
4310 else if (strcmp(args[myidx], "store-response") == 0) {
4311 myidx++;
4312 flags = STK_IS_STORE | STK_ON_RSP;
4313 }
4314 else if (strcmp(args[myidx], "match") == 0) {
4315 myidx++;
4316 flags = STK_IS_MATCH;
4317 }
4318 else if (strcmp(args[myidx], "on") == 0) {
4319 myidx++;
4320 flags = STK_IS_MATCH | STK_IS_STORE;
4321 }
4322 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004323 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004324 err_code |= ERR_ALERT | ERR_FATAL;
4325 goto out;
4326 }
4327
4328 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004329 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004330 err_code |= ERR_ALERT | ERR_FATAL;
4331 goto out;
4332 }
4333
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004334 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004335 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004336 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004337 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004338 err_code |= ERR_ALERT | ERR_FATAL;
4339 goto out;
4340 }
4341
4342 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004343 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004344 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4345 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004346 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004347 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004348 goto out;
4349 }
4350 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004351 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004352 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4353 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004354 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004355 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004356 goto out;
4357 }
4358 }
4359
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004360 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004361 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004362
Emeric Brunb982a3d2010-01-04 15:45:53 +01004363 if (strcmp(args[myidx], "table") == 0) {
4364 myidx++;
4365 name = args[myidx++];
4366 }
4367
Willy Tarreauef6494c2010-01-28 17:12:36 +01004368 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004369 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004370 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4371 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004372 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004373 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004374 goto out;
4375 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004376 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004377 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004378 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4379 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004380 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004381 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004382 goto out;
4383 }
Emeric Brun97679e72010-09-23 17:56:44 +02004384 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004385 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004386 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004387 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004388
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004389 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004390 rule->cond = cond;
4391 rule->expr = expr;
4392 rule->flags = flags;
4393 rule->table.name = name ? strdup(name) : NULL;
4394 LIST_INIT(&rule->list);
4395 if (flags & STK_ON_RSP)
4396 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4397 else
4398 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4399 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004400 else if (!strcmp(args[0], "stats")) {
4401 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4402 curproxy->uri_auth = NULL; /* we must detach from the default config */
4403
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004404 if (!*args[1]) {
4405 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004406 } else if (!strcmp(args[1], "admin")) {
4407 struct stats_admin_rule *rule;
4408
4409 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004410 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 +02004411 err_code |= ERR_ALERT | ERR_FATAL;
4412 goto out;
4413 }
4414
4415 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004416 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004417 err_code |= ERR_ALERT | ERR_ABORT;
4418 goto out;
4419 }
4420
4421 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004422 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4423 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004424 err_code |= ERR_ALERT | ERR_FATAL;
4425 goto out;
4426 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004427 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004428 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4429 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004430 err_code |= ERR_ALERT | ERR_FATAL;
4431 goto out;
4432 }
4433
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004434 err_code |= warnif_cond_conflicts(cond,
4435 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4436 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004437
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004438 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004439 rule->cond = cond;
4440 LIST_INIT(&rule->list);
4441 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004442 } else if (!strcmp(args[1], "uri")) {
4443 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004444 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004445 err_code |= ERR_ALERT | ERR_FATAL;
4446 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004447 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004448 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004449 err_code |= ERR_ALERT | ERR_ABORT;
4450 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004451 }
4452 } else if (!strcmp(args[1], "realm")) {
4453 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004454 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004455 err_code |= ERR_ALERT | ERR_FATAL;
4456 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004457 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004458 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004459 err_code |= ERR_ALERT | ERR_ABORT;
4460 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004461 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004462 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004463 unsigned interval;
4464
4465 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4466 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004467 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4468 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004469 err_code |= ERR_ALERT | ERR_FATAL;
4470 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004471 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
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 Tarreaubbd42122007-07-25 07:26:38 +02004475 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004476 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004477 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004478
4479 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004480 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004481 err_code |= ERR_ALERT | ERR_FATAL;
4482 goto out;
4483 }
4484
4485 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004486 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004487 err_code |= ERR_ALERT | ERR_ABORT;
4488 goto out;
4489 }
4490
Willy Tarreauff011f22011-01-06 17:51:27 +01004491 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004492 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004493 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4494 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004495 err_code |= ERR_WARN;
4496 }
4497
Willy Tarreauff011f22011-01-06 17:51:27 +01004498 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004499
Willy Tarreauff011f22011-01-06 17:51:27 +01004500 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004501 err_code |= ERR_ALERT | ERR_ABORT;
4502 goto out;
4503 }
4504
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004505 err_code |= warnif_cond_conflicts(rule->cond,
4506 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4507 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004508 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004509
Willy Tarreaubaaee002006-06-26 02:48:02 +02004510 } else if (!strcmp(args[1], "auth")) {
4511 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004512 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004513 err_code |= ERR_ALERT | ERR_FATAL;
4514 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004515 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004516 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004517 err_code |= ERR_ALERT | ERR_ABORT;
4518 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004519 }
4520 } else if (!strcmp(args[1], "scope")) {
4521 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004522 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004523 err_code |= ERR_ALERT | ERR_FATAL;
4524 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004525 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004526 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004527 err_code |= ERR_ALERT | ERR_ABORT;
4528 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004529 }
4530 } else if (!strcmp(args[1], "enable")) {
4531 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004532 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004533 err_code |= ERR_ALERT | ERR_ABORT;
4534 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004535 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004536 } else if (!strcmp(args[1], "hide-version")) {
4537 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004538 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004539 err_code |= ERR_ALERT | ERR_ABORT;
4540 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004541 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004542 } else if (!strcmp(args[1], "show-legends")) {
4543 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004544 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004545 err_code |= ERR_ALERT | ERR_ABORT;
4546 goto out;
4547 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004548 } else if (!strcmp(args[1], "show-node")) {
4549
4550 if (*args[2]) {
4551 int i;
4552 char c;
4553
4554 for (i=0; args[2][i]; i++) {
4555 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004556 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4557 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004558 break;
4559 }
4560
4561 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004562 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4563 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4564 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004565 err_code |= ERR_ALERT | ERR_FATAL;
4566 goto out;
4567 }
4568 }
4569
4570 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004571 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004572 err_code |= ERR_ALERT | ERR_ABORT;
4573 goto out;
4574 }
4575 } else if (!strcmp(args[1], "show-desc")) {
4576 char *desc = NULL;
4577
4578 if (*args[2]) {
4579 int i, len=0;
4580 char *d;
4581
Willy Tarreau348acfe2014-04-14 15:00:39 +02004582 for (i = 2; *args[i]; i++)
4583 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004584
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004585 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004586
Willy Tarreau348acfe2014-04-14 15:00:39 +02004587 d += snprintf(d, desc + len - d, "%s", args[2]);
4588 for (i = 3; *args[i]; i++)
4589 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004590 }
4591
4592 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004593 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4594 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004595 else {
4596 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4597 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004598 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004599 err_code |= ERR_ALERT | ERR_ABORT;
4600 goto out;
4601 }
4602 free(desc);
4603 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004604 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004605stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004606 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4607 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004608 err_code |= ERR_ALERT | ERR_FATAL;
4609 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004610 }
4611 }
4612 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004613 int optnum;
4614
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004615 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004616 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4617 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004618 err_code |= ERR_ALERT | ERR_FATAL;
4619 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004620 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004621
4622 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4623 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004624 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004625 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4626 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004627 err_code |= ERR_ALERT | ERR_FATAL;
4628 goto out;
4629 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004630 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4631 goto out;
4632
Willy Tarreau93893792009-07-23 13:19:11 +02004633 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4634 err_code |= ERR_WARN;
4635 goto out;
4636 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004637
Willy Tarreau3842f002009-06-14 11:39:52 +02004638 curproxy->no_options &= ~cfg_opts[optnum].val;
4639 curproxy->options &= ~cfg_opts[optnum].val;
4640
4641 switch (kwm) {
4642 case KWM_STD:
4643 curproxy->options |= cfg_opts[optnum].val;
4644 break;
4645 case KWM_NO:
4646 curproxy->no_options |= cfg_opts[optnum].val;
4647 break;
4648 case KWM_DEF: /* already cleared */
4649 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004650 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004651
Willy Tarreau93893792009-07-23 13:19:11 +02004652 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004653 }
4654 }
4655
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004656 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4657 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004658 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004659 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4660 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004661 err_code |= ERR_ALERT | ERR_FATAL;
4662 goto out;
4663 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004664 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4665 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004666 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4667 err_code |= ERR_WARN;
4668 goto out;
4669 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004670
Willy Tarreau3842f002009-06-14 11:39:52 +02004671 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4672 curproxy->options2 &= ~cfg_opts2[optnum].val;
4673
4674 switch (kwm) {
4675 case KWM_STD:
4676 curproxy->options2 |= cfg_opts2[optnum].val;
4677 break;
4678 case KWM_NO:
4679 curproxy->no_options2 |= cfg_opts2[optnum].val;
4680 break;
4681 case KWM_DEF: /* already cleared */
4682 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004683 }
Willy Tarreau93893792009-07-23 13:19:11 +02004684 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004685 }
4686 }
4687
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004688 /* HTTP options override each other. They can be cancelled using
4689 * "no option xxx" which only switches to default mode if the mode
4690 * was this one (useful for cancelling options set in defaults
4691 * sections).
4692 */
4693 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004694 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4695 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004696 if (kwm == KWM_STD) {
4697 curproxy->options &= ~PR_O_HTTP_MODE;
4698 curproxy->options |= PR_O_HTTP_PCL;
4699 goto out;
4700 }
4701 else if (kwm == KWM_NO) {
4702 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4703 curproxy->options &= ~PR_O_HTTP_MODE;
4704 goto out;
4705 }
4706 }
4707 else if (strcmp(args[1], "forceclose") == 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_FCL;
4713 goto out;
4714 }
4715 else if (kwm == KWM_NO) {
4716 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4717 curproxy->options &= ~PR_O_HTTP_MODE;
4718 goto out;
4719 }
4720 }
4721 else if (strcmp(args[1], "http-server-close") == 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_SCL;
4727 goto out;
4728 }
4729 else if (kwm == KWM_NO) {
4730 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4731 curproxy->options &= ~PR_O_HTTP_MODE;
4732 goto out;
4733 }
4734 }
4735 else if (strcmp(args[1], "http-keep-alive") == 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_KAL;
4741 goto out;
4742 }
4743 else if (kwm == KWM_NO) {
4744 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4745 curproxy->options &= ~PR_O_HTTP_MODE;
4746 goto out;
4747 }
4748 }
4749 else if (strcmp(args[1], "http-tunnel") == 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_TUN;
4755 goto out;
4756 }
4757 else if (kwm == KWM_NO) {
4758 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4759 curproxy->options &= ~PR_O_HTTP_MODE;
4760 goto out;
4761 }
4762 }
4763
Joseph Lynch726ab712015-05-11 23:25:34 -07004764 /* Redispatch can take an integer argument that control when the
4765 * resispatch occurs. All values are relative to the retries option.
4766 * This can be cancelled using "no option xxx".
4767 */
4768 if (strcmp(args[1], "redispatch") == 0) {
4769 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4770 err_code |= ERR_WARN;
4771 goto out;
4772 }
4773
4774 curproxy->no_options &= ~PR_O_REDISP;
4775 curproxy->options &= ~PR_O_REDISP;
4776
4777 switch (kwm) {
4778 case KWM_STD:
4779 curproxy->options |= PR_O_REDISP;
4780 curproxy->redispatch_after = -1;
4781 if(*args[2]) {
4782 curproxy->redispatch_after = atol(args[2]);
4783 }
4784 break;
4785 case KWM_NO:
4786 curproxy->no_options |= PR_O_REDISP;
4787 curproxy->redispatch_after = 0;
4788 break;
4789 case KWM_DEF: /* already cleared */
4790 break;
4791 }
4792 goto out;
4793 }
4794
Willy Tarreau3842f002009-06-14 11:39:52 +02004795 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004796 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4797 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004798 err_code |= ERR_ALERT | ERR_FATAL;
4799 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004800 }
4801
Emeric Brun3a058f32009-06-30 18:26:00 +02004802 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004803 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004804 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004805 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004806 if (*(args[2]) != '\0') {
4807 if (!strcmp(args[2], "clf")) {
4808 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004809 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004810 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004811 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004812 err_code |= ERR_ALERT | ERR_FATAL;
4813 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004814 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004815 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4816 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004817 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004818 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4819 char *oldlogformat = "log-format";
4820 char *clflogformat = "";
4821
4822 if (curproxy->conf.logformat_string == default_http_log_format)
4823 oldlogformat = "option httplog";
4824 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4825 oldlogformat = "option tcplog";
4826 else if (curproxy->conf.logformat_string == clf_http_log_format)
4827 oldlogformat = "option httplog clf";
4828 if (logformat == clf_http_log_format)
4829 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004830 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4831 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004832 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004833 if (curproxy->conf.logformat_string != default_http_log_format &&
4834 curproxy->conf.logformat_string != default_tcp_log_format &&
4835 curproxy->conf.logformat_string != clf_http_log_format)
4836 free(curproxy->conf.logformat_string);
4837 curproxy->conf.logformat_string = logformat;
4838
4839 free(curproxy->conf.lfs_file);
4840 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4841 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004842
4843 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4844 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4845 file, linenum, curproxy->id);
4846 err_code |= ERR_WARN;
4847 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004848 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004849 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004850 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4851 char *oldlogformat = "log-format";
4852
4853 if (curproxy->conf.logformat_string == default_http_log_format)
4854 oldlogformat = "option httplog";
4855 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4856 oldlogformat = "option tcplog";
4857 else if (curproxy->conf.logformat_string == clf_http_log_format)
4858 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004859 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4860 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004861 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004862 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004863 if (curproxy->conf.logformat_string != default_http_log_format &&
4864 curproxy->conf.logformat_string != default_tcp_log_format &&
4865 curproxy->conf.logformat_string != clf_http_log_format)
4866 free(curproxy->conf.logformat_string);
4867 curproxy->conf.logformat_string = default_tcp_log_format;
4868
4869 free(curproxy->conf.lfs_file);
4870 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4871 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004872
4873 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4874 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004875
4876 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4877 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4878 file, linenum, curproxy->id);
4879 err_code |= ERR_WARN;
4880 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004881 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004882 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004883 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004884 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004885 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004886
William Lallemanddf1425a2015-04-28 20:17:49 +02004887 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4888 goto out;
4889
Willy Tarreau13943ab2006-12-31 00:24:10 +01004890 if (curproxy->cap & PR_CAP_FE)
4891 curproxy->options |= PR_O_TCP_CLI_KA;
4892 if (curproxy->cap & PR_CAP_BE)
4893 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004894 }
4895 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004896 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004897 err_code |= ERR_WARN;
4898
Willy Tarreaubaaee002006-06-26 02:48:02 +02004899 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004900 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004901 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004902 curproxy->options2 &= ~PR_O2_CHK_ANY;
4903 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004904 if (!*args[2]) { /* no argument */
4905 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4906 curproxy->check_len = strlen(DEF_CHECK_REQ);
4907 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004908 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004909 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004910 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004911 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004912 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004913 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004914 if (*args[4])
4915 reqlen += strlen(args[4]);
4916 else
4917 reqlen += strlen("HTTP/1.0");
4918
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004919 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004920 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004921 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004922 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004923 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4924 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004925 }
4926 else if (!strcmp(args[1], "ssl-hello-chk")) {
4927 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004928 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004929 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004930
Willy Tarreaua534fea2008-08-03 12:19:50 +02004931 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004932 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004933 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004934 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004935
4936 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4937 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004938 }
Willy Tarreau23677902007-05-08 23:50:35 +02004939 else if (!strcmp(args[1], "smtpchk")) {
4940 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004941 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004942 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004943 curproxy->options2 &= ~PR_O2_CHK_ANY;
4944 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004945
4946 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4947 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4948 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4949 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4950 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4951 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004952 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004953 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4954 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4955 } else {
4956 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4957 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4958 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4959 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4960 }
4961 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004962 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4963 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004964 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004965 else if (!strcmp(args[1], "pgsql-check")) {
4966 /* use PostgreSQL request to check servers' health */
4967 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4968 err_code |= ERR_WARN;
4969
4970 free(curproxy->check_req);
4971 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004972 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004973 curproxy->options2 |= PR_O2_PGSQL_CHK;
4974
4975 if (*(args[2])) {
4976 int cur_arg = 2;
4977
4978 while (*(args[cur_arg])) {
4979 if (strcmp(args[cur_arg], "user") == 0) {
4980 char * packet;
4981 uint32_t packet_len;
4982 uint32_t pv;
4983
4984 /* suboption header - needs additional argument for it */
4985 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004986 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4987 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004988 err_code |= ERR_ALERT | ERR_FATAL;
4989 goto out;
4990 }
4991
4992 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4993 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4994 pv = htonl(0x30000); /* protocol version 3.0 */
4995
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004996 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004997
4998 memcpy(packet + 4, &pv, 4);
4999
5000 /* copy "user" */
5001 memcpy(packet + 8, "user", 4);
5002
5003 /* copy username */
5004 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
5005
5006 free(curproxy->check_req);
5007 curproxy->check_req = packet;
5008 curproxy->check_len = packet_len;
5009
5010 packet_len = htonl(packet_len);
5011 memcpy(packet, &packet_len, 4);
5012 cur_arg += 2;
5013 } else {
5014 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005015 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5016 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005017 err_code |= ERR_ALERT | ERR_FATAL;
5018 goto out;
5019 }
5020 } /* end while loop */
5021 }
William Lallemanddf1425a2015-04-28 20:17:49 +02005022 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
5023 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005024 }
5025
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005026 else if (!strcmp(args[1], "redis-check")) {
5027 /* use REDIS PING request to check servers' health */
5028 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5029 err_code |= ERR_WARN;
5030
5031 free(curproxy->check_req);
5032 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005033 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005034 curproxy->options2 |= PR_O2_REDIS_CHK;
5035
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005036 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005037 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5038 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005039
5040 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5041 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005042 }
5043
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005044 else if (!strcmp(args[1], "mysql-check")) {
5045 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005046 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5047 err_code |= ERR_WARN;
5048
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005049 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005050 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005051 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005052 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005053
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005054 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005055 * const char mysql40_client_auth_pkt[] = {
5056 * "\x0e\x00\x00" // packet length
5057 * "\x01" // packet number
5058 * "\x00\x00" // client capabilities
5059 * "\x00\x00\x01" // max packet
5060 * "haproxy\x00" // username (null terminated string)
5061 * "\x00" // filler (always 0x00)
5062 * "\x01\x00\x00" // packet length
5063 * "\x00" // packet number
5064 * "\x01" // COM_QUIT command
5065 * };
5066 */
5067
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005068 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5069 * const char mysql41_client_auth_pkt[] = {
5070 * "\x0e\x00\x00\" // packet length
5071 * "\x01" // packet number
5072 * "\x00\x00\x00\x00" // client capabilities
5073 * "\x00\x00\x00\x01" // max packet
5074 * "\x21" // character set (UTF-8)
5075 * char[23] // All zeroes
5076 * "haproxy\x00" // username (null terminated string)
5077 * "\x00" // filler (always 0x00)
5078 * "\x01\x00\x00" // packet length
5079 * "\x00" // packet number
5080 * "\x01" // COM_QUIT command
5081 * };
5082 */
5083
5084
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005085 if (*(args[2])) {
5086 int cur_arg = 2;
5087
5088 while (*(args[cur_arg])) {
5089 if (strcmp(args[cur_arg], "user") == 0) {
5090 char *mysqluser;
5091 int packetlen, reqlen, userlen;
5092
5093 /* suboption header - needs additional argument for it */
5094 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005095 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5096 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005097 err_code |= ERR_ALERT | ERR_FATAL;
5098 goto out;
5099 }
5100 mysqluser = args[cur_arg + 1];
5101 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005102
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005103 if (*(args[cur_arg+2])) {
5104 if (!strcmp(args[cur_arg+2], "post-41")) {
5105 packetlen = userlen + 7 + 27;
5106 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005107
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005108 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005109 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005110 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005111
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005112 snprintf(curproxy->check_req, 4, "%c%c%c",
5113 ((unsigned char) packetlen & 0xff),
5114 ((unsigned char) (packetlen >> 8) & 0xff),
5115 ((unsigned char) (packetlen >> 16) & 0xff));
5116
5117 curproxy->check_req[3] = 1;
5118 curproxy->check_req[5] = 130;
5119 curproxy->check_req[11] = 1;
5120 curproxy->check_req[12] = 33;
5121 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5122 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5123 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5124 cur_arg += 3;
5125 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005126 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 +02005127 err_code |= ERR_ALERT | ERR_FATAL;
5128 goto out;
5129 }
5130 } else {
5131 packetlen = userlen + 7;
5132 reqlen = packetlen + 9;
5133
5134 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005135 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005136 curproxy->check_len = reqlen;
5137
5138 snprintf(curproxy->check_req, 4, "%c%c%c",
5139 ((unsigned char) packetlen & 0xff),
5140 ((unsigned char) (packetlen >> 8) & 0xff),
5141 ((unsigned char) (packetlen >> 16) & 0xff));
5142
5143 curproxy->check_req[3] = 1;
5144 curproxy->check_req[5] = 128;
5145 curproxy->check_req[8] = 1;
5146 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5147 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5148 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5149 cur_arg += 2;
5150 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005151 } else {
5152 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005153 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5154 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005155 err_code |= ERR_ALERT | ERR_FATAL;
5156 goto out;
5157 }
5158 } /* end while loop */
5159 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005160 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005161 else if (!strcmp(args[1], "ldap-check")) {
5162 /* use LDAP request to check servers' health */
5163 free(curproxy->check_req);
5164 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005165 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005166 curproxy->options2 |= PR_O2_LDAP_CHK;
5167
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005168 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005169 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5170 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005171 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5172 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005173 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005174 else if (!strcmp(args[1], "spop-check")) {
5175 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005176 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5177 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005178 err_code |= ERR_ALERT | ERR_FATAL;
5179 goto out;
5180 }
5181 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005182 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5183 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005184 err_code |= ERR_ALERT | ERR_FATAL;
5185 goto out;
5186 }
5187
5188 /* use SPOE request to check servers' health */
5189 free(curproxy->check_req);
5190 curproxy->check_req = NULL;
5191 curproxy->options2 &= ~PR_O2_CHK_ANY;
5192 curproxy->options2 |= PR_O2_SPOP_CHK;
5193
Christopher Faulet8ef75252017-02-20 22:56:03 +01005194 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005195 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005196 err_code |= ERR_ALERT | ERR_FATAL;
5197 goto out;
5198 }
5199 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5200 goto out;
5201 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005202 else if (!strcmp(args[1], "tcp-check")) {
5203 /* use raw TCPCHK send/expect to check servers' health */
5204 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5205 err_code |= ERR_WARN;
5206
5207 free(curproxy->check_req);
5208 curproxy->check_req = NULL;
5209 curproxy->options2 &= ~PR_O2_CHK_ANY;
5210 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005211 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5212 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005213 }
Simon Horman98637e52014-06-20 12:30:16 +09005214 else if (!strcmp(args[1], "external-check")) {
5215 /* excute an external command to check servers' health */
5216 free(curproxy->check_req);
5217 curproxy->check_req = NULL;
5218 curproxy->options2 &= ~PR_O2_CHK_ANY;
5219 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005220 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5221 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005222 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005223 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005224 int cur_arg;
5225
5226 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5227 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005228 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005229
Willy Tarreau87cf5142011-08-19 22:57:24 +02005230 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005231
5232 free(curproxy->fwdfor_hdr_name);
5233 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5234 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5235
5236 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5237 cur_arg = 2;
5238 while (*(args[cur_arg])) {
5239 if (!strcmp(args[cur_arg], "except")) {
5240 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005241 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005242 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5243 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005244 err_code |= ERR_ALERT | ERR_FATAL;
5245 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005246 }
5247 /* flush useless bits */
5248 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005249 cur_arg += 2;
5250 } else if (!strcmp(args[cur_arg], "header")) {
5251 /* suboption header - needs additional argument for it */
5252 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005253 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5254 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005255 err_code |= ERR_ALERT | ERR_FATAL;
5256 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005257 }
5258 free(curproxy->fwdfor_hdr_name);
5259 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5260 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5261 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005262 } else if (!strcmp(args[cur_arg], "if-none")) {
5263 curproxy->options &= ~PR_O_FF_ALWAYS;
5264 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005265 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005266 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005267 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5268 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005269 err_code |= ERR_ALERT | ERR_FATAL;
5270 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005271 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005272 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005273 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005274 else if (!strcmp(args[1], "originalto")) {
5275 int cur_arg;
5276
5277 /* insert x-original-to field, but not for the IP address listed as an except.
5278 * set default options (ie: bitfield, header name, etc)
5279 */
5280
5281 curproxy->options |= PR_O_ORGTO;
5282
5283 free(curproxy->orgto_hdr_name);
5284 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5285 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5286
Willy Tarreau87cf5142011-08-19 22:57:24 +02005287 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005288 cur_arg = 2;
5289 while (*(args[cur_arg])) {
5290 if (!strcmp(args[cur_arg], "except")) {
5291 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005292 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 +01005293 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5294 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005295 err_code |= ERR_ALERT | ERR_FATAL;
5296 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005297 }
5298 /* flush useless bits */
5299 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5300 cur_arg += 2;
5301 } else if (!strcmp(args[cur_arg], "header")) {
5302 /* suboption header - needs additional argument for it */
5303 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005304 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5305 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005306 err_code |= ERR_ALERT | ERR_FATAL;
5307 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005308 }
5309 free(curproxy->orgto_hdr_name);
5310 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5311 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5312 cur_arg += 2;
5313 } else {
5314 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005315 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5316 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005317 err_code |= ERR_ALERT | ERR_FATAL;
5318 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005319 }
5320 } /* end while loop */
5321 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005322 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005323 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005324 err_code |= ERR_ALERT | ERR_FATAL;
5325 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005326 }
Willy Tarreau93893792009-07-23 13:19:11 +02005327 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005328 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005329 else if (!strcmp(args[0], "default_backend")) {
5330 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005331 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005332
5333 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005334 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005335 err_code |= ERR_ALERT | ERR_FATAL;
5336 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005337 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005338 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005339 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005340
5341 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5342 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005343 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005344 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005345 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005346 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005347
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005348 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005349 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5350 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005351 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005352 /* enable reconnections to dispatch */
5353 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005354
5355 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5356 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005357 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005358 else if (!strcmp(args[0], "http-reuse")) {
5359 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5360 err_code |= ERR_WARN;
5361
5362 if (strcmp(args[1], "never") == 0) {
5363 /* enable a graceful server shutdown on an HTTP 404 response */
5364 curproxy->options &= ~PR_O_REUSE_MASK;
5365 curproxy->options |= PR_O_REUSE_NEVR;
5366 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5367 goto out;
5368 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005369 else if (strcmp(args[1], "safe") == 0) {
5370 /* enable a graceful server shutdown on an HTTP 404 response */
5371 curproxy->options &= ~PR_O_REUSE_MASK;
5372 curproxy->options |= PR_O_REUSE_SAFE;
5373 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5374 goto out;
5375 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005376 else if (strcmp(args[1], "aggressive") == 0) {
5377 curproxy->options &= ~PR_O_REUSE_MASK;
5378 curproxy->options |= PR_O_REUSE_AGGR;
5379 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5380 goto out;
5381 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005382 else if (strcmp(args[1], "always") == 0) {
5383 /* enable a graceful server shutdown on an HTTP 404 response */
5384 curproxy->options &= ~PR_O_REUSE_MASK;
5385 curproxy->options |= PR_O_REUSE_ALWS;
5386 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5387 goto out;
5388 }
5389 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005390 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005391 err_code |= ERR_ALERT | ERR_FATAL;
5392 goto out;
5393 }
5394 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005395 else if (!strcmp(args[0], "http-check")) {
5396 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005397 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005398
5399 if (strcmp(args[1], "disable-on-404") == 0) {
5400 /* enable a graceful server shutdown on an HTTP 404 response */
5401 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005402 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5403 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005404 }
Willy Tarreauef781042010-01-27 11:53:01 +01005405 else if (strcmp(args[1], "send-state") == 0) {
5406 /* enable emission of the apparent state of a server in HTTP checks */
5407 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005408 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5409 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005410 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005411 else if (strcmp(args[1], "expect") == 0) {
5412 const char *ptr_arg;
5413 int cur_arg;
5414
5415 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005416 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005417 err_code |= ERR_ALERT | ERR_FATAL;
5418 goto out;
5419 }
5420
5421 cur_arg = 2;
5422 /* consider exclamation marks, sole or at the beginning of a word */
5423 while (*(ptr_arg = args[cur_arg])) {
5424 while (*ptr_arg == '!') {
5425 curproxy->options2 ^= PR_O2_EXP_INV;
5426 ptr_arg++;
5427 }
5428 if (*ptr_arg)
5429 break;
5430 cur_arg++;
5431 }
5432 /* now ptr_arg points to the beginning of a word past any possible
5433 * exclamation mark, and cur_arg is the argument which holds this word.
5434 */
5435 if (strcmp(ptr_arg, "status") == 0) {
5436 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005437 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5438 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005439 err_code |= ERR_ALERT | ERR_FATAL;
5440 goto out;
5441 }
5442 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005443 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005444 curproxy->expect_str = strdup(args[cur_arg + 1]);
5445 }
5446 else if (strcmp(ptr_arg, "string") == 0) {
5447 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005448 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5449 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005450 err_code |= ERR_ALERT | ERR_FATAL;
5451 goto out;
5452 }
5453 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005454 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005455 curproxy->expect_str = strdup(args[cur_arg + 1]);
5456 }
5457 else if (strcmp(ptr_arg, "rstatus") == 0) {
5458 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005459 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5460 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005461 err_code |= ERR_ALERT | ERR_FATAL;
5462 goto out;
5463 }
5464 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005465 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005466 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005467 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005468 free(curproxy->expect_regex);
5469 curproxy->expect_regex = NULL;
5470 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005471 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005472 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5473 error = NULL;
5474 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005475 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5476 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005477 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005478 err_code |= ERR_ALERT | ERR_FATAL;
5479 goto out;
5480 }
5481 }
5482 else if (strcmp(ptr_arg, "rstring") == 0) {
5483 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005484 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5485 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005486 err_code |= ERR_ALERT | ERR_FATAL;
5487 goto out;
5488 }
5489 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005490 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005491 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005492 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005493 free(curproxy->expect_regex);
5494 curproxy->expect_regex = NULL;
5495 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005496 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005497 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5498 error = NULL;
5499 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005500 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5501 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005502 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005503 err_code |= ERR_ALERT | ERR_FATAL;
5504 goto out;
5505 }
5506 }
5507 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005508 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5509 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005510 err_code |= ERR_ALERT | ERR_FATAL;
5511 goto out;
5512 }
5513 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005514 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005515 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 +02005516 err_code |= ERR_ALERT | ERR_FATAL;
5517 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005518 }
5519 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005520 else if (!strcmp(args[0], "tcp-check")) {
5521 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5522 err_code |= ERR_WARN;
5523
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005524 if (strcmp(args[1], "comment") == 0) {
5525 int cur_arg;
5526 struct tcpcheck_rule *tcpcheck;
5527
5528 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005529 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005530 tcpcheck->action = TCPCHK_ACT_COMMENT;
5531
5532 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005533 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5534 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005535 err_code |= ERR_ALERT | ERR_FATAL;
5536 goto out;
5537 }
5538
5539 tcpcheck->comment = strdup(args[cur_arg + 1]);
5540
5541 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005542 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5543 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005544 }
5545 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005546 const char *ptr_arg;
5547 int cur_arg;
5548 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005549
5550 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005551 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5552 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5553 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5554 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5555 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005556
Willy Tarreau5581c272015-05-13 12:24:53 +02005557 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5558 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005559 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5560 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005561 err_code |= ERR_ALERT | ERR_FATAL;
5562 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005563 }
5564
5565 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005566 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005567 tcpcheck->action = TCPCHK_ACT_CONNECT;
5568
5569 /* parsing each parameters to fill up the rule */
5570 while (*(ptr_arg = args[cur_arg])) {
5571 /* tcp port */
5572 if (strcmp(args[cur_arg], "port") == 0) {
5573 if ( (atol(args[cur_arg + 1]) > 65535) ||
5574 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005575 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5576 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005577 err_code |= ERR_ALERT | ERR_FATAL;
5578 goto out;
5579 }
5580 tcpcheck->port = atol(args[cur_arg + 1]);
5581 cur_arg += 2;
5582 }
5583 /* send proxy protocol */
5584 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5585 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5586 cur_arg++;
5587 }
5588#ifdef USE_OPENSSL
5589 else if (strcmp(args[cur_arg], "ssl") == 0) {
5590 curproxy->options |= PR_O_TCPCHK_SSL;
5591 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5592 cur_arg++;
5593 }
5594#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005595 /* comment for this tcpcheck line */
5596 else if (strcmp(args[cur_arg], "comment") == 0) {
5597 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005598 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5599 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005600 err_code |= ERR_ALERT | ERR_FATAL;
5601 goto out;
5602 }
5603 tcpcheck->comment = strdup(args[cur_arg + 1]);
5604 cur_arg += 2;
5605 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005606 else {
5607#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005608 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 +01005609#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005610 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 +01005611#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005612 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005613 err_code |= ERR_ALERT | ERR_FATAL;
5614 goto out;
5615 }
5616
5617 }
5618
5619 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5620 }
5621 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005622 if (! *(args[2]) ) {
5623 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005624 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5625 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005626 err_code |= ERR_ALERT | ERR_FATAL;
5627 goto out;
5628 } else {
5629 struct tcpcheck_rule *tcpcheck;
5630
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005631 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005632
5633 tcpcheck->action = TCPCHK_ACT_SEND;
5634 tcpcheck->string_len = strlen(args[2]);
5635 tcpcheck->string = strdup(args[2]);
5636 tcpcheck->expect_regex = NULL;
5637
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005638 /* comment for this tcpcheck line */
5639 if (strcmp(args[3], "comment") == 0) {
5640 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005641 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5642 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005643 err_code |= ERR_ALERT | ERR_FATAL;
5644 goto out;
5645 }
5646 tcpcheck->comment = strdup(args[4]);
5647 }
5648
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005649 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5650 }
5651 }
5652 else if (strcmp(args[1], "send-binary") == 0) {
5653 if (! *(args[2]) ) {
5654 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005655 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5656 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005657 err_code |= ERR_ALERT | ERR_FATAL;
5658 goto out;
5659 } else {
5660 struct tcpcheck_rule *tcpcheck;
5661 char *err = NULL;
5662
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005663 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005664
5665 tcpcheck->action = TCPCHK_ACT_SEND;
5666 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005667 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5668 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005669 err_code |= ERR_ALERT | ERR_FATAL;
5670 goto out;
5671 }
5672 tcpcheck->expect_regex = NULL;
5673
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005674 /* comment for this tcpcheck line */
5675 if (strcmp(args[3], "comment") == 0) {
5676 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005677 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5678 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005679 err_code |= ERR_ALERT | ERR_FATAL;
5680 goto out;
5681 }
5682 tcpcheck->comment = strdup(args[4]);
5683 }
5684
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005685 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5686 }
5687 }
5688 else if (strcmp(args[1], "expect") == 0) {
5689 const char *ptr_arg;
5690 int cur_arg;
5691 int inverse = 0;
5692
5693 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005694 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005695 err_code |= ERR_ALERT | ERR_FATAL;
5696 goto out;
5697 }
5698
5699 cur_arg = 2;
5700 /* consider exclamation marks, sole or at the beginning of a word */
5701 while (*(ptr_arg = args[cur_arg])) {
5702 while (*ptr_arg == '!') {
5703 inverse = !inverse;
5704 ptr_arg++;
5705 }
5706 if (*ptr_arg)
5707 break;
5708 cur_arg++;
5709 }
5710 /* now ptr_arg points to the beginning of a word past any possible
5711 * exclamation mark, and cur_arg is the argument which holds this word.
5712 */
5713 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005714 struct tcpcheck_rule *tcpcheck;
5715 char *err = NULL;
5716
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005717 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005718 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5719 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005720 err_code |= ERR_ALERT | ERR_FATAL;
5721 goto out;
5722 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005723
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005724 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005725
5726 tcpcheck->action = TCPCHK_ACT_EXPECT;
5727 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005728 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5729 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005730 err_code |= ERR_ALERT | ERR_FATAL;
5731 goto out;
5732 }
5733 tcpcheck->expect_regex = NULL;
5734 tcpcheck->inverse = inverse;
5735
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005736 /* tcpcheck comment */
5737 cur_arg += 2;
5738 if (strcmp(args[cur_arg], "comment") == 0) {
5739 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005740 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5741 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005742 err_code |= ERR_ALERT | ERR_FATAL;
5743 goto out;
5744 }
5745 tcpcheck->comment = strdup(args[cur_arg + 1]);
5746 }
5747
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005748 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5749 }
5750 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005751 struct tcpcheck_rule *tcpcheck;
5752
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005753 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005754 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5755 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005756 err_code |= ERR_ALERT | ERR_FATAL;
5757 goto out;
5758 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005759
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005760 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005761
5762 tcpcheck->action = TCPCHK_ACT_EXPECT;
5763 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5764 tcpcheck->string = strdup(args[cur_arg + 1]);
5765 tcpcheck->expect_regex = NULL;
5766 tcpcheck->inverse = inverse;
5767
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005768 /* tcpcheck comment */
5769 cur_arg += 2;
5770 if (strcmp(args[cur_arg], "comment") == 0) {
5771 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005772 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5773 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005774 err_code |= ERR_ALERT | ERR_FATAL;
5775 goto out;
5776 }
5777 tcpcheck->comment = strdup(args[cur_arg + 1]);
5778 }
5779
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005780 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5781 }
5782 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005783 struct tcpcheck_rule *tcpcheck;
5784
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005785 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005786 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5787 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005788 err_code |= ERR_ALERT | ERR_FATAL;
5789 goto out;
5790 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005791
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005792 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005793
5794 tcpcheck->action = TCPCHK_ACT_EXPECT;
5795 tcpcheck->string_len = 0;
5796 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005797 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5798 error = NULL;
5799 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005800 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5801 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005802 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005803 err_code |= ERR_ALERT | ERR_FATAL;
5804 goto out;
5805 }
5806 tcpcheck->inverse = inverse;
5807
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005808 /* tcpcheck comment */
5809 cur_arg += 2;
5810 if (strcmp(args[cur_arg], "comment") == 0) {
5811 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005812 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5813 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005814 err_code |= ERR_ALERT | ERR_FATAL;
5815 goto out;
5816 }
5817 tcpcheck->comment = strdup(args[cur_arg + 1]);
5818 }
5819
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005820 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5821 }
5822 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005823 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5824 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005825 err_code |= ERR_ALERT | ERR_FATAL;
5826 goto out;
5827 }
5828 }
5829 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005830 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 +02005831 err_code |= ERR_ALERT | ERR_FATAL;
5832 goto out;
5833 }
5834 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005835 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005836 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005837 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005838 err_code |= ERR_ALERT | ERR_FATAL;
5839 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005840 }
5841
Willy Tarreaub80c2302007-11-30 20:51:32 +01005842 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005843 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005844
5845 if (strcmp(args[1], "fail") == 0) {
5846 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005847 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005848 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5849 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005850 err_code |= ERR_ALERT | ERR_FATAL;
5851 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005852 }
5853
Willy Tarreau721d8e02017-12-01 18:25:08 +01005854 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005855 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005856 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5857 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005858 err_code |= ERR_ALERT | ERR_FATAL;
5859 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005860 }
5861 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5862 }
5863 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005864 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005865 err_code |= ERR_ALERT | ERR_FATAL;
5866 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005867 }
5868 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005869#ifdef TPROXY
5870 else if (!strcmp(args[0], "transparent")) {
5871 /* enable transparent proxy connections */
5872 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005873 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5874 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005875 }
5876#endif
5877 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005878 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005879 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005880
Willy Tarreaubaaee002006-06-26 02:48:02 +02005881 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005882 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005883 err_code |= ERR_ALERT | ERR_FATAL;
5884 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005885 }
5886 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005887 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5888 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005889 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005890 else if (!strcmp(args[0], "backlog")) { /* backlog */
5891 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005892 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005893
5894 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005895 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005896 err_code |= ERR_ALERT | ERR_FATAL;
5897 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005898 }
5899 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005900 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5901 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005902 }
Willy Tarreau86034312006-12-29 00:10:33 +01005903 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005904 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005905 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005906
Willy Tarreau86034312006-12-29 00:10:33 +01005907 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005908 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005909 err_code |= ERR_ALERT | ERR_FATAL;
5910 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005911 }
5912 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005913 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5914 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005915 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005916 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5917 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005918 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005919 err_code |= ERR_ALERT | ERR_FATAL;
5920 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005921 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005922 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5923 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005924 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5925 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005926 err_code |= ERR_ALERT | ERR_FATAL;
5927 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005928 }
5929 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005930 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5931 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005932 }
5933 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005934 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005935 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005936 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005937
Willy Tarreaubaaee002006-06-26 02:48:02 +02005938 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005939 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005940 err_code |= ERR_ALERT | ERR_FATAL;
5941 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005942 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005943 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005944 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005945
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005946 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005947 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005948 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005949 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005950 goto out;
5951 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005952
5953 proto = protocol_by_family(sk->ss_family);
5954 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005955 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5956 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005957 err_code |= ERR_ALERT | ERR_FATAL;
5958 goto out;
5959 }
5960
5961 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005962 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5963 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005964 err_code |= ERR_ALERT | ERR_FATAL;
5965 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005966 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005967
5968 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005969 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5970 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005971 err_code |= ERR_ALERT | ERR_FATAL;
5972 goto out;
5973 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005974
William Lallemanddf1425a2015-04-28 20:17:49 +02005975 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5976 goto out;
5977
Willy Tarreaud5191e72010-02-09 20:50:45 +01005978 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005979 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005980 }
5981 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005982 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005983 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005984
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005985 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005986 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005987 err_code |= ERR_ALERT | ERR_FATAL;
5988 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005989 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005990 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005991 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005992 /**
5993 * The syntax for hash-type config element is
5994 * hash-type {map-based|consistent} [[<algo>] avalanche]
5995 *
5996 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5997 */
5998 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005999
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006000 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
6001 err_code |= ERR_WARN;
6002
6003 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006004 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
6005 }
6006 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006007 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
6008 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006009 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006010 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 -05006011 err_code |= ERR_ALERT | ERR_FATAL;
6012 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01006013 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006014 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006015 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006016 err_code |= ERR_ALERT | ERR_FATAL;
6017 goto out;
6018 }
Bhaskar98634f02013-10-29 23:30:51 -04006019
6020 /* set the hash function to use */
6021 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006022 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04006023 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006024
6025 /* if consistent with no argument, then avalanche modifier is also applied */
6026 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6027 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006028 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006029 /* set the hash function */
6030 if (!strcmp(args[2], "sdbm")) {
6031 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6032 }
6033 else if (!strcmp(args[2], "djb2")) {
6034 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006035 }
6036 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006037 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006038 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006039 else if (!strcmp(args[2], "crc32")) {
6040 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6041 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006042 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006043 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 -05006044 err_code |= ERR_ALERT | ERR_FATAL;
6045 goto out;
6046 }
6047
6048 /* set the hash modifier */
6049 if (!strcmp(args[3], "avalanche")) {
6050 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6051 }
6052 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006053 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 -05006054 err_code |= ERR_ALERT | ERR_FATAL;
6055 goto out;
6056 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006057 }
William Lallemanda73203e2012-03-12 12:48:57 +01006058 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006059 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6060 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006061 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006062 err_code |= ERR_ALERT | ERR_FATAL;
6063 goto out;
6064 }
6065 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6066 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006067 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 -04006068 err_code |= ERR_ALERT | ERR_FATAL;
6069 goto out;
6070 }
6071 }
William Lallemanda73203e2012-03-12 12:48:57 +01006072 else if (strcmp(args[0], "unique-id-format") == 0) {
6073 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006074 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006075 err_code |= ERR_ALERT | ERR_FATAL;
6076 goto out;
6077 }
William Lallemand3203ff42012-11-11 17:30:56 +01006078 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006079 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 +01006080 err_code |= ERR_ALERT | ERR_FATAL;
6081 goto out;
6082 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006083 free(curproxy->conf.uniqueid_format_string);
6084 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006085
Willy Tarreau62a61232013-04-12 18:13:46 +02006086 free(curproxy->conf.uif_file);
6087 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6088 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006089 }
William Lallemanda73203e2012-03-12 12:48:57 +01006090
6091 else if (strcmp(args[0], "unique-id-header") == 0) {
6092 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006093 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006094 err_code |= ERR_ALERT | ERR_FATAL;
6095 goto out;
6096 }
6097 free(curproxy->header_unique_id);
6098 curproxy->header_unique_id = strdup(args[1]);
6099 }
6100
William Lallemand723b73a2012-02-08 16:37:49 +01006101 else if (strcmp(args[0], "log-format") == 0) {
6102 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006103 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006104 err_code |= ERR_ALERT | ERR_FATAL;
6105 goto out;
6106 }
William Lallemand3203ff42012-11-11 17:30:56 +01006107 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006108 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 +01006109 err_code |= ERR_ALERT | ERR_FATAL;
6110 goto out;
6111 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006112 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6113 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006114
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006115 if (curproxy->conf.logformat_string == default_http_log_format)
6116 oldlogformat = "option httplog";
6117 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6118 oldlogformat = "option tcplog";
6119 else if (curproxy->conf.logformat_string == clf_http_log_format)
6120 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006121 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6122 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006123 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006124 if (curproxy->conf.logformat_string != default_http_log_format &&
6125 curproxy->conf.logformat_string != default_tcp_log_format &&
6126 curproxy->conf.logformat_string != clf_http_log_format)
6127 free(curproxy->conf.logformat_string);
6128 curproxy->conf.logformat_string = strdup(args[1]);
6129
6130 free(curproxy->conf.lfs_file);
6131 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6132 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006133
6134 /* get a chance to improve log-format error reporting by
6135 * reporting the correct line-number when possible.
6136 */
6137 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006138 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6139 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006140 err_code |= ERR_WARN;
6141 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006142 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006143 else if (!strcmp(args[0], "log-format-sd")) {
6144 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006145 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006146 err_code |= ERR_ALERT | ERR_FATAL;
6147 goto out;
6148 }
6149 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006150 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 +02006151 err_code |= ERR_ALERT | ERR_FATAL;
6152 goto out;
6153 }
6154
6155 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6156 free(curproxy->conf.logformat_sd_string);
6157 curproxy->conf.logformat_sd_string = strdup(args[1]);
6158
6159 free(curproxy->conf.lfsd_file);
6160 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6161 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6162
6163 /* get a chance to improve log-format-sd error reporting by
6164 * reporting the correct line-number when possible.
6165 */
6166 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006167 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6168 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006169 err_code |= ERR_WARN;
6170 }
6171 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006172 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6173 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006174 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 +01006175 err_code |= ERR_ALERT | ERR_FATAL;
6176 goto out;
6177 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006178 chunk_destroy(&curproxy->log_tag);
6179 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006180 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006181 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6182 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6183 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006184 err_code |= ERR_ALERT | ERR_FATAL;
6185 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006186 }
6187 }
6188 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006189 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006190 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006191 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006192 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006193
Willy Tarreau977b8e42006-12-29 14:19:17 +01006194 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006195 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006196
Willy Tarreaubaaee002006-06-26 02:48:02 +02006197 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006198 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6199 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006200 err_code |= ERR_ALERT | ERR_FATAL;
6201 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006202 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006203
6204 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006205 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6206 free(curproxy->conn_src.iface_name);
6207 curproxy->conn_src.iface_name = NULL;
6208 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006209
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006210 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006211 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006212 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6213 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006214 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006215 goto out;
6216 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006217
6218 proto = protocol_by_family(sk->ss_family);
6219 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006220 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6221 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006222 err_code |= ERR_ALERT | ERR_FATAL;
6223 goto out;
6224 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006225
6226 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006227 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6228 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006229 err_code |= ERR_ALERT | ERR_FATAL;
6230 goto out;
6231 }
6232
Willy Tarreauef9a3602012-12-08 22:29:20 +01006233 curproxy->conn_src.source_addr = *sk;
6234 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006235
6236 cur_arg = 2;
6237 while (*(args[cur_arg])) {
6238 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006239#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006240 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006241 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6242 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006243 err_code |= ERR_ALERT | ERR_FATAL;
6244 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006245 }
6246
6247 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006248 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6249 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006250 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006251 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6252 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006253 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6254 char *name, *end;
6255
6256 name = args[cur_arg+1] + 7;
6257 while (isspace(*name))
6258 name++;
6259
6260 end = name;
6261 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6262 end++;
6263
Willy Tarreauef9a3602012-12-08 22:29:20 +01006264 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6265 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6266 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6267 curproxy->conn_src.bind_hdr_len = end - name;
6268 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6269 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6270 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006271
6272 /* now look for an occurrence number */
6273 while (isspace(*end))
6274 end++;
6275 if (*end == ',') {
6276 end++;
6277 name = end;
6278 if (*end == '-')
6279 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006280 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006281 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006282 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006283 }
6284
Willy Tarreauef9a3602012-12-08 22:29:20 +01006285 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006286 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6287 " occurrences values smaller than %d.\n",
6288 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006289 err_code |= ERR_ALERT | ERR_FATAL;
6290 goto out;
6291 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006292 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006293 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006294
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006295 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006296 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006297 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6298 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006299 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006300 goto out;
6301 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006302
6303 proto = protocol_by_family(sk->ss_family);
6304 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006305 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6306 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006307 err_code |= ERR_ALERT | ERR_FATAL;
6308 goto out;
6309 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006310
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006311 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006312 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6313 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006314 err_code |= ERR_ALERT | ERR_FATAL;
6315 goto out;
6316 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006317 curproxy->conn_src.tproxy_addr = *sk;
6318 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006319 }
6320 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006321#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006322 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6323 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006324 err_code |= ERR_ALERT | ERR_FATAL;
6325 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006326#endif
6327 cur_arg += 2;
6328 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006329 }
6330
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006331 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6332#ifdef SO_BINDTODEVICE
6333 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006334 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6335 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006336 err_code |= ERR_ALERT | ERR_FATAL;
6337 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006338 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006339 free(curproxy->conn_src.iface_name);
6340 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6341 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006342 global.last_checks |= LSTCHK_NETADM;
6343#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006344 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6345 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006346 err_code |= ERR_ALERT | ERR_FATAL;
6347 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006348#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006349 cur_arg += 2;
6350 continue;
6351 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006352 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6353 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006354 err_code |= ERR_ALERT | ERR_FATAL;
6355 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006356 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006357 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006358 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006359 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6360 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006361 err_code |= ERR_ALERT | ERR_FATAL;
6362 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006363 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006364 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006365 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006366 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6367 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006368 err_code |= ERR_ALERT | ERR_FATAL;
6369 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006370 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006371
6372 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006373 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006374 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006375 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006376 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006377 }
6378 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006379 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006380 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006381 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006382 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006383 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006384 }
6385 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006386 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006387 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006388 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006389 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006390 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006391 }
6392 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006393 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006394 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006395 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006396 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006397 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006398 }
6399 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006400 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006401 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006402 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006403 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006404 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006405 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006406 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006407 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006408 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006409 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006410 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006411 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006412 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006413 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006414 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006415 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6416 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006417 err_code |= ERR_ALERT | ERR_FATAL;
6418 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006419 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006420
6421 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006422 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006423 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006424 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006425 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006426 }
6427 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006428 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006429 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006430 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006431 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006432 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006433 }
6434 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006435 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006436 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006437 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006438 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006439 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006440 }
6441 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006442 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006443 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006444 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006445 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006446 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006447 }
6448 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006449 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006450 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006451 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006452 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006453 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006454 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006455 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006456 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006457 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006458 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006459 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006460 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006461 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006462 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006463 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006464
Willy Tarreaubaaee002006-06-26 02:48:02 +02006465 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006466 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006467 err_code |= ERR_ALERT | ERR_FATAL;
6468 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006469 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006470 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006471 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006472
Willy Tarreaubaaee002006-06-26 02:48:02 +02006473 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006474 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006475 err_code |= ERR_ALERT | ERR_FATAL;
6476 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006477 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006478
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006479 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006480 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006481 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6482 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006483 err_code |= ERR_ALERT | ERR_FATAL;
6484 goto out;
6485 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006486 err_code |= warnif_cond_conflicts(cond,
6487 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6488 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006489 }
6490 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006491 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6492 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006493 err_code |= ERR_ALERT | ERR_FATAL;
6494 goto out;
6495 }
6496
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006497 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006498 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006499 wl->s = strdup(args[1]);
6500 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006501 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006502 }
6503 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006504 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006505 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6506 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006507 err_code |= ERR_ALERT | ERR_FATAL;
6508 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006509 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006510
Willy Tarreauade5ec42010-01-28 19:33:49 +01006511 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006512 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006513 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006514 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006515 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006516 }
6517 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006518 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006519 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006520 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006521 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006522 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006523 }
6524 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006525 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006526 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006527 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006528 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006529 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006530 }
6531 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006532 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006533 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6534 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006535 err_code |= ERR_ALERT | ERR_FATAL;
6536 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006537 }
6538
Willy Tarreauade5ec42010-01-28 19:33:49 +01006539 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006540 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006541 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006542 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006543 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006544 }
6545 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006546 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006547 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006548 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006549 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006550 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006551 }
6552 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006553 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006554 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006555 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006556 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006557 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006558 }
6559 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006560 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006561
Willy Tarreaubaaee002006-06-26 02:48:02 +02006562 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006563 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006564 err_code |= ERR_ALERT | ERR_FATAL;
6565 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006566 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006567 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006568 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006569
Willy Tarreaubaaee002006-06-26 02:48:02 +02006570 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006571 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006572 err_code |= ERR_ALERT | ERR_FATAL;
6573 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006574 }
6575
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006576 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006577 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006578 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6579 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006580 err_code |= ERR_ALERT | ERR_FATAL;
6581 goto out;
6582 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006583 err_code |= warnif_cond_conflicts(cond,
6584 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6585 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006586 }
6587 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006588 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6589 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006590 err_code |= ERR_ALERT | ERR_FATAL;
6591 goto out;
6592 }
6593
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006594 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006595 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006596 wl->s = strdup(args[1]);
6597 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006598 }
6599 else if (!strcmp(args[0], "errorloc") ||
6600 !strcmp(args[0], "errorloc302") ||
6601 !strcmp(args[0], "errorloc303")) { /* error location */
6602 int errnum, errlen;
6603 char *err;
6604
Willy Tarreau977b8e42006-12-29 14:19:17 +01006605 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006606 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006607
Willy Tarreaubaaee002006-06-26 02:48:02 +02006608 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006609 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 +02006610 err_code |= ERR_ALERT | ERR_FATAL;
6611 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006612 }
6613
6614 errnum = atol(args[1]);
6615 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006616 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6617 err = malloc(errlen);
6618 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006619 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006620 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6621 err = malloc(errlen);
6622 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006623 }
6624
Willy Tarreau0f772532006-12-23 20:51:41 +01006625 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6626 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006627 chunk_destroy(&curproxy->errmsg[rc]);
6628 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006629 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006630 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006631 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006632
6633 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006634 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6635 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006636 free(err);
6637 }
6638 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006639 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6640 int errnum, errlen, fd;
6641 char *err;
6642 struct stat stat;
6643
6644 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006645 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006646
6647 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006648 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 +02006649 err_code |= ERR_ALERT | ERR_FATAL;
6650 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006651 }
6652
6653 fd = open(args[2], O_RDONLY);
6654 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006655 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6656 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006657 if (fd >= 0)
6658 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006659 err_code |= ERR_ALERT | ERR_FATAL;
6660 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006661 }
6662
Willy Tarreau27a674e2009-08-17 07:23:33 +02006663 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006664 errlen = stat.st_size;
6665 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006666 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6667 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006668 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006669 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006670 }
6671
6672 err = malloc(errlen); /* malloc() must succeed during parsing */
6673 errnum = read(fd, err, errlen);
6674 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006675 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6676 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006677 close(fd);
6678 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006679 err_code |= ERR_ALERT | ERR_FATAL;
6680 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006681 }
6682 close(fd);
6683
6684 errnum = atol(args[1]);
6685 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6686 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006687 chunk_destroy(&curproxy->errmsg[rc]);
6688 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006689 break;
6690 }
6691 }
6692
6693 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006694 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6695 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006696 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006697 free(err);
6698 }
6699 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006700 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006701 struct cfg_kw_list *kwl;
6702 int index;
6703
6704 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6705 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6706 if (kwl->kw[index].section != CFG_LISTEN)
6707 continue;
6708 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6709 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006710 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006711 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006712 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006713 err_code |= ERR_ALERT | ERR_FATAL;
6714 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006715 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006716 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006717 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006718 err_code |= ERR_WARN;
6719 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006720 }
Willy Tarreau93893792009-07-23 13:19:11 +02006721 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006722 }
6723 }
6724 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006725
Christopher Faulet767a84b2017-11-24 16:50:31 +01006726 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006727 err_code |= ERR_ALERT | ERR_FATAL;
6728 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006729 }
Willy Tarreau93893792009-07-23 13:19:11 +02006730 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006731 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006732 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006733}
6734
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006735int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006736cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6737{
6738#ifdef CONFIG_HAP_NS
6739 const char *err;
6740 const char *item = args[0];
6741
6742 if (!strcmp(item, "namespace_list")) {
6743 return 0;
6744 }
6745 else if (!strcmp(item, "namespace")) {
6746 size_t idx = 1;
6747 const char *current;
6748 while (*(current = args[idx++])) {
6749 err = invalid_char(current);
6750 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006751 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6752 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006753 return ERR_ALERT | ERR_FATAL;
6754 }
6755
6756 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006757 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6758 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006759 return ERR_ALERT | ERR_FATAL;
6760 }
6761 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006762 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6763 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006764 return ERR_ALERT | ERR_FATAL;
6765 }
6766 }
6767 }
6768
6769 return 0;
6770#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006771 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6772 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006773 return ERR_ALERT | ERR_FATAL;
6774#endif
6775}
6776
6777int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006778cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6779{
6780
6781 int err_code = 0;
6782 const char *err;
6783
6784 if (!strcmp(args[0], "userlist")) { /* new userlist */
6785 struct userlist *newul;
6786
6787 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006788 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6789 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006790 err_code |= ERR_ALERT | ERR_FATAL;
6791 goto out;
6792 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006793 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6794 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006795
6796 err = invalid_char(args[1]);
6797 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006798 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6799 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006800 err_code |= ERR_ALERT | ERR_FATAL;
6801 goto out;
6802 }
6803
6804 for (newul = userlist; newul; newul = newul->next)
6805 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006806 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6807 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006808 err_code |= ERR_WARN;
6809 goto out;
6810 }
6811
Vincent Bernat02779b62016-04-03 13:48:43 +02006812 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006813 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006814 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006815 err_code |= ERR_ALERT | ERR_ABORT;
6816 goto out;
6817 }
6818
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006819 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006820 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006821 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006822 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006823 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006824 goto out;
6825 }
6826
6827 newul->next = userlist;
6828 userlist = newul;
6829
6830 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006831 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006832 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006833 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006834
6835 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006836 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6837 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006838 err_code |= ERR_ALERT | ERR_FATAL;
6839 goto out;
6840 }
6841
6842 err = invalid_char(args[1]);
6843 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006844 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6845 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006846 err_code |= ERR_ALERT | ERR_FATAL;
6847 goto out;
6848 }
6849
William Lallemand4ac9f542015-05-28 18:03:51 +02006850 if (!userlist)
6851 goto out;
6852
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006853 for (ag = userlist->groups; ag; ag = ag->next)
6854 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006855 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6856 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006857 err_code |= ERR_ALERT;
6858 goto out;
6859 }
6860
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006861 ag = calloc(1, sizeof(*ag));
6862 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006863 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006864 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006865 goto out;
6866 }
6867
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006868 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006869 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006870 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006871 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006872 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006873 goto out;
6874 }
6875
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006876 cur_arg = 2;
6877
6878 while (*args[cur_arg]) {
6879 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006880 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006881 cur_arg += 2;
6882 continue;
6883 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006884 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6885 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006886 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006887 free(ag->groupusers);
6888 free(ag->name);
6889 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006890 goto out;
6891 }
6892 }
6893
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006894 ag->next = userlist->groups;
6895 userlist->groups = ag;
6896
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006897 } else if (!strcmp(args[0], "user")) { /* new user */
6898 struct auth_users *newuser;
6899 int cur_arg;
6900
6901 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006902 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6903 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006904 err_code |= ERR_ALERT | ERR_FATAL;
6905 goto out;
6906 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006907 if (!userlist)
6908 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006909
6910 for (newuser = userlist->users; newuser; newuser = newuser->next)
6911 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006912 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6913 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006914 err_code |= ERR_ALERT;
6915 goto out;
6916 }
6917
Vincent Bernat02779b62016-04-03 13:48:43 +02006918 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006919 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006920 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006921 err_code |= ERR_ALERT | ERR_ABORT;
6922 goto out;
6923 }
6924
6925 newuser->user = strdup(args[1]);
6926
6927 newuser->next = userlist->users;
6928 userlist->users = newuser;
6929
6930 cur_arg = 2;
6931
6932 while (*args[cur_arg]) {
6933 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006934#ifdef CONFIG_HAP_CRYPT
6935 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006936 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6937 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006938 err_code |= ERR_ALERT | ERR_FATAL;
6939 goto out;
6940 }
6941#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006942 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6943 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006944 err_code |= ERR_ALERT;
6945#endif
6946 newuser->pass = strdup(args[cur_arg + 1]);
6947 cur_arg += 2;
6948 continue;
6949 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6950 newuser->pass = strdup(args[cur_arg + 1]);
6951 newuser->flags |= AU_O_INSECURE;
6952 cur_arg += 2;
6953 continue;
6954 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006955 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006956 cur_arg += 2;
6957 continue;
6958 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006959 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6960 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006961 err_code |= ERR_ALERT | ERR_FATAL;
6962 goto out;
6963 }
6964 }
6965 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006966 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 +01006967 err_code |= ERR_ALERT | ERR_FATAL;
6968 }
6969
6970out:
6971 return err_code;
6972}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006973
Christopher Faulet79bdef32016-11-04 22:36:15 +01006974int
6975cfg_parse_scope(const char *file, int linenum, char *line)
6976{
6977 char *beg, *end, *scope = NULL;
6978 int err_code = 0;
6979 const char *err;
6980
6981 beg = line + 1;
6982 end = strchr(beg, ']');
6983
6984 /* Detect end of scope declaration */
6985 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006986 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
6987 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006988 err_code |= ERR_ALERT | ERR_FATAL;
6989 goto out;
6990 }
6991
6992 /* Get scope name and check its validity */
6993 scope = my_strndup(beg, end-beg);
6994 err = invalid_char(scope);
6995 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006996 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
6997 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006998 err_code |= ERR_ALERT | ERR_ABORT;
6999 goto out;
7000 }
7001
7002 /* Be sure to have a scope declaration alone on its line */
7003 line = end+1;
7004 while (isspace((unsigned char)*line))
7005 line++;
7006 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007007 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7008 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007009 err_code |= ERR_ALERT | ERR_ABORT;
7010 goto out;
7011 }
7012
7013 /* We have a valid scope declaration, save it */
7014 free(cfg_scope);
7015 cfg_scope = scope;
7016 scope = NULL;
7017
7018 out:
7019 free(scope);
7020 return err_code;
7021}
7022
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01007023int
7024cfg_parse_track_sc_num(unsigned int *track_sc_num,
7025 const char *arg, const char *end, char **errmsg)
7026{
7027 const char *p;
7028 unsigned int num;
7029
7030 p = arg;
7031 num = read_uint64(&arg, end);
7032
7033 if (arg != end) {
7034 memprintf(errmsg, "Wrong track-sc number '%s'", p);
7035 return -1;
7036 }
7037
7038 if (num >= MAX_SESS_STKCTR) {
7039 memprintf(errmsg, "%u track-sc number exceeding "
7040 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
7041 return -1;
7042 }
7043
7044 *track_sc_num = num;
7045 return 0;
7046}
7047
Willy Tarreaubaaee002006-06-26 02:48:02 +02007048/*
7049 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007050 * Returns the error code, 0 if OK, or any combination of :
7051 * - ERR_ABORT: must abort ASAP
7052 * - ERR_FATAL: we can continue parsing but not start the service
7053 * - ERR_WARN: a warning has been emitted
7054 * - ERR_ALERT: an alert has been emitted
7055 * Only the two first ones can stop processing, the two others are just
7056 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007057 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007058int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007059{
William Lallemand64e84512015-05-12 14:25:37 +02007060 char *thisline;
7061 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007062 FILE *f;
7063 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007064 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007065 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007066 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007067 int readbytes = 0;
7068
7069 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007070 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007071 return -1;
7072 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007073
David Carlier97880bb2016-04-08 10:35:26 +01007074 if ((f=fopen(file,"r")) == NULL) {
7075 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007076 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007077 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007078
William Lallemandb2f07452015-05-12 14:27:13 +02007079next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007080 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007081 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007082 char *end;
7083 char *args[MAX_LINE_ARGS + 1];
7084 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007085 int dquote = 0; /* double quote */
7086 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007087
Willy Tarreaubaaee002006-06-26 02:48:02 +02007088 linenum++;
7089
7090 end = line + strlen(line);
7091
William Lallemand64e84512015-05-12 14:25:37 +02007092 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007093 /* Check if we reached the limit and the last char is not \n.
7094 * Watch out for the last line without the terminating '\n'!
7095 */
William Lallemand64e84512015-05-12 14:25:37 +02007096 char *newline;
7097 int newlinesize = linesize * 2;
7098
7099 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7100 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007101 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7102 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007103 err_code |= ERR_ALERT | ERR_FATAL;
7104 continue;
7105 }
7106
7107 readbytes = linesize - 1;
7108 linesize = newlinesize;
7109 thisline = newline;
7110 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007111 }
7112
William Lallemand64e84512015-05-12 14:25:37 +02007113 readbytes = 0;
7114
Willy Tarreaubaaee002006-06-26 02:48:02 +02007115 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007116 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007117 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007118
Christopher Faulet79bdef32016-11-04 22:36:15 +01007119
7120 if (*line == '[') {/* This is the begining if a scope */
7121 err_code |= cfg_parse_scope(file, linenum, line);
7122 goto next_line;
7123 }
7124
Willy Tarreaubaaee002006-06-26 02:48:02 +02007125 arg = 0;
7126 args[arg] = line;
7127
7128 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007129 if (*line == '"' && !squote) { /* double quote outside single quotes */
7130 if (dquote)
7131 dquote = 0;
7132 else
7133 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007134 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007135 end--;
7136 }
7137 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7138 if (squote)
7139 squote = 0;
7140 else
7141 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007142 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007143 end--;
7144 }
7145 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007146 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7147 * C equivalent value. Other combinations left unchanged (eg: \1).
7148 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007149 int skip = 0;
7150 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7151 *line = line[1];
7152 skip = 1;
7153 }
7154 else if (line[1] == 'r') {
7155 *line = '\r';
7156 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007157 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007158 else if (line[1] == 'n') {
7159 *line = '\n';
7160 skip = 1;
7161 }
7162 else if (line[1] == 't') {
7163 *line = '\t';
7164 skip = 1;
7165 }
7166 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007167 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007168 unsigned char hex1, hex2;
7169 hex1 = toupper(line[2]) - '0';
7170 hex2 = toupper(line[3]) - '0';
7171 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7172 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7173 *line = (hex1<<4) + hex2;
7174 skip = 3;
7175 }
7176 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007177 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007178 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007179 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007180 } else if (line[1] == '"') {
7181 *line = '"';
7182 skip = 1;
7183 } else if (line[1] == '\'') {
7184 *line = '\'';
7185 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007186 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7187 *line = '$';
7188 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007189 }
7190 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007191 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007192 end -= skip;
7193 }
7194 line++;
7195 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007196 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007197 /* end of string, end of loop */
7198 *line = 0;
7199 break;
7200 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007201 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007202 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007203 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007204 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007205 line++;
7206 args[++arg] = line;
7207 }
William Lallemandb2f07452015-05-12 14:27:13 +02007208 else if (dquote && *line == '$') {
7209 /* environment variables are evaluated inside double quotes */
7210 char *var_beg;
7211 char *var_end;
7212 char save_char;
7213 char *value;
7214 int val_len;
7215 int newlinesize;
7216 int braces = 0;
7217
7218 var_beg = line + 1;
7219 var_end = var_beg;
7220
7221 if (*var_beg == '{') {
7222 var_beg++;
7223 var_end++;
7224 braces = 1;
7225 }
7226
7227 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007228 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 +02007229 err_code |= ERR_ALERT | ERR_FATAL;
7230 goto next_line; /* skip current line */
7231 }
7232
7233 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7234 var_end++;
7235
7236 save_char = *var_end;
7237 *var_end = '\0';
7238 value = getenv(var_beg);
7239 *var_end = save_char;
7240 val_len = value ? strlen(value) : 0;
7241
7242 if (braces) {
7243 if (*var_end == '}') {
7244 var_end++;
7245 braces = 0;
7246 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007247 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007248 err_code |= ERR_ALERT | ERR_FATAL;
7249 goto next_line; /* skip current line */
7250 }
7251 }
7252
7253 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7254
7255 /* if not enough space in thisline */
7256 if (newlinesize > linesize) {
7257 char *newline;
7258
7259 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7260 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007261 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007262 err_code |= ERR_ALERT | ERR_FATAL;
7263 goto next_line; /* slip current line */
7264 }
7265 /* recompute pointers if realloc returns a new pointer */
7266 if (newline != thisline) {
7267 int i;
7268 int diff;
7269
7270 for (i = 0; i <= arg; i++) {
7271 diff = args[i] - thisline;
7272 args[i] = newline + diff;
7273 }
7274
7275 diff = var_end - thisline;
7276 var_end = newline + diff;
7277 diff = end - thisline;
7278 end = newline + diff;
7279 diff = line - thisline;
7280 line = newline + diff;
7281 thisline = newline;
7282 }
7283 linesize = newlinesize;
7284 }
7285
7286 /* insert value inside the line */
7287 memmove(line + val_len, var_end, end - var_end + 1);
7288 memcpy(line, value, val_len);
7289 end += val_len - (var_end - line);
7290 line += val_len;
7291 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007292 else {
7293 line++;
7294 }
7295 }
William Lallemandb2f07452015-05-12 14:27:13 +02007296
William Lallemandf9873ba2015-05-05 17:37:14 +02007297 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007298 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007299 err_code |= ERR_ALERT | ERR_FATAL;
7300 }
7301
7302 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007303 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007304 err_code |= ERR_ALERT | ERR_FATAL;
7305 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007306
7307 /* empty line */
7308 if (!**args)
7309 continue;
7310
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007311 if (*line) {
7312 /* we had to stop due to too many args.
7313 * Let's terminate the string, print the offending part then cut the
7314 * last arg.
7315 */
7316 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7317 line++;
7318 *line = '\0';
7319
Christopher Faulet767a84b2017-11-24 16:50:31 +01007320 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7321 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007322 err_code |= ERR_ALERT | ERR_FATAL;
7323 args[arg] = line;
7324 }
7325
Willy Tarreau540abe42007-05-02 20:50:16 +02007326 /* zero out remaining args and ensure that at least one entry
7327 * is zeroed out.
7328 */
7329 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007330 args[arg] = line;
7331 }
7332
Willy Tarreau3842f002009-06-14 11:39:52 +02007333 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007334 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007335 char *tmp;
7336
Willy Tarreau3842f002009-06-14 11:39:52 +02007337 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007338 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007339 for (arg=0; *args[arg+1]; arg++)
7340 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007341 *tmp = '\0'; // fix the next arg to \0
7342 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007343 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007344 else if (!strcmp(args[0], "default")) {
7345 kwm = KWM_DEF;
7346 for (arg=0; *args[arg+1]; arg++)
7347 args[arg] = args[arg+1]; // shift args after inversion
7348 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007349
William Lallemand0f99e342011-10-12 17:50:54 +02007350 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7351 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007352 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007353 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007354 }
7355
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007356 /* detect section start */
7357 list_for_each_entry(ics, &sections, list) {
7358 if (strcmp(args[0], ics->section_name) == 0) {
7359 cursection = ics->section_name;
7360 cs = ics;
7361 break;
7362 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007363 }
7364
William Lallemandd2ff56d2017-10-16 11:06:50 +02007365 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007366 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007367 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007368 } else {
7369 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007370
William Lallemandd2ff56d2017-10-16 11:06:50 +02007371 if (pcs != cs && pcs && pcs->post_section_parser) {
7372 err_code |= pcs->post_section_parser();
7373 if (err_code & ERR_ABORT)
7374 goto err;
7375 }
7376
7377 err_code |= cs->section_parser(file, linenum, args, kwm);
7378 if (err_code & ERR_ABORT)
7379 goto err;
7380 }
7381 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007382 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007383
7384 if (pcs == cs && pcs && pcs->post_section_parser)
7385 err_code |= pcs->post_section_parser();
7386
7387err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007388 free(cfg_scope);
7389 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007390 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007391 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007392 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007393 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007394}
7395
Willy Tarreau64ab6072014-09-16 12:17:36 +02007396/* This function propagates processes from frontend <from> to backend <to> so
7397 * that it is always guaranteed that a backend pointed to by a frontend is
7398 * bound to all of its processes. After that, if the target is a "listen"
7399 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007400 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007401 * checked first to ensure that <to> is already bound to all processes of
7402 * <from>, there is no risk of looping and we ensure to follow the shortest
7403 * path to the destination.
7404 *
7405 * It is possible to set <to> to NULL for the first call so that the function
7406 * takes care of visiting the initial frontend in <from>.
7407 *
7408 * It is important to note that the function relies on the fact that all names
7409 * have already been resolved.
7410 */
7411void propagate_processes(struct proxy *from, struct proxy *to)
7412{
7413 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007414
7415 if (to) {
7416 /* check whether we need to go down */
7417 if (from->bind_proc &&
7418 (from->bind_proc & to->bind_proc) == from->bind_proc)
7419 return;
7420
7421 if (!from->bind_proc && !to->bind_proc)
7422 return;
7423
7424 to->bind_proc = from->bind_proc ?
7425 (to->bind_proc | from->bind_proc) : 0;
7426
7427 /* now propagate down */
7428 from = to;
7429 }
7430
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007431 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007432 return;
7433
Willy Tarreauf6b70012014-12-18 14:00:43 +01007434 if (from->state == PR_STSTOPPED)
7435 return;
7436
Willy Tarreau64ab6072014-09-16 12:17:36 +02007437 /* default_backend */
7438 if (from->defbe.be)
7439 propagate_processes(from, from->defbe.be);
7440
7441 /* use_backend */
7442 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007443 if (rule->dynamic)
7444 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007445 to = rule->be.backend;
7446 propagate_processes(from, to);
7447 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007448}
7449
Willy Tarreaubb925012009-07-23 13:36:36 +02007450/*
7451 * Returns the error code, 0 if OK, or any combination of :
7452 * - ERR_ABORT: must abort ASAP
7453 * - ERR_FATAL: we can continue parsing but not start the service
7454 * - ERR_WARN: a warning has been emitted
7455 * - ERR_ALERT: an alert has been emitted
7456 * Only the two first ones can stop processing, the two others are just
7457 * indicators.
7458 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007459int check_config_validity()
7460{
7461 int cfgerr = 0;
7462 struct proxy *curproxy = NULL;
7463 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007464 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007465 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007466 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007467 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007468 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06007469 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007470
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007471 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007472 /*
7473 * Now, check for the integrity of all that we have collected.
7474 */
7475
7476 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007477 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007478
Willy Tarreau193b8c62012-11-22 00:17:38 +01007479 if (!global.tune.max_http_hdr)
7480 global.tune.max_http_hdr = MAX_HTTP_HDR;
7481
7482 if (!global.tune.cookie_len)
7483 global.tune.cookie_len = CAPTURE_LEN;
7484
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007485 if (!global.tune.requri_len)
7486 global.tune.requri_len = REQURI_LEN;
7487
Willy Tarreaubafbe012017-11-24 17:34:44 +01007488 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007489
Willy Tarreaubafbe012017-11-24 17:34:44 +01007490 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007491
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007492 /* Post initialisation of the users and groups lists. */
7493 err_code = userlist_postinit();
7494 if (err_code != ERR_NONE)
7495 goto out;
7496
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007497 /* first, we will invert the proxy list order */
7498 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007499 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007500 struct proxy *next;
7501
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007502 next = proxies_list->next;
7503 proxies_list->next = curproxy;
7504 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007505 if (!next)
7506 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007507 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007508 }
7509
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007510 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007511 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007512 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007513 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007514 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007515 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007516 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007517 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007518
Willy Tarreau050536d2012-10-04 08:47:34 +02007519 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007520 /* proxy ID not set, use automatic numbering with first
7521 * spare entry starting with next_pxid.
7522 */
7523 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7524 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7525 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007526 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007527 next_pxid++;
7528
Willy Tarreau55ea7572007-06-17 19:56:27 +02007529
Willy Tarreaubaaee002006-06-26 02:48:02 +02007530 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007531 /* ensure we don't keep listeners uselessly bound */
7532 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007533 free((void *)curproxy->table.peers.name);
7534 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007535 continue;
7536 }
7537
Willy Tarreau102df612014-05-07 23:56:38 +02007538 /* Check multi-process mode compatibility for the current proxy */
7539
7540 if (curproxy->bind_proc) {
7541 /* an explicit bind-process was specified, let's check how many
7542 * processes remain.
7543 */
David Carliere6c39412015-07-02 07:00:17 +00007544 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007545
7546 curproxy->bind_proc &= nbits(global.nbproc);
7547 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007548 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 +02007549 curproxy->bind_proc = 1;
7550 }
7551 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007552 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 +02007553 curproxy->bind_proc = 0;
7554 }
7555 }
7556
Willy Tarreau3d209582014-05-09 17:06:11 +02007557 /* check and reduce the bind-proc of each listener */
7558 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7559 unsigned long mask;
7560
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007561 /* HTTP frontends with "h2" as ALPN/NPN will work in
7562 * HTTP/2 and absolutely require buffers 16kB or larger.
7563 */
7564#ifdef USE_OPENSSL
7565 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7566#ifdef OPENSSL_NPN_NEGOTIATED
7567 /* check NPN */
7568 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007569 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",
7570 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007571 cfgerr++;
7572 }
7573#endif
7574#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7575 /* check ALPN */
7576 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007577 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",
7578 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007579 cfgerr++;
7580 }
7581#endif
7582 } /* HTTP && bufsize < 16384 */
7583#endif
7584
Willy Tarreau3d209582014-05-09 17:06:11 +02007585 if (!bind_conf->bind_proc)
7586 continue;
7587
7588 mask = nbits(global.nbproc);
7589 if (curproxy->bind_proc)
7590 mask &= curproxy->bind_proc;
7591 /* mask cannot be null here thanks to the previous checks */
7592
David Carliere6c39412015-07-02 07:00:17 +00007593 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007594 bind_conf->bind_proc &= mask;
7595
7596 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007597 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",
7598 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007599 bind_conf->bind_proc = mask & ~(mask - 1);
7600 }
7601 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007602 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",
7603 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007604 bind_conf->bind_proc = 0;
7605 }
7606 }
7607
Willy Tarreauff01a212009-03-15 13:46:16 +01007608 switch (curproxy->mode) {
7609 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007610 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007611 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007612 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7613 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007614 cfgerr++;
7615 }
7616
7617 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007618 ha_warning("config : servers will be ignored for %s '%s'.\n",
7619 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007620 break;
7621
7622 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007623 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007624 break;
7625
7626 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007627 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007628 break;
7629 }
7630
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007631 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007632 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7633 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007634 err_code |= ERR_WARN;
7635 }
7636
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007637 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007638 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007639 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007640 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7641 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007642 cfgerr++;
7643 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007644#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007645 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007646 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7647 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007648 cfgerr++;
7649 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007650#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007651 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007652 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7653 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007654 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007655 }
7656 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007657 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007658 /* If no LB algo is set in a backend, and we're not in
7659 * transparent mode, dispatch mode nor proxy mode, we
7660 * want to use balance roundrobin by default.
7661 */
7662 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7663 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007664 }
7665 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007666
Willy Tarreau1620ec32011-08-06 17:05:02 +02007667 if (curproxy->options & PR_O_DISPATCH)
7668 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7669 else if (curproxy->options & PR_O_HTTP_PROXY)
7670 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7671 else if (curproxy->options & PR_O_TRANSP)
7672 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007673
Willy Tarreau1620ec32011-08-06 17:05:02 +02007674 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7675 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007676 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7677 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007678 err_code |= ERR_WARN;
7679 curproxy->options &= ~PR_O_DISABLE404;
7680 }
7681 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007682 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7683 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007684 err_code |= ERR_WARN;
7685 curproxy->options &= ~PR_O2_CHK_SNDST;
7686 }
Willy Tarreauef781042010-01-27 11:53:01 +01007687 }
7688
Simon Horman98637e52014-06-20 12:30:16 +09007689 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7690 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007691 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7692 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007693 cfgerr++;
7694 }
7695 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007696 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7697 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007698 cfgerr++;
7699 }
7700 }
7701
Simon Horman64e34162015-02-06 11:11:57 +09007702 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007703 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007704 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7705 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7706 "'email-alert myhostname', or 'email-alert to' "
7707 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7708 "to be present).\n",
7709 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007710 err_code |= ERR_WARN;
7711 free_email_alert(curproxy);
7712 }
7713 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007714 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007715 }
7716
Simon Horman98637e52014-06-20 12:30:16 +09007717 if (curproxy->check_command) {
7718 int clear = 0;
7719 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007720 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7721 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007722 err_code |= ERR_WARN;
7723 clear = 1;
7724 }
7725 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007726 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7727 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007728 cfgerr++;
7729 }
7730 if (clear) {
7731 free(curproxy->check_command);
7732 curproxy->check_command = NULL;
7733 }
7734 }
7735
7736 if (curproxy->check_path) {
7737 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007738 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7739 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007740 err_code |= ERR_WARN;
7741 free(curproxy->check_path);
7742 curproxy->check_path = NULL;
7743 }
7744 }
7745
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007746 /* if a default backend was specified, let's find it */
7747 if (curproxy->defbe.name) {
7748 struct proxy *target;
7749
Willy Tarreauafb39922015-05-26 12:04:09 +02007750 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007751 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007752 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7753 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007754 cfgerr++;
7755 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007756 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7757 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007758 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007759 } else if (target->mode != curproxy->mode &&
7760 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7761
Christopher Faulet767a84b2017-11-24 16:50:31 +01007762 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7763 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7764 curproxy->conf.file, curproxy->conf.line,
7765 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7766 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007767 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007768 } else {
7769 free(curproxy->defbe.name);
7770 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007771 /* Update tot_fe_maxconn for a further fullconn's computation */
7772 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007773 /* Emit a warning if this proxy also has some servers */
7774 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007775 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7776 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007777 err_code |= ERR_WARN;
7778 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007779 }
7780 }
7781
Emeric Brun3f783572017-01-12 11:21:28 +01007782 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7783 /* Case of listen without default backend
7784 * The curproxy will be its own default backend
7785 * so we update tot_fe_maxconn for a further
7786 * fullconn's computation */
7787 curproxy->tot_fe_maxconn += curproxy->maxconn;
7788 }
7789
Willy Tarreau55ea7572007-06-17 19:56:27 +02007790 /* find the target proxy for 'use_backend' rules */
7791 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007792 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007793 struct logformat_node *node;
7794 char *pxname;
7795
7796 /* Try to parse the string as a log format expression. If the result
7797 * of the parsing is only one entry containing a simple string, then
7798 * it's a standard string corresponding to a static rule, thus the
7799 * parsing is cancelled and be.name is restored to be resolved.
7800 */
7801 pxname = rule->be.name;
7802 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007803 curproxy->conf.args.ctx = ARGC_UBK;
7804 curproxy->conf.args.file = rule->file;
7805 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007806 err = NULL;
7807 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007808 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7809 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007810 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007811 cfgerr++;
7812 continue;
7813 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007814 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7815
7816 if (!LIST_ISEMPTY(&rule->be.expr)) {
7817 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7818 rule->dynamic = 1;
7819 free(pxname);
7820 continue;
7821 }
7822 /* simple string: free the expression and fall back to static rule */
7823 free(node->arg);
7824 free(node);
7825 }
7826
7827 rule->dynamic = 0;
7828 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007829
Willy Tarreauafb39922015-05-26 12:04:09 +02007830 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007831 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007832 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7833 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007834 cfgerr++;
7835 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007836 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7837 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007838 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007839 } else if (target->mode != curproxy->mode &&
7840 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7841
Christopher Faulet767a84b2017-11-24 16:50:31 +01007842 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7843 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7844 curproxy->conf.file, curproxy->conf.line,
7845 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7846 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007847 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007848 } else {
7849 free((void *)rule->be.name);
7850 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007851 /* For each target of switching rules, we update
7852 * their tot_fe_maxconn, except if a previous rule point
7853 * on the same backend or on the default backend */
7854 if (rule->be.backend != curproxy->defbe.be) {
7855 struct switching_rule *swrule;
7856
7857 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7858 if (rule == swrule) {
7859 target->tot_fe_maxconn += curproxy->maxconn;
7860 break;
7861 }
7862 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7863 /* there is multiple ref of this backend */
7864 break;
7865 }
7866 }
7867 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007868 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007869 }
7870
Willy Tarreau64ab6072014-09-16 12:17:36 +02007871 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007872 list_for_each_entry(srule, &curproxy->server_rules, list) {
7873 struct server *target = findserver(curproxy, srule->srv.name);
7874
7875 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007876 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7877 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007878 cfgerr++;
7879 continue;
7880 }
7881 free((void *)srule->srv.name);
7882 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007883 }
7884
Emeric Brunb982a3d2010-01-04 15:45:53 +01007885 /* find the target table for 'stick' rules */
7886 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7887 struct proxy *target;
7888
Emeric Brun1d33b292010-01-04 15:47:17 +01007889 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7890 if (mrule->flags & STK_IS_STORE)
7891 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7892
Emeric Brunb982a3d2010-01-04 15:45:53 +01007893 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007894 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007895 else
7896 target = curproxy;
7897
7898 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007899 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7900 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007901 cfgerr++;
7902 }
7903 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007904 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7905 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007906 cfgerr++;
7907 }
Willy Tarreau12785782012-04-27 21:37:17 +02007908 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007909 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7910 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007911 cfgerr++;
7912 }
7913 else {
7914 free((void *)mrule->table.name);
7915 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007916 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007917 }
7918 }
7919
7920 /* find the target table for 'store response' rules */
7921 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7922 struct proxy *target;
7923
Emeric Brun1d33b292010-01-04 15:47:17 +01007924 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7925
Emeric Brunb982a3d2010-01-04 15:45:53 +01007926 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007927 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007928 else
7929 target = curproxy;
7930
7931 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007932 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7933 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007934 cfgerr++;
7935 }
7936 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007937 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7938 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007939 cfgerr++;
7940 }
Willy Tarreau12785782012-04-27 21:37:17 +02007941 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007942 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7943 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007944 cfgerr++;
7945 }
7946 else {
7947 free((void *)mrule->table.name);
7948 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007949 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007950 }
7951 }
7952
Christopher Faulete4e830d2017-09-18 14:51:41 +02007953 /* check validity for 'tcp-request' layer 4 rules */
7954 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
7955 err = NULL;
7956 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007957 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007958 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01007959 cfgerr++;
7960 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02007961 }
7962
Christopher Faulete4e830d2017-09-18 14:51:41 +02007963 /* check validity for 'tcp-request' layer 5 rules */
7964 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
7965 err = NULL;
7966 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007967 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007968 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007969 cfgerr++;
7970 }
7971 }
7972
Christopher Faulete4e830d2017-09-18 14:51:41 +02007973 /* check validity for 'tcp-request' layer 6 rules */
7974 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
7975 err = NULL;
7976 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007977 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007978 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007979 cfgerr++;
7980 }
7981 }
7982
Christopher Faulete4e830d2017-09-18 14:51:41 +02007983 /* check validity for 'http-request' layer 7 rules */
7984 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
7985 err = NULL;
7986 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007987 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007988 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007989 cfgerr++;
7990 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007991 }
7992
Christopher Faulete4e830d2017-09-18 14:51:41 +02007993 /* check validity for 'http-response' layer 7 rules */
7994 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
7995 err = NULL;
7996 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007997 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007998 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02007999 cfgerr++;
8000 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008001 }
8002
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008003 /* move any "block" rules at the beginning of the http-request rules */
8004 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8005 /* insert block_rules into http_req_rules at the beginning */
8006 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8007 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8008 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8009 curproxy->http_req_rules.n = curproxy->block_rules.n;
8010 LIST_INIT(&curproxy->block_rules);
8011 }
8012
Emeric Brun32da3c42010-09-23 18:39:19 +02008013 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008014 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008015
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008016 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008017 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8018 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008019 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008020 break;
8021 }
8022 }
8023
8024 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008025 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8026 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008027 free((void *)curproxy->table.peers.name);
8028 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008029 cfgerr++;
8030 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008031 else if (curpeers->state == PR_STSTOPPED) {
8032 /* silently disable this peers section */
8033 curproxy->table.peers.p = NULL;
8034 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008035 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008036 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8037 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008038 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008039 cfgerr++;
8040 }
8041 }
8042
Simon Horman9dc49962015-01-30 11:22:59 +09008043
8044 if (curproxy->email_alert.mailers.name) {
8045 struct mailers *curmailers = mailers;
8046
8047 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008048 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008049 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008050 }
Simon Horman9dc49962015-01-30 11:22:59 +09008051 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008052 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8053 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008054 free_email_alert(curproxy);
8055 cfgerr++;
8056 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008057 else {
8058 err = NULL;
8059 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008060 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008061 free(err);
8062 cfgerr++;
8063 }
8064 }
Simon Horman9dc49962015-01-30 11:22:59 +09008065 }
8066
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008067 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008068 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008069 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008070 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8071 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008072 cfgerr++;
8073 goto out_uri_auth_compat;
8074 }
8075
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008076 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008077 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008078 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008079 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008080
Willy Tarreau95fa4692010-02-01 13:05:50 +01008081 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8082 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008083
8084 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008085 uri_auth_compat_req[i++] = "realm";
8086 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8087 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008088
Willy Tarreau95fa4692010-02-01 13:05:50 +01008089 uri_auth_compat_req[i++] = "unless";
8090 uri_auth_compat_req[i++] = "{";
8091 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8092 uri_auth_compat_req[i++] = "}";
8093 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008094
Willy Tarreauff011f22011-01-06 17:51:27 +01008095 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8096 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008097 cfgerr++;
8098 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008099 }
8100
Willy Tarreauff011f22011-01-06 17:51:27 +01008101 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008102
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008103 if (curproxy->uri_auth->auth_realm) {
8104 free(curproxy->uri_auth->auth_realm);
8105 curproxy->uri_auth->auth_realm = NULL;
8106 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008107
8108 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008109 }
8110out_uri_auth_compat:
8111
Dragan Dosen43885c72015-10-01 13:18:13 +02008112 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008113 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008114 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8115 if (!curproxy->conf.logformat_sd_string) {
8116 /* set the default logformat_sd_string */
8117 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8118 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008119 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008120 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008121 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008122
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008123 /* compile the log format */
8124 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008125 if (curproxy->conf.logformat_string != default_http_log_format &&
8126 curproxy->conf.logformat_string != default_tcp_log_format &&
8127 curproxy->conf.logformat_string != clf_http_log_format)
8128 free(curproxy->conf.logformat_string);
8129 curproxy->conf.logformat_string = NULL;
8130 free(curproxy->conf.lfs_file);
8131 curproxy->conf.lfs_file = NULL;
8132 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008133
8134 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8135 free(curproxy->conf.logformat_sd_string);
8136 curproxy->conf.logformat_sd_string = NULL;
8137 free(curproxy->conf.lfsd_file);
8138 curproxy->conf.lfsd_file = NULL;
8139 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008140 }
8141
Willy Tarreau62a61232013-04-12 18:13:46 +02008142 if (curproxy->conf.logformat_string) {
8143 curproxy->conf.args.ctx = ARGC_LOG;
8144 curproxy->conf.args.file = curproxy->conf.lfs_file;
8145 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008146 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008147 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008148 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008149 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8150 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008151 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008152 cfgerr++;
8153 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008154 curproxy->conf.args.file = NULL;
8155 curproxy->conf.args.line = 0;
8156 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008157
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008158 if (curproxy->conf.logformat_sd_string) {
8159 curproxy->conf.args.ctx = ARGC_LOGSD;
8160 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8161 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008162 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008163 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 +01008164 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008165 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8166 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008167 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008168 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008169 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008170 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8171 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008172 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008173 cfgerr++;
8174 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008175 curproxy->conf.args.file = NULL;
8176 curproxy->conf.args.line = 0;
8177 }
8178
Willy Tarreau62a61232013-04-12 18:13:46 +02008179 if (curproxy->conf.uniqueid_format_string) {
8180 curproxy->conf.args.ctx = ARGC_UIF;
8181 curproxy->conf.args.file = curproxy->conf.uif_file;
8182 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008183 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008184 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 +01008185 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008186 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8187 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008188 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008189 cfgerr++;
8190 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008191 curproxy->conf.args.file = NULL;
8192 curproxy->conf.args.line = 0;
8193 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008194
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008195 /* only now we can check if some args remain unresolved.
8196 * This must be done after the users and groups resolution.
8197 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008198 cfgerr += smp_resolve_args(curproxy);
8199 if (!cfgerr)
8200 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008201
Willy Tarreau2738a142006-07-08 17:28:09 +02008202 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008203 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008204 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008205 (!curproxy->timeout.connect ||
8206 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008207 ha_warning("config : missing timeouts for %s '%s'.\n"
8208 " | While not properly invalid, you will certainly encounter various problems\n"
8209 " | with such a configuration. To fix this, please ensure that all following\n"
8210 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8211 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008212 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008213 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008214
Willy Tarreau1fa31262007-12-03 00:36:16 +01008215 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8216 * We must still support older configurations, so let's find out whether those
8217 * parameters have been set or must be copied from contimeouts.
8218 */
8219 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008220 if (!curproxy->timeout.tarpit ||
8221 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008222 /* tarpit timeout not set. We search in the following order:
8223 * default.tarpit, curr.connect, default.connect.
8224 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008225 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008226 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008227 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008228 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008229 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008230 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008231 }
8232 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008233 (!curproxy->timeout.queue ||
8234 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008235 /* queue timeout not set. We search in the following order:
8236 * default.queue, curr.connect, default.connect.
8237 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008238 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008239 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008240 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008241 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008242 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008243 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008244 }
8245 }
8246
Willy Tarreau1620ec32011-08-06 17:05:02 +02008247 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008248 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008249 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008250 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008251 }
8252
Willy Tarreau215663d2014-06-13 18:30:23 +02008253 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8254 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008255 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8256 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008257 err_code |= ERR_WARN;
8258 }
8259
Willy Tarreau193b8c62012-11-22 00:17:38 +01008260 /* ensure that cookie capture length is not too large */
8261 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008262 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8263 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008264 err_code |= ERR_WARN;
8265 curproxy->capture_len = global.tune.cookie_len - 1;
8266 }
8267
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008268 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008269 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008270 curproxy->req_cap_pool = create_pool("ptrcap",
8271 curproxy->nb_req_cap * sizeof(char *),
8272 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008273 }
8274
8275 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008276 curproxy->rsp_cap_pool = create_pool("ptrcap",
8277 curproxy->nb_rsp_cap * sizeof(char *),
8278 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008279 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008280
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008281 switch (curproxy->load_server_state_from_file) {
8282 case PR_SRV_STATE_FILE_UNSPEC:
8283 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8284 break;
8285 case PR_SRV_STATE_FILE_GLOBAL:
8286 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008287 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",
8288 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008289 err_code |= ERR_WARN;
8290 }
8291 break;
8292 }
8293
Willy Tarreaubaaee002006-06-26 02:48:02 +02008294 /* first, we will invert the servers list order */
8295 newsrv = NULL;
8296 while (curproxy->srv) {
8297 struct server *next;
8298
8299 next = curproxy->srv->next;
8300 curproxy->srv->next = newsrv;
8301 newsrv = curproxy->srv;
8302 if (!next)
8303 break;
8304 curproxy->srv = next;
8305 }
8306
Willy Tarreau17edc812014-01-03 12:14:34 +01008307 /* Check that no server name conflicts. This causes trouble in the stats.
8308 * We only emit a warning for the first conflict affecting each server,
8309 * in order to avoid combinatory explosion if all servers have the same
8310 * name. We do that only for servers which do not have an explicit ID,
8311 * because these IDs were made also for distinguishing them and we don't
8312 * want to annoy people who correctly manage them.
8313 */
8314 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8315 struct server *other_srv;
8316
8317 if (newsrv->puid)
8318 continue;
8319
8320 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8321 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008322 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",
8323 newsrv->conf.file, newsrv->conf.line,
8324 proxy_type_str(curproxy), curproxy->id,
8325 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008326 break;
8327 }
8328 }
8329 }
8330
Willy Tarreaudd701652010-05-25 23:03:02 +02008331 /* assign automatic UIDs to servers which don't have one yet */
8332 next_id = 1;
8333 newsrv = curproxy->srv;
8334 while (newsrv != NULL) {
8335 if (!newsrv->puid) {
8336 /* server ID not set, use automatic numbering with first
8337 * spare entry starting with next_svid.
8338 */
8339 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8340 newsrv->conf.id.key = newsrv->puid = next_id;
8341 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8342 }
8343 next_id++;
8344 newsrv = newsrv->next;
8345 }
8346
Willy Tarreau20697042007-11-15 23:26:18 +01008347 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008348 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008349
Willy Tarreau62c3be22012-01-20 13:12:32 +01008350 /*
8351 * If this server supports a maxconn parameter, it needs a dedicated
8352 * tasks to fill the emptied slots when a connection leaves.
8353 * Also, resolve deferred tracking dependency if needed.
8354 */
8355 newsrv = curproxy->srv;
8356 while (newsrv != NULL) {
8357 if (newsrv->minconn > newsrv->maxconn) {
8358 /* Only 'minconn' was specified, or it was higher than or equal
8359 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8360 * this will avoid further useless expensive computations.
8361 */
8362 newsrv->maxconn = newsrv->minconn;
8363 } else if (newsrv->maxconn && !newsrv->minconn) {
8364 /* minconn was not specified, so we set it to maxconn */
8365 newsrv->minconn = newsrv->maxconn;
8366 }
8367
Willy Tarreau17d45382016-12-22 21:16:08 +01008368 /* this will also properly set the transport layer for prod and checks */
8369 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8370 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8371 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8372 }
Emeric Brun94324a42012-10-11 14:00:19 +02008373
Willy Tarreau2f075e92013-12-03 11:11:34 +01008374 /* set the check type on the server */
8375 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8376
Willy Tarreau62c3be22012-01-20 13:12:32 +01008377 if (newsrv->trackit) {
8378 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008379 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008380 char *pname, *sname;
8381
8382 pname = newsrv->trackit;
8383 sname = strrchr(pname, '/');
8384
8385 if (sname)
8386 *sname++ = '\0';
8387 else {
8388 sname = pname;
8389 pname = NULL;
8390 }
8391
8392 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008393 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008394 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008395 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8396 proxy_type_str(curproxy), curproxy->id,
8397 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008398 cfgerr++;
8399 goto next_srv;
8400 }
8401 } else
8402 px = curproxy;
8403
8404 srv = findserver(px, sname);
8405 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008406 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8407 proxy_type_str(curproxy), curproxy->id,
8408 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008409 cfgerr++;
8410 goto next_srv;
8411 }
8412
Willy Tarreau32091232014-05-16 13:52:00 +02008413 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8414 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8415 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008416 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8417 "tracking as it does not have any check nor agent enabled.\n",
8418 proxy_type_str(curproxy), curproxy->id,
8419 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008420 cfgerr++;
8421 goto next_srv;
8422 }
8423
8424 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8425
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008426 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008427 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8428 "belongs to a tracking chain looping back to %s/%s.\n",
8429 proxy_type_str(curproxy), curproxy->id,
8430 newsrv->id, px->id, srv->id, px->id,
8431 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008432 cfgerr++;
8433 goto next_srv;
8434 }
8435
8436 if (curproxy != px &&
8437 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008438 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8439 "tracking: disable-on-404 option inconsistency.\n",
8440 proxy_type_str(curproxy), curproxy->id,
8441 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008442 cfgerr++;
8443 goto next_srv;
8444 }
8445
Willy Tarreau62c3be22012-01-20 13:12:32 +01008446 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008447 newsrv->tracknext = srv->trackers;
8448 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008449
8450 free(newsrv->trackit);
8451 newsrv->trackit = NULL;
8452 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008453
Willy Tarreau62c3be22012-01-20 13:12:32 +01008454 next_srv:
8455 newsrv = newsrv->next;
8456 }
8457
Olivier Houchard4e694042017-03-14 20:01:29 +01008458 /*
8459 * Try to generate dynamic cookies for servers now.
8460 * It couldn't be done earlier, since at the time we parsed
8461 * the server line, we may not have known yet that we
8462 * should use dynamic cookies, or the secret key may not
8463 * have been provided yet.
8464 */
8465 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8466 newsrv = curproxy->srv;
8467 while (newsrv != NULL) {
8468 srv_set_dyncookie(newsrv);
8469 newsrv = newsrv->next;
8470 }
8471
8472 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008473 /* We have to initialize the server lookup mechanism depending
8474 * on what LB algorithm was choosen.
8475 */
8476
8477 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8478 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8479 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008480 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8481 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8482 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02008483 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
8484 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8485 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02008486 } else {
8487 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8488 fwrr_init_server_groups(curproxy);
8489 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008490 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008491
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008492 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008493 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8494 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8495 fwlc_init_server_tree(curproxy);
8496 } else {
8497 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8498 fas_init_server_tree(curproxy);
8499 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008500 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008501
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008502 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008503 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8504 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8505 chash_init_server_tree(curproxy);
8506 } else {
8507 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8508 init_server_map(curproxy);
8509 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008510 break;
8511 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008512 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008513
8514 if (curproxy->options & PR_O_LOGASAP)
8515 curproxy->to_log &= ~LW_BYTES;
8516
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008517 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008518 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8519 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008520 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8521 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008522 err_code |= ERR_WARN;
8523 }
8524
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008525 if (curproxy->mode != PR_MODE_HTTP) {
8526 int optnum;
8527
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008528 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008529 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8530 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008531 err_code |= ERR_WARN;
8532 curproxy->uri_auth = NULL;
8533 }
8534
Willy Tarreaude7dc882017-03-10 11:49:21 +01008535 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008536 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8537 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008538 err_code |= ERR_WARN;
8539 }
8540
8541 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008542 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8543 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008544 err_code |= ERR_WARN;
8545 }
8546
8547 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008548 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8549 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008550 err_code |= ERR_WARN;
8551 }
8552
8553 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008554 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8555 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008556 err_code |= ERR_WARN;
8557 }
8558
8559 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008560 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8561 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008562 err_code |= ERR_WARN;
8563 }
8564
Willy Tarreau87cf5142011-08-19 22:57:24 +02008565 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008566 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8567 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008568 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008569 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008570 }
8571
8572 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008573 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8574 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008575 err_code |= ERR_WARN;
8576 curproxy->options &= ~PR_O_ORGTO;
8577 }
8578
8579 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8580 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8581 (curproxy->cap & cfg_opts[optnum].cap) &&
8582 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008583 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8584 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008585 err_code |= ERR_WARN;
8586 curproxy->options &= ~cfg_opts[optnum].val;
8587 }
8588 }
8589
8590 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8591 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8592 (curproxy->cap & cfg_opts2[optnum].cap) &&
8593 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008594 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8595 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008596 err_code |= ERR_WARN;
8597 curproxy->options2 &= ~cfg_opts2[optnum].val;
8598 }
8599 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008600
Willy Tarreau29fbe512015-08-20 19:35:14 +02008601#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008602 if (curproxy->conn_src.bind_hdr_occ) {
8603 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008604 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8605 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008606 err_code |= ERR_WARN;
8607 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008608#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008609 }
8610
Willy Tarreaubaaee002006-06-26 02:48:02 +02008611 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008612 * ensure that we're not cross-dressing a TCP server into HTTP.
8613 */
8614 newsrv = curproxy->srv;
8615 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008616 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008617 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8618 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008619 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008620 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008621
Willy Tarreau0cec3312011-10-31 13:49:26 +01008622 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008623 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8624 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008625 err_code |= ERR_WARN;
8626 }
8627
Willy Tarreauc93cd162014-05-13 15:54:22 +02008628 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008629 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8630 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008631 err_code |= ERR_WARN;
8632 }
8633
Willy Tarreau29fbe512015-08-20 19:35:14 +02008634#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008635 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8636 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008637 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8638 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008639 err_code |= ERR_WARN;
8640 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008641#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008642
Willy Tarreau46deab62018-04-28 07:18:15 +02008643 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
8644 curproxy->options &= ~PR_O_REUSE_MASK;
8645
Willy Tarreau4c183462017-01-06 12:21:38 +01008646 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8647 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8648 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8649 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8650 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008651 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",
8652 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008653 err_code |= ERR_WARN;
8654 }
8655
8656
8657 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008658 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",
8659 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008660 err_code |= ERR_WARN;
8661 }
8662 }
8663
Willy Tarreau21d2af32008-02-14 20:25:24 +01008664 newsrv = newsrv->next;
8665 }
8666
Willy Tarreaue42bd962014-09-16 16:21:19 +02008667 /* check if we have a frontend with "tcp-request content" looking at L7
8668 * with no inspect-delay
8669 */
8670 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008671 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8672 if (arule->action == ACT_TCP_CAPTURE &&
8673 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008674 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008675 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8676 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008677 break;
8678 }
8679
Christopher Faulete4e830d2017-09-18 14:51:41 +02008680 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008681 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8682 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8683 " This means that these rules will randomly find their contents. This can be fixed by"
8684 " setting the tcp-request inspect-delay.\n",
8685 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008686 err_code |= ERR_WARN;
8687 }
8688 }
8689
Christopher Fauletd7c91962015-04-30 11:48:27 +02008690 /* Check filter configuration, if any */
8691 cfgerr += flt_check(curproxy);
8692
Willy Tarreauc1a21672009-08-16 22:37:44 +02008693 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008694 if (!curproxy->accept)
8695 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008696
Willy Tarreauc1a21672009-08-16 22:37:44 +02008697 if (curproxy->tcp_req.inspect_delay ||
8698 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008699 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008700
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008701 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008702 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008703 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008704 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008705
8706 /* both TCP and HTTP must check switching rules */
8707 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008708
8709 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008710 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008711 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8712 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 +01008713 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008714 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8715 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008716 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008717 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008718 }
8719
8720 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008721 if (curproxy->tcp_req.inspect_delay ||
8722 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8723 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8724
Emeric Brun97679e72010-09-23 17:56:44 +02008725 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8726 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8727
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008728 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008729 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008730 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008731 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008732
8733 /* If the backend does requires RDP cookie persistence, we have to
8734 * enable the corresponding analyser.
8735 */
8736 if (curproxy->options2 & PR_O2_RDPC_PRST)
8737 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008738
8739 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008740 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008741 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8742 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 +01008743 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008744 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8745 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008746 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008747 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008748 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008749 }
8750
8751 /***********************************************************/
8752 /* At this point, target names have already been resolved. */
8753 /***********************************************************/
8754
8755 /* Check multi-process mode compatibility */
8756
8757 if (global.nbproc > 1 && global.stats_fe) {
8758 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8759 unsigned long mask;
8760
8761 mask = nbits(global.nbproc);
8762 if (global.stats_fe->bind_proc)
8763 mask &= global.stats_fe->bind_proc;
8764
8765 if (bind_conf->bind_proc)
8766 mask &= bind_conf->bind_proc;
8767
8768 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008769 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008770 break;
8771 }
8772 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008773 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 +02008774 }
8775 }
8776
8777 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008778 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008779 if (curproxy->bind_proc)
8780 continue;
8781
8782 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8783 unsigned long mask;
8784
Willy Tarreaue428b082015-05-04 21:57:58 +02008785 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008786 curproxy->bind_proc |= mask;
8787 }
8788
8789 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008790 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008791 }
8792
8793 if (global.stats_fe) {
8794 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8795 unsigned long mask;
8796
Cyril Bonté06181952016-02-24 00:14:54 +01008797 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008798 global.stats_fe->bind_proc |= mask;
8799 }
8800 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008801 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008802 }
8803
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008804 /* propagate bindings from frontends to backends. Don't do it if there
8805 * are any fatal errors as we must not call it with unresolved proxies.
8806 */
8807 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008808 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008809 if (curproxy->cap & PR_CAP_FE)
8810 propagate_processes(curproxy, NULL);
8811 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008812 }
8813
8814 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008815 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008816 if (curproxy->bind_proc)
8817 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008818 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008819 }
8820
8821 /*******************************************************/
8822 /* At this step, all proxies have a non-null bind_proc */
8823 /*******************************************************/
8824
8825 /* perform the final checks before creating tasks */
8826
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008827 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008828 struct listener *listener;
8829 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008830
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008831 /* Configure SSL for each bind line.
8832 * Note: if configuration fails at some point, the ->ctx member
8833 * remains NULL so that listeners can later detach.
8834 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008835 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008836 if (bind_conf->xprt->prepare_bind_conf &&
8837 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008838 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008839 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008840
Willy Tarreaue6b98942007-10-29 01:09:36 +01008841 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008842 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008843 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008844 int nbproc;
8845
8846 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008847 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008848 nbits(global.nbproc));
8849
8850 if (!nbproc) /* no intersection between listener and frontend */
8851 nbproc = 1;
8852
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008853 if (!listener->luid) {
8854 /* listener ID not set, use automatic numbering with first
8855 * spare entry starting with next_luid.
8856 */
8857 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8858 listener->conf.id.key = listener->luid = next_id;
8859 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008860 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008861 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008862
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008863 /* enable separate counters */
8864 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008865 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008866 if (!listener->name)
8867 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008868 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008869
Willy Tarreaue6b98942007-10-29 01:09:36 +01008870 if (curproxy->options & PR_O_TCP_NOLING)
8871 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008872 if (!listener->maxconn)
8873 listener->maxconn = curproxy->maxconn;
8874 if (!listener->backlog)
8875 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008876 if (!listener->maxaccept)
8877 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8878
8879 /* we want to have an optimal behaviour on single process mode to
8880 * maximize the work at once, but in multi-process we want to keep
8881 * some fairness between processes, so we target half of the max
8882 * number of events to be balanced over all the processes the proxy
8883 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8884 * used to disable the limit.
8885 */
8886 if (listener->maxaccept > 0) {
8887 if (nbproc > 1)
8888 listener->maxaccept = (listener->maxaccept + 1) / 2;
8889 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8890 }
8891
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008892 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008893 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008894 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008895
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008896 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008897 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008898
Willy Tarreau620408f2016-10-21 16:37:51 +02008899 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8900 listener->options |= LI_O_TCP_L5_RULES;
8901
Willy Tarreaude3041d2010-05-31 10:56:17 +02008902 if (curproxy->mon_mask.s_addr)
8903 listener->options |= LI_O_CHK_MONNET;
8904
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008905 /* smart accept mode is automatic in HTTP mode */
8906 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008907 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008908 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8909 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008910 }
8911
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008912 /* Release unused SSL configs */
8913 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008914 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8915 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008916 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008917
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008918 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008919 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008920 int count, maxproc = 0;
8921
8922 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008923 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008924 if (count > maxproc)
8925 maxproc = count;
8926 }
8927 /* backends have 0, frontends have 1 or more */
8928 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008929 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8930 " limited to process assigned to the current request.\n",
8931 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008932
Willy Tarreau102df612014-05-07 23:56:38 +02008933 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008934 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
8935 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008936 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008937 }
Willy Tarreau102df612014-05-07 23:56:38 +02008938 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008939 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
8940 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008941 }
8942 }
Willy Tarreau918ff602011-07-25 16:33:49 +02008943
8944 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02008945 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02008946 if (curproxy->task) {
8947 curproxy->task->context = curproxy;
8948 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02008949 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008950 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
8951 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02008952 cfgerr++;
8953 }
Willy Tarreaub369a042014-09-16 13:21:03 +02008954 }
8955
Willy Tarreaufbb78422011-06-05 15:38:35 +02008956 /* automatically compute fullconn if not set. We must not do it in the
8957 * loop above because cross-references are not yet fully resolved.
8958 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008959 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008960 /* If <fullconn> is not set, let's set it to 10% of the sum of
8961 * the possible incoming frontend's maxconns.
8962 */
8963 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008964 /* we have the sum of the maxconns in <total>. We only
8965 * keep 10% of that sum to set the default fullconn, with
8966 * a hard minimum of 1 (to avoid a divide by zero).
8967 */
Emeric Brun3f783572017-01-12 11:21:28 +01008968 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02008969 if (!curproxy->fullconn)
8970 curproxy->fullconn = 1;
8971 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01008972 }
8973
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008974 /*
8975 * Recount currently required checks.
8976 */
8977
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008978 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008979 int optnum;
8980
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008981 for (optnum = 0; cfg_opts[optnum].name; optnum++)
8982 if (curproxy->options & cfg_opts[optnum].val)
8983 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008984
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008985 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
8986 if (curproxy->options2 & cfg_opts2[optnum].val)
8987 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008988 }
8989
Willy Tarreau0fca4832015-05-01 19:12:05 +02008990 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008991 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02008992 if (curproxy->table.peers.p)
8993 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
8994
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008995 if (cfg_peers) {
8996 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02008997 struct peer *p, *pb;
8998
Willy Tarreau1e273012015-05-01 19:15:17 +02008999 /* Remove all peers sections which don't have a valid listener,
9000 * which are not used by any table, or which are bound to more
9001 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009002 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009003 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009004 while (*last) {
9005 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009006
9007 if (curpeers->state == PR_STSTOPPED) {
9008 /* the "disabled" keyword was present */
9009 if (curpeers->peers_fe)
9010 stop_proxy(curpeers->peers_fe);
9011 curpeers->peers_fe = NULL;
9012 }
9013 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009014 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9015 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009016 }
David Carliere6c39412015-07-02 07:00:17 +00009017 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009018 /* either it's totally stopped or too much used */
9019 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009020 ha_alert("Peers section '%s': peers referenced by sections "
9021 "running in different processes (%d different ones). "
9022 "Check global.nbproc and all tables' bind-process "
9023 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009024 cfgerr++;
9025 }
9026 stop_proxy(curpeers->peers_fe);
9027 curpeers->peers_fe = NULL;
9028 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009029 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009030 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009031 last = &curpeers->next;
9032 continue;
9033 }
9034
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009035 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009036 p = curpeers->remote;
9037 while (p) {
9038 pb = p->next;
9039 free(p->id);
9040 free(p);
9041 p = pb;
9042 }
9043
9044 /* Destroy and unlink this curpeers section.
9045 * Note: curpeers is backed up into *last.
9046 */
9047 free(curpeers->id);
9048 curpeers = curpeers->next;
9049 free(*last);
9050 *last = curpeers;
9051 }
9052 }
9053
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009054 /* initialize stick-tables on backend capable proxies. This must not
9055 * be done earlier because the data size may be discovered while parsing
9056 * other proxies.
9057 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009058 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009059 if (curproxy->state == PR_STSTOPPED)
9060 continue;
9061
9062 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009063 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009064 cfgerr++;
9065 }
9066 }
9067
Simon Horman0d16a402015-01-30 11:22:58 +09009068 if (mailers) {
9069 struct mailers *curmailers = mailers, **last;
9070 struct mailer *m, *mb;
9071
9072 /* Remove all mailers sections which don't have a valid listener.
9073 * This can happen when a mailers section is never referenced.
9074 */
9075 last = &mailers;
9076 while (*last) {
9077 curmailers = *last;
9078 if (curmailers->users) {
9079 last = &curmailers->next;
9080 continue;
9081 }
9082
Christopher Faulet767a84b2017-11-24 16:50:31 +01009083 ha_warning("Removing incomplete section 'mailers %s'.\n",
9084 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009085
9086 m = curmailers->mailer_list;
9087 while (m) {
9088 mb = m->next;
9089 free(m->id);
9090 free(m);
9091 m = mb;
9092 }
9093
9094 /* Destroy and unlink this curmailers section.
9095 * Note: curmailers is backed up into *last.
9096 */
9097 free(curmailers->id);
9098 curmailers = curmailers->next;
9099 free(*last);
9100 *last = curmailers;
9101 }
9102 }
9103
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009104 /* Update server_state_file_name to backend name if backend is supposed to use
9105 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009106 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009107 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9108 curproxy->server_state_file_name == NULL)
9109 curproxy->server_state_file_name = strdup(curproxy->id);
9110 }
9111
Willy Tarreaubafbe012017-11-24 17:34:44 +01009112 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009113 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009114 MEM_F_SHARED);
9115
Ben Draut054fbee2018-04-13 15:43:04 -06009116 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
9117 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
9118 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
9119 curr_resolvers->id, curr_resolvers->conf.file,
9120 curr_resolvers->conf.line);
9121 err_code |= ERR_WARN;
9122 }
9123 }
9124
William Lallemand48b4bb42017-10-23 14:36:34 +02009125 list_for_each_entry(postparser, &postparsers, list) {
9126 if (postparser->func)
9127 cfgerr += postparser->func();
9128 }
9129
Willy Tarreaubb925012009-07-23 13:36:36 +02009130 if (cfgerr > 0)
9131 err_code |= ERR_ALERT | ERR_FATAL;
9132 out:
9133 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009134}
9135
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009136/*
9137 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9138 * parsing sessions.
9139 */
9140void cfg_register_keywords(struct cfg_kw_list *kwl)
9141{
9142 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9143}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009144
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009145/*
9146 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9147 */
9148void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9149{
9150 LIST_DEL(&kwl->list);
9151 LIST_INIT(&kwl->list);
9152}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009153
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009154/* this function register new section in the haproxy configuration file.
9155 * <section_name> is the name of this new section and <section_parser>
9156 * is the called parser. If two section declaration have the same name,
9157 * only the first declared is used.
9158 */
9159int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009160 int (*section_parser)(const char *, int, char **, int),
9161 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009162{
9163 struct cfg_section *cs;
9164
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009165 list_for_each_entry(cs, &sections, list) {
9166 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009167 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009168 return 0;
9169 }
9170 }
9171
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009172 cs = calloc(1, sizeof(*cs));
9173 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009174 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009175 return 0;
9176 }
9177
9178 cs->section_name = section_name;
9179 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009180 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009181
9182 LIST_ADDQ(&sections, &cs->list);
9183
9184 return 1;
9185}
9186
William Lallemand48b4bb42017-10-23 14:36:34 +02009187/* this function register a new function which will be called once the haproxy
9188 * configuration file has been parsed. It's useful to check dependencies
9189 * between sections or to resolve items once everything is parsed.
9190 */
9191int cfg_register_postparser(char *name, int (*func)())
9192{
9193 struct cfg_postparser *cp;
9194
9195 cp = calloc(1, sizeof(*cp));
9196 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009197 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009198 return 0;
9199 }
9200 cp->name = name;
9201 cp->func = func;
9202
9203 LIST_ADDQ(&postparsers, &cp->list);
9204
9205 return 1;
9206}
9207
Willy Tarreaubaaee002006-06-26 02:48:02 +02009208/*
David Carlier845efb52015-09-25 11:49:18 +01009209 * free all config section entries
9210 */
9211void cfg_unregister_sections(void)
9212{
9213 struct cfg_section *cs, *ics;
9214
9215 list_for_each_entry_safe(cs, ics, &sections, list) {
9216 LIST_DEL(&cs->list);
9217 free(cs);
9218 }
9219}
9220
Christopher Faulet7110b402016-10-26 11:09:44 +02009221void cfg_backup_sections(struct list *backup_sections)
9222{
9223 struct cfg_section *cs, *ics;
9224
9225 list_for_each_entry_safe(cs, ics, &sections, list) {
9226 LIST_DEL(&cs->list);
9227 LIST_ADDQ(backup_sections, &cs->list);
9228 }
9229}
9230
9231void cfg_restore_sections(struct list *backup_sections)
9232{
9233 struct cfg_section *cs, *ics;
9234
9235 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9236 LIST_DEL(&cs->list);
9237 LIST_ADDQ(&sections, &cs->list);
9238 }
9239}
9240
Willy Tarreau659fbf02016-05-26 17:55:28 +02009241__attribute__((constructor))
9242static void cfgparse_init(void)
9243{
9244 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009245 cfg_register_section("listen", cfg_parse_listen, NULL);
9246 cfg_register_section("frontend", cfg_parse_listen, NULL);
9247 cfg_register_section("backend", cfg_parse_listen, NULL);
9248 cfg_register_section("defaults", cfg_parse_listen, NULL);
9249 cfg_register_section("global", cfg_parse_global, NULL);
9250 cfg_register_section("userlist", cfg_parse_users, NULL);
9251 cfg_register_section("peers", cfg_parse_peers, NULL);
9252 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9253 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9254 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009255}
9256
David Carlier845efb52015-09-25 11:49:18 +01009257/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009258 * Local variables:
9259 * c-indent-level: 8
9260 * c-basic-offset: 8
9261 * End:
9262 */