blob: 803a9189bd8531430d5764c183031a491fc0551e [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 }
Willy Tarreau0ccd3222018-07-30 10:34:35 +02001193 global.nbthread = parse_nbthread(args[1], &errmsg);
1194 if (!global.nbthread) {
1195 ha_alert("parsing [%s:%d] : '%s' %s.\n",
1196 file, linenum, args[0], errmsg);
Willy Tarreau421f02e2018-01-20 18:19:22 +01001197 err_code |= ERR_ALERT | ERR_FATAL;
1198 goto out;
1199 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001200 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001201 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001202 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1203 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001204 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001205 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001206 err_code |= ERR_ALERT;
1207 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001208 }
1209 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001210 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001211 err_code |= ERR_ALERT | ERR_FATAL;
1212 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001213 }
1214 global.maxconn = atol(args[1]);
1215#ifdef SYSTEM_MAXCONN
1216 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001217 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 +02001218 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001219 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001220 }
1221#endif /* SYSTEM_MAXCONN */
1222 }
Emeric Brun850efd52014-01-29 12:24:34 +01001223 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001224 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1225 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001226 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001227 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001228 err_code |= ERR_ALERT | ERR_FATAL;
1229 goto out;
1230 }
1231 if (strcmp(args[1],"none") == 0)
1232 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1233 else if (strcmp(args[1],"required") == 0)
1234 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1235 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001236 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001237 err_code |= ERR_ALERT | ERR_FATAL;
1238 goto out;
1239 }
1240 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001241 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001242 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1243 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001244 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001245 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001246 err_code |= ERR_ALERT;
1247 goto out;
1248 }
1249 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001250 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001251 err_code |= ERR_ALERT | ERR_FATAL;
1252 goto out;
1253 }
1254 global.cps_lim = atol(args[1]);
1255 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001256 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001257 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1258 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001259 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001260 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001261 err_code |= ERR_ALERT;
1262 goto out;
1263 }
1264 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001265 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001266 err_code |= ERR_ALERT | ERR_FATAL;
1267 goto out;
1268 }
1269 global.sps_lim = atol(args[1]);
1270 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001271 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001272 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1273 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001274 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001275 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001276 err_code |= ERR_ALERT;
1277 goto out;
1278 }
1279 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001280 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001281 err_code |= ERR_ALERT | ERR_FATAL;
1282 goto out;
1283 }
1284 global.ssl_lim = atol(args[1]);
1285 }
William Lallemandd85f9172012-11-09 17:05:39 +01001286 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001287 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1288 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001289 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001290 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 +01001291 err_code |= ERR_ALERT | ERR_FATAL;
1292 goto out;
1293 }
1294 global.comp_rate_lim = atoi(args[1]) * 1024;
1295 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001296 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001297 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1298 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001299 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001300 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001301 err_code |= ERR_ALERT;
1302 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001303 }
1304 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001305 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001306 err_code |= ERR_ALERT | ERR_FATAL;
1307 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001308 }
1309 global.maxpipes = atol(args[1]);
1310 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001311 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001312 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1313 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001314 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001315 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001316 err_code |= ERR_ALERT | ERR_FATAL;
1317 goto out;
1318 }
William Lallemande3a7d992012-11-20 11:25:20 +01001319 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001320 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001321 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001322 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1323 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001324 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001325 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 +01001326 err_code |= ERR_ALERT | ERR_FATAL;
1327 goto out;
1328 }
1329 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001330 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001331 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 +01001332 err_code |= ERR_ALERT | ERR_FATAL;
1333 goto out;
1334 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001335 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001336
Willy Tarreaubaaee002006-06-26 02:48:02 +02001337 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001338 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1339 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001340 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001341 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001342 err_code |= ERR_ALERT;
1343 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001344 }
1345 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001346 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001347 err_code |= ERR_ALERT | ERR_FATAL;
1348 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001349 }
1350 global.rlimit_nofile = atol(args[1]);
1351 }
1352 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001353 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1354 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001355 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001356 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001357 err_code |= ERR_ALERT;
1358 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001359 }
1360 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001361 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001362 err_code |= ERR_ALERT | ERR_FATAL;
1363 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001364 }
1365 global.chroot = strdup(args[1]);
1366 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001367 else if (!strcmp(args[0], "description")) {
1368 int i, len=0;
1369 char *d;
1370
1371 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001372 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1373 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001374 err_code |= ERR_ALERT | ERR_FATAL;
1375 goto out;
1376 }
1377
Willy Tarreau348acfe2014-04-14 15:00:39 +02001378 for (i = 1; *args[i]; i++)
1379 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001380
1381 if (global.desc)
1382 free(global.desc);
1383
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001384 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001385
Willy Tarreau348acfe2014-04-14 15:00:39 +02001386 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1387 for (i = 2; *args[i]; i++)
1388 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001389 }
1390 else if (!strcmp(args[0], "node")) {
1391 int i;
1392 char c;
1393
William Lallemand1a748ae2015-05-19 16:37:23 +02001394 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1395 goto out;
1396
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001397 for (i=0; args[1][i]; i++) {
1398 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001399 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1400 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001401 break;
1402 }
1403
1404 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001405 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1406 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1407 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001408 err_code |= ERR_ALERT | ERR_FATAL;
1409 goto out;
1410 }
1411
1412 if (global.node)
1413 free(global.node);
1414
1415 global.node = strdup(args[1]);
1416 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001417 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001418 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1419 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001420 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001421 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001422 err_code |= ERR_ALERT;
1423 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001424 }
1425 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001426 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 +02001427 err_code |= ERR_ALERT | ERR_FATAL;
1428 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001429 }
1430 global.pidfile = strdup(args[1]);
1431 }
Emeric Bruned760922010-10-22 17:59:25 +02001432 else if (!strcmp(args[0], "unix-bind")) {
1433 int cur_arg = 1;
1434 while (*(args[cur_arg])) {
1435 if (!strcmp(args[cur_arg], "prefix")) {
1436 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001437 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001438 err_code |= ERR_ALERT;
1439 cur_arg += 2;
1440 continue;
1441 }
1442
1443 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001444 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 +02001445 err_code |= ERR_ALERT | ERR_FATAL;
1446 goto out;
1447 }
1448 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1449 cur_arg += 2;
1450 continue;
1451 }
1452
1453 if (!strcmp(args[cur_arg], "mode")) {
1454
1455 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1456 cur_arg += 2;
1457 continue;
1458 }
1459
1460 if (!strcmp(args[cur_arg], "uid")) {
1461
1462 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1463 cur_arg += 2;
1464 continue;
1465 }
1466
1467 if (!strcmp(args[cur_arg], "gid")) {
1468
1469 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1470 cur_arg += 2;
1471 continue;
1472 }
1473
1474 if (!strcmp(args[cur_arg], "user")) {
1475 struct passwd *user;
1476
1477 user = getpwnam(args[cur_arg + 1]);
1478 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001479 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1480 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001481 err_code |= ERR_ALERT | ERR_FATAL;
1482 goto out;
1483 }
1484
1485 global.unix_bind.ux.uid = user->pw_uid;
1486 cur_arg += 2;
1487 continue;
1488 }
1489
1490 if (!strcmp(args[cur_arg], "group")) {
1491 struct group *group;
1492
1493 group = getgrnam(args[cur_arg + 1]);
1494 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001495 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1496 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001497 err_code |= ERR_ALERT | ERR_FATAL;
1498 goto out;
1499 }
1500
1501 global.unix_bind.ux.gid = group->gr_gid;
1502 cur_arg += 2;
1503 continue;
1504 }
1505
Christopher Faulet767a84b2017-11-24 16:50:31 +01001506 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1507 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001508 err_code |= ERR_ALERT | ERR_FATAL;
1509 goto out;
1510 }
1511 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001512 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1513 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1514 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001515 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001516 goto out;
1517 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001518 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001519 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1520 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001521
1522 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001523 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001524 err_code |= ERR_ALERT;
1525 goto out;
1526 }
1527
1528 if (*(args[1]))
1529 name = args[1];
1530 else
1531 name = hostname;
1532
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001533 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001534 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001535 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001536 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1537 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001538 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001539 err_code |= ERR_ALERT;
1540 goto out;
1541 }
1542
1543 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001544 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001545 err_code |= ERR_FATAL;
1546 goto out;
1547 }
1548
1549 global.server_state_base = strdup(args[1]);
1550 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001551 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1552 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001553 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001554 err_code |= ERR_ALERT;
1555 goto out;
1556 }
1557
1558 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001559 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001560 err_code |= ERR_FATAL;
1561 goto out;
1562 }
1563
1564 global.server_state_file = strdup(args[1]);
1565 }
Kevinm48936af2010-12-22 16:08:21 +00001566 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001567 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1568 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001569 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001570 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001571 err_code |= ERR_ALERT | ERR_FATAL;
1572 goto out;
1573 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001574 chunk_destroy(&global.log_tag);
1575 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001576 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001577 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001578 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1579 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001580 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001581 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001582 err_code |= ERR_ALERT;
1583 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001584 }
1585 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001586 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001587 err_code |= ERR_ALERT | ERR_FATAL;
1588 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001589 }
1590 global.spread_checks = atol(args[1]);
1591 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001592 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 +02001593 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001594 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001595 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001596 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1597 const char *err;
1598 unsigned int val;
1599
William Lallemand1a748ae2015-05-19 16:37:23 +02001600 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1601 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001602 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001603 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001604 err_code |= ERR_ALERT | ERR_FATAL;
1605 goto out;
1606 }
1607
1608 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1609 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001610 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 +02001611 err_code |= ERR_ALERT | ERR_FATAL;
1612 }
1613 global.max_spread_checks = val;
1614 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001615 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001616 err_code |= ERR_ALERT | ERR_FATAL;
1617 }
1618 }
Christopher Faulet62519022017-10-16 15:49:32 +02001619 else if (strcmp(args[0], "cpu-map") == 0) {
1620 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001621#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001622 char *slash;
1623 unsigned long proc = 0, thread = 0, cpus;
1624 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001625
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001626 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001627 ha_alert("parsing [%s:%d] : %s expects a process number "
1628 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1629 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1630 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001631 err_code |= ERR_ALERT | ERR_FATAL;
1632 goto out;
1633 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001634
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001635 if ((slash = strchr(args[1], '/')) != NULL)
1636 *slash = 0;
1637
Christopher Faulet26028f62017-11-22 15:01:51 +01001638 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001639 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001640 err_code |= ERR_ALERT | ERR_FATAL;
1641 goto out;
1642 }
1643
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001644 if (slash) {
1645 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001646 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001647 err_code |= ERR_ALERT | ERR_FATAL;
1648 goto out;
1649 }
1650 *slash = '/';
1651
1652 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001653 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1654 "a process range _AND_ a thread range\n",
1655 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001656 err_code |= ERR_ALERT | ERR_FATAL;
1657 goto out;
1658 }
1659 }
1660
Christopher Faulet62519022017-10-16 15:49:32 +02001661 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001662 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001663 err_code |= ERR_ALERT | ERR_FATAL;
1664 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001665 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001666
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001667 if (autoinc &&
1668 my_popcountl(proc) != my_popcountl(cpus) &&
1669 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001670 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1671 "must have the same size to be automatically bound\n",
1672 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001673 err_code |= ERR_ALERT | ERR_FATAL;
1674 goto out;
1675 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001676
Christopher Faulet26028f62017-11-22 15:01:51 +01001677 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001678 /* No mapping for this process */
1679 if (!(proc & (1UL << i)))
1680 continue;
1681
1682 /* Mapping at the process level */
1683 if (!thread) {
1684 if (!autoinc)
1685 global.cpu_map.proc[i] = cpus;
1686 else {
1687 n += my_ffsl(cpus >> n);
1688 global.cpu_map.proc[i] = (1UL << (n-1));
1689 }
1690 continue;
1691 }
1692
1693 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001694 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001695 /* Np mapping for this thread */
1696 if (!(thread & (1UL << j)))
1697 continue;
1698
1699 if (!autoinc)
1700 global.cpu_map.thread[i][j] = cpus;
1701 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001702 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001703 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001704 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001705 }
1706 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001707#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001708 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1709 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001710 err_code |= ERR_ALERT | ERR_FATAL;
1711 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001712#endif /* ! USE_CPU_AFFINITY */
1713 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001714 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1715 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1716 goto out;
1717
1718 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001719 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001720 err_code |= ERR_ALERT | ERR_FATAL;
1721 goto out;
1722 }
1723
1724 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1725 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001726 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 +01001727 err_code |= ERR_ALERT | ERR_FATAL;
1728 goto out;
1729 }
1730 }
1731 else if (!strcmp(args[0], "unsetenv")) {
1732 int arg;
1733
1734 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001735 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001736 err_code |= ERR_ALERT | ERR_FATAL;
1737 goto out;
1738 }
1739
1740 for (arg = 1; *args[arg]; arg++) {
1741 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001742 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
Willy Tarreau1d549722016-02-16 12:41:57 +01001743 err_code |= ERR_ALERT | ERR_FATAL;
1744 goto out;
1745 }
1746 }
1747 }
1748 else if (!strcmp(args[0], "resetenv")) {
1749 extern char **environ;
1750 char **env = environ;
1751
1752 /* args contain variable names to keep, one per argument */
1753 while (*env) {
1754 int arg;
1755
1756 /* look for current variable in among all those we want to keep */
1757 for (arg = 1; *args[arg]; arg++) {
1758 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1759 (*env)[strlen(args[arg])] == '=')
1760 break;
1761 }
1762
1763 /* delete this variable */
1764 if (!*args[arg]) {
1765 char *delim = strchr(*env, '=');
1766
1767 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001768 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 +01001769 err_code |= ERR_ALERT | ERR_FATAL;
1770 goto out;
1771 }
1772
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001773 memcpy(trash.area, *env, delim - *env);
1774 trash.area[delim - *env] = 0;
Willy Tarreau1d549722016-02-16 12:41:57 +01001775
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001776 if (unsetenv(trash.area) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001777 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 +01001778 err_code |= ERR_ALERT | ERR_FATAL;
1779 goto out;
1780 }
1781 }
1782 else
1783 env++;
1784 }
1785 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001786 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001787 struct cfg_kw_list *kwl;
1788 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001789 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001790
1791 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1792 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1793 if (kwl->kw[index].section != CFG_GLOBAL)
1794 continue;
1795 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001796 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001797 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001798 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001799 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001800 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001801 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001802 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001803 err_code |= ERR_WARN;
1804 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001805 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001806 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001807 }
1808 }
1809 }
1810
Christopher Faulet767a84b2017-11-24 16:50:31 +01001811 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001812 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001813 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001814
Willy Tarreau058e9072009-07-20 09:30:05 +02001815 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001816 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001817 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001818}
1819
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001820void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001821{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001822 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001823 defproxy.mode = PR_MODE_TCP;
1824 defproxy.state = PR_STNEW;
1825 defproxy.maxconn = cfg_maxpconn;
1826 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001827 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001828 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001829
Simon Horman66183002013-02-23 10:16:43 +09001830 defproxy.defsrv.check.inter = DEF_CHKINTR;
1831 defproxy.defsrv.check.fastinter = 0;
1832 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001833 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1834 defproxy.defsrv.agent.fastinter = 0;
1835 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001836 defproxy.defsrv.check.rise = DEF_RISETIME;
1837 defproxy.defsrv.check.fall = DEF_FALLTIME;
1838 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1839 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001840 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001841 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001842 defproxy.defsrv.maxqueue = 0;
1843 defproxy.defsrv.minconn = 0;
1844 defproxy.defsrv.maxconn = 0;
1845 defproxy.defsrv.slowstart = 0;
1846 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1847 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1848 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001849
1850 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001851 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001852}
1853
Willy Tarreauade5ec42010-01-28 19:33:49 +01001854
Willy Tarreau63af98d2014-05-18 08:11:41 +02001855/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1856 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1857 * ERR_FATAL in case of error.
1858 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001859static int create_cond_regex_rule(const char *file, int line,
1860 struct proxy *px, int dir, int action, int flags,
1861 const char *cmd, const char *reg, const char *repl,
1862 const char **cond_start)
1863{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001864 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001865 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001866 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001867 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001868 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001869 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001870 int cs;
1871 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001872
1873 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001874 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001875 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001876 goto err;
1877 }
1878
1879 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001880 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001881 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001882 goto err;
1883 }
1884
Christopher Faulet898566e2016-10-26 11:06:28 +02001885 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001886 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001887
Willy Tarreau5321c422010-01-28 20:35:13 +01001888 if (cond_start &&
1889 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001890 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001891 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1892 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001893 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001894 goto err;
1895 }
1896 }
1897 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001898 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1899 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001900 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001901 goto err;
1902 }
1903
Willy Tarreau63af98d2014-05-18 08:11:41 +02001904 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001905 (dir == SMP_OPT_DIR_REQ) ?
1906 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1907 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1908 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001909
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001910 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001911 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001912 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001913 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001914 goto err;
1915 }
1916
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001917 cs = !(flags & REG_ICASE);
1918 cap = !(flags & REG_NOSUB);
1919 error = NULL;
1920 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001921 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001922 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001923 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001924 goto err;
1925 }
1926
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001927 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001928 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001929 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001930 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1931 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001932 ret_code |= ERR_ALERT | ERR_FATAL;
1933 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001934 }
1935
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001936 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001937 ret_code |= ERR_WARN;
1938
1939 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001940
Willy Tarreau63af98d2014-05-18 08:11:41 +02001941 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001942 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001943 err:
1944 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001945 free(errmsg);
1946 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001947}
1948
Willy Tarreaubaaee002006-06-26 02:48:02 +02001949/*
William Lallemand51097192015-04-14 16:35:22 +02001950 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001951 * Returns the error code, 0 if OK, or any combination of :
1952 * - ERR_ABORT: must abort ASAP
1953 * - ERR_FATAL: we can continue parsing but not start the service
1954 * - ERR_WARN: a warning has been emitted
1955 * - ERR_ALERT: an alert has been emitted
1956 * Only the two first ones can stop processing, the two others are just
1957 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001958 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001959int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1960{
1961 static struct peers *curpeers = NULL;
1962 struct peer *newpeer = NULL;
1963 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001964 struct bind_conf *bind_conf;
1965 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001966 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001967 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001968
1969 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001970 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001971 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001972 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001973 goto out;
1974 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001975
William Lallemand6e62fb62015-04-28 16:55:23 +02001976 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1977 goto out;
1978
Emeric Brun32da3c42010-09-23 18:39:19 +02001979 err = invalid_char(args[1]);
1980 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001981 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1982 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001983 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001984 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02001985 }
1986
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02001987 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02001988 /*
1989 * If there are two proxies with the same name only following
1990 * combinations are allowed:
1991 */
1992 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001993 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
1994 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02001995 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001996 }
1997 }
1998
Vincent Bernat02779b62016-04-03 13:48:43 +02001999 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002000 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002001 err_code |= ERR_ALERT | ERR_ABORT;
2002 goto out;
2003 }
2004
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002005 curpeers->next = cfg_peers;
2006 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002007 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002008 curpeers->conf.line = linenum;
2009 curpeers->last_change = now.tv_sec;
2010 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002011 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002012 }
2013 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002014 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002015 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002016 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002017
2018 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002019 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2020 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002021 err_code |= ERR_ALERT | ERR_FATAL;
2022 goto out;
2023 }
2024
2025 err = invalid_char(args[1]);
2026 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002027 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2028 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002029 err_code |= ERR_ALERT | ERR_FATAL;
2030 goto out;
2031 }
2032
Vincent Bernat02779b62016-04-03 13:48:43 +02002033 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002034 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002035 err_code |= ERR_ALERT | ERR_ABORT;
2036 goto out;
2037 }
2038
2039 /* the peers are linked backwards first */
2040 curpeers->count++;
2041 newpeer->next = curpeers->remote;
2042 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002043 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002044 newpeer->conf.line = linenum;
2045
2046 newpeer->last_change = now.tv_sec;
2047 newpeer->id = strdup(args[1]);
2048
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002049 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002050 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002051 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002052 err_code |= ERR_ALERT | ERR_FATAL;
2053 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002054 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002055
2056 proto = protocol_by_family(sk->ss_family);
2057 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002058 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2059 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002060 err_code |= ERR_ALERT | ERR_FATAL;
2061 goto out;
2062 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002063
2064 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002065 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2066 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002067 err_code |= ERR_ALERT | ERR_FATAL;
2068 goto out;
2069 }
2070
Willy Tarreau2aa38802013-02-20 19:20:59 +01002071 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002072 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2073 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002074 err_code |= ERR_ALERT | ERR_FATAL;
2075 goto out;
2076 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002077
Emeric Brun32da3c42010-09-23 18:39:19 +02002078 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002079 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002080 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002081 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002082 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002083
Emeric Brun32da3c42010-09-23 18:39:19 +02002084 if (strcmp(newpeer->id, localpeer) == 0) {
2085 /* Current is local peer, it define a frontend */
2086 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002087 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002088
2089 if (!curpeers->peers_fe) {
2090 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002091 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002092 err_code |= ERR_ALERT | ERR_ABORT;
2093 goto out;
2094 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002095
Willy Tarreau237250c2011-07-29 01:49:03 +02002096 init_new_proxy(curpeers->peers_fe);
2097 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002098 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002099 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2100 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002101 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002102
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002103 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002104
Willy Tarreau902636f2013-03-10 19:44:48 +01002105 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2106 if (errmsg && *errmsg) {
2107 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002108 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002109 }
2110 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002111 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2112 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002113 err_code |= ERR_FATAL;
2114 goto out;
2115 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002116
2117 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002118 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002119 l->maxconn = curpeers->peers_fe->maxconn;
2120 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002121 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002122 l->analysers |= curpeers->peers_fe->fe_req_ana;
2123 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002124 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2125 global.maxsock += l->maxconn;
2126 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002127 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002128 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002129 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2130 file, linenum, args[0], args[1],
2131 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002132 err_code |= ERR_FATAL;
2133 goto out;
2134 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002135 }
2136 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002137 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2138 curpeers->state = PR_STSTOPPED;
2139 }
2140 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2141 curpeers->state = PR_STNEW;
2142 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002143 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002144 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002145 err_code |= ERR_ALERT | ERR_FATAL;
2146 goto out;
2147 }
2148
2149out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002150 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002151 return err_code;
2152}
2153
Baptiste Assmann325137d2015-04-13 23:40:55 +02002154/*
2155 * Parse a <resolvers> section.
2156 * Returns the error code, 0 if OK, or any combination of :
2157 * - ERR_ABORT: must abort ASAP
2158 * - ERR_FATAL: we can continue parsing but not start the service
2159 * - ERR_WARN: a warning has been emitted
2160 * - ERR_ALERT: an alert has been emitted
2161 * Only the two first ones can stop processing, the two others are just
2162 * indicators.
2163 */
2164int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2165{
2166 static struct dns_resolvers *curr_resolvers = NULL;
2167 struct dns_nameserver *newnameserver = NULL;
2168 const char *err;
2169 int err_code = 0;
2170 char *errmsg = NULL;
2171
2172 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2173 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002174 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002175 err_code |= ERR_ALERT | ERR_ABORT;
2176 goto out;
2177 }
2178
2179 err = invalid_char(args[1]);
2180 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002181 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2182 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002183 err_code |= ERR_ALERT | ERR_ABORT;
2184 goto out;
2185 }
2186
2187 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2188 /* Error if two resolvers owns the same name */
2189 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002190 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2191 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002192 err_code |= ERR_ALERT | ERR_ABORT;
2193 }
2194 }
2195
Vincent Bernat02779b62016-04-03 13:48:43 +02002196 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002197 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002198 err_code |= ERR_ALERT | ERR_ABORT;
2199 goto out;
2200 }
2201
2202 /* default values */
2203 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2204 curr_resolvers->conf.file = strdup(file);
2205 curr_resolvers->conf.line = linenum;
2206 curr_resolvers->id = strdup(args[1]);
2207 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002208 /* default maximum response size */
2209 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002210 /* default hold period for nx, other, refuse and timeout is 30s */
2211 curr_resolvers->hold.nx = 30000;
2212 curr_resolvers->hold.other = 30000;
2213 curr_resolvers->hold.refused = 30000;
2214 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002215 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002216 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002217 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002218 curr_resolvers->timeout.resolve = 1000;
2219 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002220 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002221 curr_resolvers->nb_nameservers = 0;
2222 LIST_INIT(&curr_resolvers->nameservers);
2223 LIST_INIT(&curr_resolvers->resolutions.curr);
2224 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002225 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002226 }
2227 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2228 struct sockaddr_storage *sk;
2229 int port1, port2;
2230 struct protocol *proto;
2231
2232 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002233 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2234 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002235 err_code |= ERR_ALERT | ERR_FATAL;
2236 goto out;
2237 }
2238
2239 err = invalid_char(args[1]);
2240 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002241 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2242 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002243 err_code |= ERR_ALERT | ERR_FATAL;
2244 goto out;
2245 }
2246
Christopher Faulet67957bd2017-09-27 11:00:59 +02002247 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002248 /* Error if two resolvers owns the same name */
2249 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002250 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 -06002251 file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002252 err_code |= ERR_ALERT | ERR_FATAL;
2253 }
2254 }
2255
Vincent Bernat02779b62016-04-03 13:48:43 +02002256 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002257 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002258 err_code |= ERR_ALERT | ERR_ABORT;
2259 goto out;
2260 }
2261
2262 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002263 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002264 newnameserver->resolvers = curr_resolvers;
2265 newnameserver->conf.file = strdup(file);
2266 newnameserver->conf.line = linenum;
2267 newnameserver->id = strdup(args[1]);
2268
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002269 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002270 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002271 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002272 err_code |= ERR_ALERT | ERR_FATAL;
2273 goto out;
2274 }
2275
2276 proto = protocol_by_family(sk->ss_family);
2277 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002278 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002279 file, linenum, args[0], args[1]);
2280 err_code |= ERR_ALERT | ERR_FATAL;
2281 goto out;
2282 }
2283
2284 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002285 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2286 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002287 err_code |= ERR_ALERT | ERR_FATAL;
2288 goto out;
2289 }
2290
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002291 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002292 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2293 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002294 err_code |= ERR_ALERT | ERR_FATAL;
2295 goto out;
2296 }
2297
Baptiste Assmann325137d2015-04-13 23:40:55 +02002298 newnameserver->addr = *sk;
2299 }
Ben Draut44e609b2018-05-29 15:40:08 -06002300 else if (strcmp(args[0], "parse-resolv-conf") == 0) {
2301 const char *whitespace = "\r\n\t ";
2302 char *resolv_line = NULL;
2303 int resolv_linenum = 0;
2304 FILE *f = NULL;
2305 char *address = NULL;
2306 struct sockaddr_storage *sk = NULL;
2307 struct protocol *proto;
2308 int duplicate_name = 0;
2309
2310 if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
2311 ha_alert("parsing [%s:%d] : out of memory.\n",
2312 file, linenum);
2313 err_code |= ERR_ALERT | ERR_FATAL;
2314 goto resolv_out;
2315 }
2316
2317 if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
2318 ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n",
2319 file, linenum);
2320 err_code |= ERR_ALERT | ERR_FATAL;
2321 goto resolv_out;
2322 }
2323
2324 sk = calloc(1, sizeof(*sk));
2325 if (sk == NULL) {
2326 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n",
2327 resolv_linenum);
2328 err_code |= ERR_ALERT | ERR_FATAL;
2329 goto resolv_out;
2330 }
2331
2332 while (fgets(resolv_line, LINESIZE, f) != NULL) {
2333 resolv_linenum++;
2334 if (strncmp(resolv_line, "nameserver", 10) != 0)
2335 continue;
2336
2337 address = strtok(resolv_line + 10, whitespace);
2338 if (address == resolv_line + 10)
2339 continue;
2340
2341 if (address == NULL) {
2342 ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
2343 resolv_linenum);
2344 err_code |= ERR_WARN;
2345 continue;
2346 }
2347
2348 duplicate_name = 0;
2349 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
2350 if (strcmp(newnameserver->id, address) == 0) {
2351 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",
2352 resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line);
2353 err_code |= ERR_WARN;
2354 duplicate_name = 1;
2355 }
2356 }
2357
2358 if (duplicate_name)
2359 continue;
2360
2361 memset(sk, 0, sizeof(*sk));
2362 sk = str2ip2(address, sk, 1);
2363 if (!sk) {
2364 ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, namerserver will be excluded.\n",
2365 resolv_linenum, address);
2366 err_code |= ERR_WARN;
2367 continue;
2368 }
2369
2370 set_host_port(sk, 53);
2371
2372 proto = protocol_by_family(sk->ss_family);
2373 if (!proto || !proto->connect) {
2374 ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
2375 resolv_linenum, address);
2376 err_code |= ERR_WARN;
2377 continue;
2378 }
2379
2380 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
2381 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2382 err_code |= ERR_ALERT | ERR_FATAL;
2383 goto resolv_out;
2384 }
2385
2386 newnameserver->conf.file = strdup("/etc/resolv.conf");
2387 if (newnameserver->conf.file == NULL) {
2388 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2389 err_code |= ERR_ALERT | ERR_FATAL;
2390 goto resolv_out;
2391 }
2392
2393 newnameserver->id = strdup(address);
2394 if (newnameserver->id == NULL) {
2395 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2396 err_code |= ERR_ALERT | ERR_FATAL;
2397 goto resolv_out;
2398 }
2399
2400 newnameserver->resolvers = curr_resolvers;
2401 newnameserver->conf.line = resolv_linenum;
2402 newnameserver->addr = *sk;
2403
2404 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
2405 }
2406
2407resolv_out:
2408 free(sk);
2409 free(resolv_line);
2410 if (f != NULL)
2411 fclose(f);
2412 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002413 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2414 const char *res;
2415 unsigned int time;
2416
2417 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002418 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2419 file, linenum, args[0]);
2420 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002421 err_code |= ERR_ALERT | ERR_FATAL;
2422 goto out;
2423 }
2424 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2425 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002426 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2427 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002428 err_code |= ERR_ALERT | ERR_FATAL;
2429 goto out;
2430 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002431 if (strcmp(args[1], "nx") == 0)
2432 curr_resolvers->hold.nx = time;
2433 else if (strcmp(args[1], "other") == 0)
2434 curr_resolvers->hold.other = time;
2435 else if (strcmp(args[1], "refused") == 0)
2436 curr_resolvers->hold.refused = time;
2437 else if (strcmp(args[1], "timeout") == 0)
2438 curr_resolvers->hold.timeout = time;
2439 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002440 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002441 else if (strcmp(args[1], "obsolete") == 0)
2442 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002443 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002444 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2445 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002446 err_code |= ERR_ALERT | ERR_FATAL;
2447 goto out;
2448 }
2449
2450 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002451 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002452 int i = 0;
2453
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002454 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002455 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2456 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002457 err_code |= ERR_ALERT | ERR_FATAL;
2458 goto out;
2459 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002460
2461 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002462 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002463 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2464 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002465 err_code |= ERR_ALERT | ERR_FATAL;
2466 goto out;
2467 }
2468
2469 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002470 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002471 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002472 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2473 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002474 err_code |= ERR_WARN;
2475 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002476 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002477 else if (strcmp(args[0], "resolve_retries") == 0) {
2478 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002479 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2480 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002481 err_code |= ERR_ALERT | ERR_FATAL;
2482 goto out;
2483 }
2484 curr_resolvers->resolve_retries = atoi(args[1]);
2485 }
2486 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002487 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002488 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2489 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002490 err_code |= ERR_ALERT | ERR_FATAL;
2491 goto out;
2492 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002493 else if (strcmp(args[1], "retry") == 0 ||
2494 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002495 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002496 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002497
2498 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002499 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2500 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002501 err_code |= ERR_ALERT | ERR_FATAL;
2502 goto out;
2503 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002504 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002505 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002506 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2507 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002508 err_code |= ERR_ALERT | ERR_FATAL;
2509 goto out;
2510 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002511 if (args[1][2] == 't')
2512 curr_resolvers->timeout.retry = tout;
2513 else
2514 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002515 }
2516 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002517 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2518 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002519 err_code |= ERR_ALERT | ERR_FATAL;
2520 goto out;
2521 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002522 } /* neither "nameserver" nor "resolvers" */
2523 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002524 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002525 err_code |= ERR_ALERT | ERR_FATAL;
2526 goto out;
2527 }
2528
2529 out:
2530 free(errmsg);
2531 return err_code;
2532}
Simon Horman0d16a402015-01-30 11:22:58 +09002533
2534/*
William Lallemand51097192015-04-14 16:35:22 +02002535 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002536 * Returns the error code, 0 if OK, or any combination of :
2537 * - ERR_ABORT: must abort ASAP
2538 * - ERR_FATAL: we can continue parsing but not start the service
2539 * - ERR_WARN: a warning has been emitted
2540 * - ERR_ALERT: an alert has been emitted
2541 * Only the two first ones can stop processing, the two others are just
2542 * indicators.
2543 */
2544int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2545{
2546 static struct mailers *curmailers = NULL;
2547 struct mailer *newmailer = NULL;
2548 const char *err;
2549 int err_code = 0;
2550 char *errmsg = NULL;
2551
2552 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2553 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002554 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002555 err_code |= ERR_ALERT | ERR_ABORT;
2556 goto out;
2557 }
2558
2559 err = invalid_char(args[1]);
2560 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002561 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2562 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002563 err_code |= ERR_ALERT | ERR_ABORT;
2564 goto out;
2565 }
2566
2567 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2568 /*
2569 * If there are two proxies with the same name only following
2570 * combinations are allowed:
2571 */
2572 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002573 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2574 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002575 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002576 }
2577 }
2578
Vincent Bernat02779b62016-04-03 13:48:43 +02002579 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002580 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002581 err_code |= ERR_ALERT | ERR_ABORT;
2582 goto out;
2583 }
2584
2585 curmailers->next = mailers;
2586 mailers = curmailers;
2587 curmailers->conf.file = strdup(file);
2588 curmailers->conf.line = linenum;
2589 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002590 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2591 * But need enough time so that timeouts don't occur
2592 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002593 }
2594 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2595 struct sockaddr_storage *sk;
2596 int port1, port2;
2597 struct protocol *proto;
2598
2599 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002600 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2601 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002602 err_code |= ERR_ALERT | ERR_FATAL;
2603 goto out;
2604 }
2605
2606 err = invalid_char(args[1]);
2607 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002608 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2609 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002610 err_code |= ERR_ALERT | ERR_FATAL;
2611 goto out;
2612 }
2613
Vincent Bernat02779b62016-04-03 13:48:43 +02002614 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002615 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002616 err_code |= ERR_ALERT | ERR_ABORT;
2617 goto out;
2618 }
2619
2620 /* the mailers are linked backwards first */
2621 curmailers->count++;
2622 newmailer->next = curmailers->mailer_list;
2623 curmailers->mailer_list = newmailer;
2624 newmailer->mailers = curmailers;
2625 newmailer->conf.file = strdup(file);
2626 newmailer->conf.line = linenum;
2627
2628 newmailer->id = strdup(args[1]);
2629
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002630 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002631 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002632 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002633 err_code |= ERR_ALERT | ERR_FATAL;
2634 goto out;
2635 }
2636
2637 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002638 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002639 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2640 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002641 err_code |= ERR_ALERT | ERR_FATAL;
2642 goto out;
2643 }
2644
2645 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002646 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2647 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002648 err_code |= ERR_ALERT | ERR_FATAL;
2649 goto out;
2650 }
2651
2652 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002653 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2654 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002655 err_code |= ERR_ALERT | ERR_FATAL;
2656 goto out;
2657 }
2658
2659 newmailer->addr = *sk;
2660 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002661 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002662 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002663 }
2664 else if (strcmp(args[0], "timeout") == 0) {
2665 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002666 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2667 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002668 err_code |= ERR_ALERT | ERR_FATAL;
2669 goto out;
2670 }
2671 else if (strcmp(args[1], "mail") == 0) {
2672 const char *res;
2673 unsigned int timeout_mail;
2674 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002675 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2676 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002677 err_code |= ERR_ALERT | ERR_FATAL;
2678 goto out;
2679 }
2680 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2681 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002682 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2683 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002684 err_code |= ERR_ALERT | ERR_FATAL;
2685 goto out;
2686 }
2687 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002688 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 +01002689 err_code |= ERR_ALERT | ERR_FATAL;
2690 goto out;
2691 }
2692 curmailers->timeout.mail = timeout_mail;
2693 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002694 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002695 file, linenum, args[0], args[1]);
2696 err_code |= ERR_ALERT | ERR_FATAL;
2697 goto out;
2698 }
2699 }
Simon Horman0d16a402015-01-30 11:22:58 +09002700 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002701 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002702 err_code |= ERR_ALERT | ERR_FATAL;
2703 goto out;
2704 }
2705
2706out:
2707 free(errmsg);
2708 return err_code;
2709}
2710
Simon Horman9dc49962015-01-30 11:22:59 +09002711static void free_email_alert(struct proxy *p)
2712{
2713 free(p->email_alert.mailers.name);
2714 p->email_alert.mailers.name = NULL;
2715 free(p->email_alert.from);
2716 p->email_alert.from = NULL;
2717 free(p->email_alert.to);
2718 p->email_alert.to = NULL;
2719 free(p->email_alert.myhostname);
2720 p->email_alert.myhostname = NULL;
2721}
2722
Willy Tarreau3842f002009-06-14 11:39:52 +02002723int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002724{
2725 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002726 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002727 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002728 int rc;
2729 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002730 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002731 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002732 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002733 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002734 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002735
Willy Tarreau977b8e42006-12-29 14:19:17 +01002736 if (!strcmp(args[0], "listen"))
2737 rc = PR_CAP_LISTEN;
2738 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002739 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002740 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002741 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002742 else
2743 rc = PR_CAP_NONE;
2744
2745 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002746 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002747 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2748 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2749 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002750 err_code |= ERR_ALERT | ERR_ABORT;
2751 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002752 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002753
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002754 err = invalid_char(args[1]);
2755 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002756 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2757 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002758 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002759 }
2760
Willy Tarreau8f50b682015-05-26 11:45:02 +02002761 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2762 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002763 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2764 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2765 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002766 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002767 }
2768
Vincent Bernat02779b62016-04-03 13:48:43 +02002769 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002770 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002771 err_code |= ERR_ALERT | ERR_ABORT;
2772 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002773 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002774
Willy Tarreau97cb7802010-01-03 20:23:58 +01002775 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002776 curproxy->next = proxies_list;
2777 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002778 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2779 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002780 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002781 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002782 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002783 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002784
William Lallemand6e62fb62015-04-28 16:55:23 +02002785 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2786 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002787 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002788 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002789 }
2790
2791 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002792 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002793 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002794
Willy Tarreaubaaee002006-06-26 02:48:02 +02002795 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002796 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002797 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002798 curproxy->no_options = defproxy.no_options;
2799 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002800 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002801 curproxy->except_net = defproxy.except_net;
2802 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002803 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002804 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002805
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002806 if (defproxy.fwdfor_hdr_len) {
2807 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2808 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2809 }
2810
Willy Tarreaub86db342009-11-30 11:50:16 +01002811 if (defproxy.orgto_hdr_len) {
2812 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2813 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2814 }
2815
Mark Lamourinec2247f02012-01-04 13:02:01 -05002816 if (defproxy.server_id_hdr_len) {
2817 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2818 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2819 }
2820
Willy Tarreau977b8e42006-12-29 14:19:17 +01002821 if (curproxy->cap & PR_CAP_FE) {
2822 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002823 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002824 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002825
2826 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002827 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2828 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002829
2830 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2831 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002832
Willy Tarreau977b8e42006-12-29 14:19:17 +01002833 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002834 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002835 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002836 curproxy->fullconn = defproxy.fullconn;
2837 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002838 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002839 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002840
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002841 if (defproxy.check_req) {
2842 curproxy->check_req = calloc(1, defproxy.check_len);
2843 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2844 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002845 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002846
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002847 if (defproxy.expect_str) {
2848 curproxy->expect_str = strdup(defproxy.expect_str);
2849 if (defproxy.expect_regex) {
2850 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002851 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2852 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002853 }
2854 }
2855
Willy Tarreau67402132012-05-31 20:40:20 +02002856 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002857 if (defproxy.cookie_name)
2858 curproxy->cookie_name = strdup(defproxy.cookie_name);
2859 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002860
2861 if (defproxy.dyncookie_key)
2862 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002863 if (defproxy.cookie_domain)
2864 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002865
Willy Tarreau31936852010-10-06 16:59:56 +02002866 if (defproxy.cookie_maxidle)
2867 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2868
2869 if (defproxy.cookie_maxlife)
2870 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2871
Emeric Brun647caf12009-06-30 17:57:00 +02002872 if (defproxy.rdp_cookie_name)
2873 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2874 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2875
Willy Tarreau01732802007-11-01 22:48:15 +01002876 if (defproxy.url_param_name)
2877 curproxy->url_param_name = strdup(defproxy.url_param_name);
2878 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002879
Benoitaffb4812009-03-25 13:02:10 +01002880 if (defproxy.hh_name)
2881 curproxy->hh_name = strdup(defproxy.hh_name);
2882 curproxy->hh_len = defproxy.hh_len;
2883 curproxy->hh_match_domain = defproxy.hh_match_domain;
2884
Willy Tarreauef9a3602012-12-08 22:29:20 +01002885 if (defproxy.conn_src.iface_name)
2886 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2887 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002888 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002889#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002890 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002891#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002892 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002893 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002894
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002895 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002896 if (defproxy.capture_name)
2897 curproxy->capture_name = strdup(defproxy.capture_name);
2898 curproxy->capture_namelen = defproxy.capture_namelen;
2899 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002900 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002901
Willy Tarreau977b8e42006-12-29 14:19:17 +01002902 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002903 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002904 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002905 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002906 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002907 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002908 curproxy->mon_net = defproxy.mon_net;
2909 curproxy->mon_mask = defproxy.mon_mask;
2910 if (defproxy.monitor_uri)
2911 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2912 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002913 if (defproxy.defbe.name)
2914 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002915
2916 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002917 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2918 if (curproxy->conf.logformat_string &&
2919 curproxy->conf.logformat_string != default_http_log_format &&
2920 curproxy->conf.logformat_string != default_tcp_log_format &&
2921 curproxy->conf.logformat_string != clf_http_log_format)
2922 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2923
2924 if (defproxy.conf.lfs_file) {
2925 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2926 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2927 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002928
2929 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2930 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2931 if (curproxy->conf.logformat_sd_string &&
2932 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2933 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2934
2935 if (defproxy.conf.lfsd_file) {
2936 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2937 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2938 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002939 }
2940
2941 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002942 curproxy->timeout.connect = defproxy.timeout.connect;
2943 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002944 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002945 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002946 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002947 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002948 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002949 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002950 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002951 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002952 }
2953
Willy Tarreaubaaee002006-06-26 02:48:02 +02002954 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002955 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002956
2957 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002958 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002959 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002960 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002961 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002962 LIST_INIT(&node->list);
2963 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2964 }
2965
Willy Tarreau62a61232013-04-12 18:13:46 +02002966 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2967 if (curproxy->conf.uniqueid_format_string)
2968 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2969
Dragan Dosen43885c72015-10-01 13:18:13 +02002970 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002971
Willy Tarreau62a61232013-04-12 18:13:46 +02002972 if (defproxy.conf.uif_file) {
2973 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2974 curproxy->conf.uif_line = defproxy.conf.uif_line;
2975 }
William Lallemanda73203e2012-03-12 12:48:57 +01002976
2977 /* copy default header unique id */
2978 if (defproxy.header_unique_id)
2979 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2980
William Lallemand82fe75c2012-10-23 10:25:10 +02002981 /* default compression options */
2982 if (defproxy.comp != NULL) {
2983 curproxy->comp = calloc(1, sizeof(struct comp));
2984 curproxy->comp->algos = defproxy.comp->algos;
2985 curproxy->comp->types = defproxy.comp->types;
2986 }
2987
Willy Tarreaubaaee002006-06-26 02:48:02 +02002988 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002989 curproxy->conf.used_listener_id = EB_ROOT;
2990 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002991
Simon Horman98637e52014-06-20 12:30:16 +09002992 if (defproxy.check_path)
2993 curproxy->check_path = strdup(defproxy.check_path);
2994 if (defproxy.check_command)
2995 curproxy->check_command = strdup(defproxy.check_command);
2996
Simon Horman9dc49962015-01-30 11:22:59 +09002997 if (defproxy.email_alert.mailers.name)
2998 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
2999 if (defproxy.email_alert.from)
3000 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
3001 if (defproxy.email_alert.to)
3002 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
3003 if (defproxy.email_alert.myhostname)
3004 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003005 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003006 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003007
Willy Tarreau93893792009-07-23 13:19:11 +02003008 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003009 }
3010 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3011 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003012 /* FIXME-20070101: we should do this too at the end of the
3013 * config parsing to free all default values.
3014 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003015 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3016 err_code |= ERR_ABORT;
3017 goto out;
3018 }
3019
Willy Tarreaua534fea2008-08-03 12:19:50 +02003020 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003021 free(defproxy.check_command);
3022 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003023 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003024 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003025 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003026 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003027 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003028 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003029 free(defproxy.capture_name);
3030 free(defproxy.monitor_uri);
3031 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003032 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003033 free(defproxy.fwdfor_hdr_name);
3034 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003035 free(defproxy.orgto_hdr_name);
3036 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003037 free(defproxy.server_id_hdr_name);
3038 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003039 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003040 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003041 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003042 free(defproxy.expect_regex);
3043 defproxy.expect_regex = NULL;
3044 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003045
Willy Tarreau62a61232013-04-12 18:13:46 +02003046 if (defproxy.conf.logformat_string != default_http_log_format &&
3047 defproxy.conf.logformat_string != default_tcp_log_format &&
3048 defproxy.conf.logformat_string != clf_http_log_format)
3049 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003050
Willy Tarreau62a61232013-04-12 18:13:46 +02003051 free(defproxy.conf.uniqueid_format_string);
3052 free(defproxy.conf.lfs_file);
3053 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003054 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003055 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003056
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003057 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3058 free(defproxy.conf.logformat_sd_string);
3059 free(defproxy.conf.lfsd_file);
3060
Willy Tarreaua534fea2008-08-03 12:19:50 +02003061 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003062 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003063
Willy Tarreaubaaee002006-06-26 02:48:02 +02003064 /* we cannot free uri_auth because it might already be used */
3065 init_default_instance();
3066 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003067 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3068 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003069 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003070 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003071 }
3072 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003073 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003074 err_code |= ERR_ALERT | ERR_FATAL;
3075 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003076 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003077
3078 /* update the current file and line being parsed */
3079 curproxy->conf.args.file = curproxy->conf.file;
3080 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003081
3082 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003083 if (!strcmp(args[0], "server") ||
3084 !strcmp(args[0], "default-server") ||
3085 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003086 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3087 if (err_code & ERR_FATAL)
3088 goto out;
3089 }
3090 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003091 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003092 int cur_arg;
3093
Willy Tarreaubaaee002006-06-26 02:48:02 +02003094 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003095 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003096 err_code |= ERR_ALERT | ERR_FATAL;
3097 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003098 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003099 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003100 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003101
Willy Tarreau24709282013-03-10 21:32:12 +01003102 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003103 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3104 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003105 err_code |= ERR_ALERT | ERR_FATAL;
3106 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003107 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003108
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003109 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003110
3111 /* use default settings for unix sockets */
3112 bind_conf->ux.uid = global.unix_bind.ux.uid;
3113 bind_conf->ux.gid = global.unix_bind.ux.gid;
3114 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003115
3116 /* NOTE: the following line might create several listeners if there
3117 * are comma-separated IPs or port ranges. So all further processing
3118 * will have to be applied to all listeners created after last_listen.
3119 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003120 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3121 if (errmsg && *errmsg) {
3122 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003123 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003124 }
3125 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003126 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3127 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003128 err_code |= ERR_ALERT | ERR_FATAL;
3129 goto out;
3130 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003131
Willy Tarreau4348fad2012-09-20 16:48:07 +02003132 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3133 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003134 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003135 }
3136
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003137 cur_arg = 2;
3138 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003139 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003140 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003141 char *err;
3142
Willy Tarreau26982662012-09-12 23:17:10 +02003143 kw = bind_find_kw(args[cur_arg]);
3144 if (kw) {
3145 char *err = NULL;
3146 int code;
3147
3148 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003149 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3150 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003151 cur_arg += 1 + kw->skip ;
3152 err_code |= ERR_ALERT | ERR_FATAL;
3153 goto out;
3154 }
3155
Willy Tarreau4348fad2012-09-20 16:48:07 +02003156 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003157 err_code |= code;
3158
3159 if (code) {
3160 if (err && *err) {
3161 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003162 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003163 }
3164 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003165 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3166 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003167 if (code & ERR_FATAL) {
3168 free(err);
3169 cur_arg += 1 + kw->skip;
3170 goto out;
3171 }
3172 }
3173 free(err);
3174 cur_arg += 1 + kw->skip;
3175 continue;
3176 }
3177
Willy Tarreau8638f482012-09-18 18:01:17 +02003178 err = NULL;
3179 if (!bind_dumped) {
3180 bind_dump_kws(&err);
3181 indent_msg(&err, 4);
3182 bind_dumped = 1;
3183 }
3184
Christopher Faulet767a84b2017-11-24 16:50:31 +01003185 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3186 file, linenum, args[0], args[1], args[cur_arg],
3187 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003188 free(err);
3189
Willy Tarreau93893792009-07-23 13:19:11 +02003190 err_code |= ERR_ALERT | ERR_FATAL;
3191 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003192 }
Willy Tarreau93893792009-07-23 13:19:11 +02003193 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003194 }
3195 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003196 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003197 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3198 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003199 err_code |= ERR_ALERT | ERR_FATAL;
3200 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003201 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003202 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003203 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003204
Willy Tarreaubaaee002006-06-26 02:48:02 +02003205 /* flush useless bits */
3206 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003207 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003208 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003209 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
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
William Lallemanddf1425a2015-04-28 20:17:49 +02003213 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3214 goto out;
3215
Willy Tarreau1c47f852006-07-09 08:22:27 +02003216 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003217 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3218 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003219 err_code |= ERR_ALERT | ERR_FATAL;
3220 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003221 }
3222
Willy Tarreaua534fea2008-08-03 12:19:50 +02003223 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003224 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003225 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003226 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003227 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3228
Willy Tarreau93893792009-07-23 13:19:11 +02003229 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003230 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003231 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003232 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3233 goto out;
3234
Willy Tarreaubaaee002006-06-26 02:48:02 +02003235 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3236 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3237 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3238 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003239 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003240 err_code |= ERR_ALERT | ERR_FATAL;
3241 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003242 }
3243 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003244 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003245 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003246
3247 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003248 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003249 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003250 err_code |= ERR_ALERT | ERR_FATAL;
3251 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003252 }
3253
William Lallemanddf1425a2015-04-28 20:17:49 +02003254 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3255 goto out;
3256
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003257 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003258 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3259 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003260 err_code |= ERR_ALERT | ERR_FATAL;
3261 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003262 }
3263
3264 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003265 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003266 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003267
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003268 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003269 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3270 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003271 err_code |= ERR_ALERT | ERR_FATAL;
3272 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003273 }
3274
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003275 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3276 if (node) {
3277 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003278 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3279 file, linenum, proxy_type_str(curproxy), curproxy->id,
3280 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003281 err_code |= ERR_ALERT | ERR_FATAL;
3282 goto out;
3283 }
3284 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003285 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003286 else if (!strcmp(args[0], "description")) {
3287 int i, len=0;
3288 char *d;
3289
Cyril Bonté99ed3272010-01-24 23:29:44 +01003290 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003291 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003292 file, linenum, args[0]);
3293 err_code |= ERR_ALERT | ERR_FATAL;
3294 goto out;
3295 }
3296
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003297 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003298 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3299 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003300 return -1;
3301 }
3302
Willy Tarreau348acfe2014-04-14 15:00:39 +02003303 for (i = 1; *args[i]; i++)
3304 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003305
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003306 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003307 curproxy->desc = d;
3308
Willy Tarreau348acfe2014-04-14 15:00:39 +02003309 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3310 for (i = 2; *args[i]; i++)
3311 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003312
3313 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003314 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003315 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3316 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003317 curproxy->state = PR_STSTOPPED;
3318 }
3319 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003320 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3321 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003322 curproxy->state = PR_STNEW;
3323 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003324 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3325 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003326 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003327
3328 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003329 if (strcmp(args[cur_arg], "all") == 0) {
3330 set = 0;
3331 break;
3332 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003333 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003334 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003335 err_code |= ERR_ALERT | ERR_FATAL;
3336 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003337 }
3338 cur_arg++;
3339 }
3340 curproxy->bind_proc = set;
3341 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003342 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003343 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003344 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003345 err_code |= ERR_ALERT | ERR_FATAL;
3346 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003347 }
3348
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003349 err = invalid_char(args[1]);
3350 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003351 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3352 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003353 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003354 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003355 }
3356
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003357 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003358 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3359 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003360 err_code |= ERR_ALERT | ERR_FATAL;
3361 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003362 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003363 }
3364 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3365
3366 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3367 err_code |= ERR_WARN;
3368
3369 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003370 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3371 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003372 err_code |= ERR_ALERT | ERR_FATAL;
3373 goto out;
3374 }
3375 free(curproxy->dyncookie_key);
3376 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003377 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003378 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3379 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003380
Willy Tarreau977b8e42006-12-29 14:19:17 +01003381 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003382 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003383
Willy Tarreaubaaee002006-06-26 02:48:02 +02003384 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003385 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3386 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003387 err_code |= ERR_ALERT | ERR_FATAL;
3388 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003389 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003390
Willy Tarreau67402132012-05-31 20:40:20 +02003391 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003392 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003393 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003394 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003395 curproxy->cookie_name = strdup(args[1]);
3396 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003397
Willy Tarreaubaaee002006-06-26 02:48:02 +02003398 cur_arg = 2;
3399 while (*(args[cur_arg])) {
3400 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003401 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003402 }
3403 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003404 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003405 }
3406 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003407 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003408 }
3409 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003410 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003411 }
3412 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003413 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003414 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003415 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003416 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003417 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003418 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003419 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003420 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003421 else if (!strcmp(args[cur_arg], "httponly")) {
3422 curproxy->ck_opts |= PR_CK_HTTPONLY;
3423 }
3424 else if (!strcmp(args[cur_arg], "secure")) {
3425 curproxy->ck_opts |= PR_CK_SECURE;
3426 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003427 else if (!strcmp(args[cur_arg], "domain")) {
3428 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003429 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3430 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003431 err_code |= ERR_ALERT | ERR_FATAL;
3432 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003433 }
3434
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003435 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003436 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003437 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3438 " dots nor does not start with a dot."
3439 " RFC forbids it, this configuration may not work properly.\n",
3440 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003441 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003442 }
3443
3444 err = invalid_domainchar(args[cur_arg + 1]);
3445 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003446 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3447 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003448 err_code |= ERR_ALERT | ERR_FATAL;
3449 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003450 }
3451
Willy Tarreau68a897b2009-12-03 23:28:34 +01003452 if (!curproxy->cookie_domain) {
3453 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3454 } else {
3455 /* one domain was already specified, add another one by
3456 * building the string which will be returned along with
3457 * the cookie.
3458 */
3459 char *new_ptr;
3460 int new_len = strlen(curproxy->cookie_domain) +
3461 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3462 new_ptr = malloc(new_len);
3463 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3464 free(curproxy->cookie_domain);
3465 curproxy->cookie_domain = new_ptr;
3466 }
Willy Tarreau31936852010-10-06 16:59:56 +02003467 cur_arg++;
3468 }
3469 else if (!strcmp(args[cur_arg], "maxidle")) {
3470 unsigned int maxidle;
3471 const char *res;
3472
3473 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003474 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3475 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003476 err_code |= ERR_ALERT | ERR_FATAL;
3477 goto out;
3478 }
3479
3480 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3481 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003482 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3483 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003484 err_code |= ERR_ALERT | ERR_FATAL;
3485 goto out;
3486 }
3487 curproxy->cookie_maxidle = maxidle;
3488 cur_arg++;
3489 }
3490 else if (!strcmp(args[cur_arg], "maxlife")) {
3491 unsigned int maxlife;
3492 const char *res;
3493
3494 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003495 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3496 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003497 err_code |= ERR_ALERT | ERR_FATAL;
3498 goto out;
3499 }
3500
3501 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3502 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003503 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3504 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003505 err_code |= ERR_ALERT | ERR_FATAL;
3506 goto out;
3507 }
3508 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003509 cur_arg++;
3510 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003511 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003512
3513 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3514 err_code |= ERR_WARN;
3515 curproxy->ck_opts |= PR_CK_DYNAMIC;
3516 }
3517
Willy Tarreaubaaee002006-06-26 02:48:02 +02003518 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003519 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3520 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003521 err_code |= ERR_ALERT | ERR_FATAL;
3522 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003523 }
3524 cur_arg++;
3525 }
Willy Tarreau67402132012-05-31 20:40:20 +02003526 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003527 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3528 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003529 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003530 }
3531
Willy Tarreau67402132012-05-31 20:40:20 +02003532 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003533 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3534 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003535 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003536 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003537
Willy Tarreau67402132012-05-31 20:40:20 +02003538 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003539 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3540 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003541 err_code |= ERR_ALERT | ERR_FATAL;
3542 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003543 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003544 else if (!strcmp(args[0], "email-alert")) {
3545 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003546 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3547 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003548 err_code |= ERR_ALERT | ERR_FATAL;
3549 goto out;
3550 }
3551
3552 if (!strcmp(args[1], "from")) {
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[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003556 err_code |= ERR_ALERT | ERR_FATAL;
3557 goto out;
3558 }
3559 free(curproxy->email_alert.from);
3560 curproxy->email_alert.from = strdup(args[2]);
3561 }
3562 else if (!strcmp(args[1], "mailers")) {
3563 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003564 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3565 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003566 err_code |= ERR_ALERT | ERR_FATAL;
3567 goto out;
3568 }
3569 free(curproxy->email_alert.mailers.name);
3570 curproxy->email_alert.mailers.name = strdup(args[2]);
3571 }
3572 else if (!strcmp(args[1], "myhostname")) {
3573 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003574 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3575 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003576 err_code |= ERR_ALERT | ERR_FATAL;
3577 goto out;
3578 }
3579 free(curproxy->email_alert.myhostname);
3580 curproxy->email_alert.myhostname = strdup(args[2]);
3581 }
Simon Horman64e34162015-02-06 11:11:57 +09003582 else if (!strcmp(args[1], "level")) {
3583 curproxy->email_alert.level = get_log_level(args[2]);
3584 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003585 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3586 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003587 err_code |= ERR_ALERT | ERR_FATAL;
3588 goto out;
3589 }
3590 }
Simon Horman9dc49962015-01-30 11:22:59 +09003591 else if (!strcmp(args[1], "to")) {
3592 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003593 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3594 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003595 err_code |= ERR_ALERT | ERR_FATAL;
3596 goto out;
3597 }
3598 free(curproxy->email_alert.to);
3599 curproxy->email_alert.to = strdup(args[2]);
3600 }
3601 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003602 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3603 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003604 err_code |= ERR_ALERT | ERR_FATAL;
3605 goto out;
3606 }
Simon Horman64e34162015-02-06 11:11:57 +09003607 /* Indicate that the email_alert is at least partially configured */
3608 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003609 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003610 else if (!strcmp(args[0], "external-check")) {
3611 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003612 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3613 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003614 err_code |= ERR_ALERT | ERR_FATAL;
3615 goto out;
3616 }
3617
3618 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003619 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003620 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003621 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003622 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3623 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003624 err_code |= ERR_ALERT | ERR_FATAL;
3625 goto out;
3626 }
3627 free(curproxy->check_command);
3628 curproxy->check_command = strdup(args[2]);
3629 }
3630 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003631 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003632 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003633 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003634 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3635 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003636 err_code |= ERR_ALERT | ERR_FATAL;
3637 goto out;
3638 }
3639 free(curproxy->check_path);
3640 curproxy->check_path = strdup(args[2]);
3641 }
3642 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003643 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3644 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003645 err_code |= ERR_ALERT | ERR_FATAL;
3646 goto out;
3647 }
3648 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003649 else if (!strcmp(args[0], "persist")) { /* persist */
3650 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003651 ha_alert("parsing [%s:%d] : missing persist method.\n",
3652 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003653 err_code |= ERR_ALERT | ERR_FATAL;
3654 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003655 }
3656
3657 if (!strncmp(args[1], "rdp-cookie", 10)) {
3658 curproxy->options2 |= PR_O2_RDPC_PRST;
3659
Emeric Brunb982a3d2010-01-04 15:45:53 +01003660 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003661 const char *beg, *end;
3662
3663 beg = args[1] + 11;
3664 end = strchr(beg, ')');
3665
William Lallemanddf1425a2015-04-28 20:17:49 +02003666 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3667 goto out;
3668
Emeric Brun647caf12009-06-30 17:57:00 +02003669 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003670 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3671 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003672 err_code |= ERR_ALERT | ERR_FATAL;
3673 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003674 }
3675
3676 free(curproxy->rdp_cookie_name);
3677 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3678 curproxy->rdp_cookie_len = end-beg;
3679 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003680 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003681 free(curproxy->rdp_cookie_name);
3682 curproxy->rdp_cookie_name = strdup("msts");
3683 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3684 }
3685 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003686 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3687 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003688 err_code |= ERR_ALERT | ERR_FATAL;
3689 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003690 }
3691 }
3692 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003693 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3694 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003695 err_code |= ERR_ALERT | ERR_FATAL;
3696 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003697 }
3698 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003699 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003700 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 +02003701 err_code |= ERR_ALERT | ERR_FATAL;
3702 goto out;
3703 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003704 else if (!strcmp(args[0], "load-server-state-from-file")) {
3705 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3706 err_code |= ERR_WARN;
3707 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3708 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3709 }
3710 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3711 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3712 }
3713 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3714 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3715 }
3716 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003717 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3718 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003719 err_code |= ERR_ALERT | ERR_FATAL;
3720 goto out;
3721 }
3722 }
3723 else if (!strcmp(args[0], "server-state-file-name")) {
3724 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3725 err_code |= ERR_WARN;
3726 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003727 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3728 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003729 err_code |= ERR_ALERT | ERR_FATAL;
3730 goto out;
3731 }
3732 else if (!strcmp(args[1], "use-backend-name"))
3733 curproxy->server_state_file_name = strdup(curproxy->id);
3734 else
3735 curproxy->server_state_file_name = strdup(args[1]);
3736 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003737 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003738 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003739 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003740
Willy Tarreaubaaee002006-06-26 02:48:02 +02003741 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003742 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003743 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 +01003744 err_code |= ERR_ALERT | ERR_FATAL;
3745 goto out;
3746 }
3747
William Lallemand1a748ae2015-05-19 16:37:23 +02003748 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3749 goto out;
3750
Willy Tarreaubaaee002006-06-26 02:48:02 +02003751 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003752 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3753 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003754 err_code |= ERR_ALERT | ERR_FATAL;
3755 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003756 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003757 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003758 curproxy->capture_name = strdup(args[2]);
3759 curproxy->capture_namelen = strlen(curproxy->capture_name);
3760 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003761 curproxy->to_log |= LW_COOKIE;
3762 }
3763 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3764 struct cap_hdr *hdr;
3765
3766 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003767 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 +02003768 err_code |= ERR_ALERT | ERR_FATAL;
3769 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003770 }
3771
William Lallemand1a748ae2015-05-19 16:37:23 +02003772 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3773 goto out;
3774
Willy Tarreaubaaee002006-06-26 02:48:02 +02003775 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003776 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3777 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003778 err_code |= ERR_ALERT | ERR_FATAL;
3779 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003780 }
3781
Vincent Bernat02779b62016-04-03 13:48:43 +02003782 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003783 hdr->next = curproxy->req_cap;
3784 hdr->name = strdup(args[3]);
3785 hdr->namelen = strlen(args[3]);
3786 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003787 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003788 hdr->index = curproxy->nb_req_cap++;
3789 curproxy->req_cap = hdr;
3790 curproxy->to_log |= LW_REQHDR;
3791 }
3792 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3793 struct cap_hdr *hdr;
3794
3795 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003796 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 +02003797 err_code |= ERR_ALERT | ERR_FATAL;
3798 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003799 }
3800
William Lallemand1a748ae2015-05-19 16:37:23 +02003801 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3802 goto out;
3803
Willy Tarreaubaaee002006-06-26 02:48:02 +02003804 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003805 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3806 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003807 err_code |= ERR_ALERT | ERR_FATAL;
3808 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003809 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003810 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003811 hdr->next = curproxy->rsp_cap;
3812 hdr->name = strdup(args[3]);
3813 hdr->namelen = strlen(args[3]);
3814 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003815 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003816 hdr->index = curproxy->nb_rsp_cap++;
3817 curproxy->rsp_cap = hdr;
3818 curproxy->to_log |= LW_RSPHDR;
3819 }
3820 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003821 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3822 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003823 err_code |= ERR_ALERT | ERR_FATAL;
3824 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003825 }
3826 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003827 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003828 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003829 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003830
William Lallemanddf1425a2015-04-28 20:17:49 +02003831 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3832 goto out;
3833
Willy Tarreaubaaee002006-06-26 02:48:02 +02003834 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003835 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3836 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003837 err_code |= ERR_ALERT | ERR_FATAL;
3838 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003839 }
3840 curproxy->conn_retries = atol(args[1]);
3841 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003842 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003843 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003844
3845 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003846 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003847 err_code |= ERR_ALERT | ERR_FATAL;
3848 goto out;
3849 }
3850
Willy Tarreau20b0de52012-12-24 15:45:22 +01003851 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003852 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003853 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3854 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3855 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3856 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003857 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3858 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003859 err_code |= ERR_WARN;
3860 }
3861
Willy Tarreauff011f22011-01-06 17:51:27 +01003862 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003863
Willy Tarreauff011f22011-01-06 17:51:27 +01003864 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003865 err_code |= ERR_ALERT | ERR_ABORT;
3866 goto out;
3867 }
3868
Willy Tarreau5002f572014-04-23 01:32:02 +02003869 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003870 err_code |= warnif_cond_conflicts(rule->cond,
3871 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3872 file, linenum);
3873
Willy Tarreauff011f22011-01-06 17:51:27 +01003874 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003875 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003876 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003877 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003878
3879 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003880 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003881 err_code |= ERR_ALERT | ERR_FATAL;
3882 goto out;
3883 }
3884
3885 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003886 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003887 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3888 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003889 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3890 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003891 err_code |= ERR_WARN;
3892 }
3893
3894 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3895
3896 if (!rule) {
3897 err_code |= ERR_ALERT | ERR_ABORT;
3898 goto out;
3899 }
3900
3901 err_code |= warnif_cond_conflicts(rule->cond,
3902 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3903 file, linenum);
3904
3905 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3906 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003907 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3908 /* set the header name and length into the proxy structure */
3909 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3910 err_code |= ERR_WARN;
3911
3912 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003913 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3914 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003915 err_code |= ERR_ALERT | ERR_FATAL;
3916 goto out;
3917 }
3918
3919 /* set the desired header name */
3920 free(curproxy->server_id_hdr_name);
3921 curproxy->server_id_hdr_name = strdup(args[1]);
3922 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3923 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003924 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003925 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003926
Willy Tarreaub099aca2008-10-12 17:26:37 +02003927 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003928 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003929 err_code |= ERR_ALERT | ERR_FATAL;
3930 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003931 }
3932
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003933 /* emulate "block" using "http-request block". Since these rules are supposed to
3934 * be processed before all http-request rules, we put them into their own list
3935 * and will insert them at the end.
3936 */
3937 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3938 if (!rule) {
3939 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003940 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003941 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003942 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3943 err_code |= warnif_cond_conflicts(rule->cond,
3944 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3945 file, linenum);
3946 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003947
3948 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003949 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 +02003950
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003951 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003952 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003953 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003954
Cyril Bonté99ed3272010-01-24 23:29:44 +01003955 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003956 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003957 err_code |= ERR_ALERT | ERR_FATAL;
3958 goto out;
3959 }
3960
Willy Tarreaube4653b2015-05-28 15:26:58 +02003961 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003962 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3963 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003964 err_code |= ERR_ALERT | ERR_FATAL;
3965 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003966 }
3967
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003968 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003969 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003970 err_code |= warnif_cond_conflicts(rule->cond,
3971 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3972 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003973 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003974 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003975 struct switching_rule *rule;
3976
Willy Tarreaub099aca2008-10-12 17:26:37 +02003977 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003978 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003979 err_code |= ERR_ALERT | ERR_FATAL;
3980 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003981 }
3982
Willy Tarreau55ea7572007-06-17 19:56:27 +02003983 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003984 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003985
3986 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003987 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003988 err_code |= ERR_ALERT | ERR_FATAL;
3989 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003990 }
3991
Willy Tarreauf51658d2014-04-23 01:21:56 +02003992 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003993 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003994 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3995 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02003996 err_code |= ERR_ALERT | ERR_FATAL;
3997 goto out;
3998 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003999
Willy Tarreauf51658d2014-04-23 01:21:56 +02004000 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004001 }
Willy Tarreau4f862642017-02-28 09:34:39 +01004002 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004003 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
4004 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004005 err_code |= ERR_ALERT | ERR_FATAL;
4006 goto out;
4007 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004008
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004009 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004010 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004011 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004012 goto out;
4013 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004014 rule->cond = cond;
4015 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004016 rule->line = linenum;
4017 rule->file = strdup(file);
4018 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004019 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004020 goto out;
4021 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004022 LIST_INIT(&rule->list);
4023 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4024 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004025 else if (strcmp(args[0], "use-server") == 0) {
4026 struct server_rule *rule;
4027
4028 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004029 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004030 err_code |= ERR_ALERT | ERR_FATAL;
4031 goto out;
4032 }
4033
4034 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4035 err_code |= ERR_WARN;
4036
4037 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004038 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004039 err_code |= ERR_ALERT | ERR_FATAL;
4040 goto out;
4041 }
4042
4043 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004044 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4045 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004046 err_code |= ERR_ALERT | ERR_FATAL;
4047 goto out;
4048 }
4049
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004050 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004051 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4052 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004053 err_code |= ERR_ALERT | ERR_FATAL;
4054 goto out;
4055 }
4056
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004057 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004058
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004059 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004060 rule->cond = cond;
4061 rule->srv.name = strdup(args[1]);
4062 LIST_INIT(&rule->list);
4063 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4064 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4065 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004066 else if ((!strcmp(args[0], "force-persist")) ||
4067 (!strcmp(args[0], "ignore-persist"))) {
4068 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004069
4070 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004071 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004072 err_code |= ERR_ALERT | ERR_FATAL;
4073 goto out;
4074 }
4075
Cyril Bonté4288c5a2018-03-12 22:02:59 +01004076 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01004077 err_code |= ERR_WARN;
4078
Willy Tarreauef6494c2010-01-28 17:12:36 +01004079 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004080 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4081 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004082 err_code |= ERR_ALERT | ERR_FATAL;
4083 goto out;
4084 }
4085
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004086 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004087 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4088 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004089 err_code |= ERR_ALERT | ERR_FATAL;
4090 goto out;
4091 }
4092
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004093 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4094 * where force-persist is applied.
4095 */
4096 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004097
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004098 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004099 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004100 if (!strcmp(args[0], "force-persist")) {
4101 rule->type = PERSIST_TYPE_FORCE;
4102 } else {
4103 rule->type = PERSIST_TYPE_IGNORE;
4104 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004105 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004106 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004107 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004108 else if (!strcmp(args[0], "stick-table")) {
4109 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004110 struct proxy *other;
4111
Willy Tarreauc7867682018-07-27 10:26:22 +02004112 if (curproxy == &defproxy) {
4113 ha_alert("parsing [%s:%d] : 'stick-table' is not supported in 'defaults' section.\n",
4114 file, linenum);
4115 err_code |= ERR_ALERT | ERR_FATAL;
4116 goto out;
4117 }
4118
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004119 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004120 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004121 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4122 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004123 err_code |= ERR_ALERT | ERR_FATAL;
4124 goto out;
4125 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004126
Emeric Brun32da3c42010-09-23 18:39:19 +02004127 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004128 curproxy->table.type = (unsigned int)-1;
4129 while (*args[myidx]) {
4130 const char *err;
4131
4132 if (strcmp(args[myidx], "size") == 0) {
4133 myidx++;
4134 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004135 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4136 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004137 err_code |= ERR_ALERT | ERR_FATAL;
4138 goto out;
4139 }
4140 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004141 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4142 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004143 err_code |= ERR_ALERT | ERR_FATAL;
4144 goto out;
4145 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004146 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004147 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004148 else if (strcmp(args[myidx], "peers") == 0) {
4149 myidx++;
Godbach50523162013-12-11 19:48:57 +08004150 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004151 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4152 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004153 err_code |= ERR_ALERT | ERR_FATAL;
4154 goto out;
Godbach50523162013-12-11 19:48:57 +08004155 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004156 curproxy->table.peers.name = strdup(args[myidx++]);
4157 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004158 else if (strcmp(args[myidx], "expire") == 0) {
4159 myidx++;
4160 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004161 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4162 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004163 err_code |= ERR_ALERT | ERR_FATAL;
4164 goto out;
4165 }
4166 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4167 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004168 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4169 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004170 err_code |= ERR_ALERT | ERR_FATAL;
4171 goto out;
4172 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004173 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004174 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4175 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004176 err_code |= ERR_ALERT | ERR_FATAL;
4177 goto out;
4178 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004179 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004180 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004181 }
4182 else if (strcmp(args[myidx], "nopurge") == 0) {
4183 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004184 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004185 }
4186 else if (strcmp(args[myidx], "type") == 0) {
4187 myidx++;
4188 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004189 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4190 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004191 err_code |= ERR_ALERT | ERR_FATAL;
4192 goto out;
4193 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004194 /* myidx already points to next arg */
4195 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004196 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004197 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004198 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004199
4200 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004201 nw = args[myidx];
4202 while (*nw) {
4203 /* the "store" keyword supports a comma-separated list */
4204 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004205 sa = NULL; /* store arg */
4206 while (*nw && *nw != ',') {
4207 if (*nw == '(') {
4208 *nw = 0;
4209 sa = ++nw;
4210 while (*nw != ')') {
4211 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004212 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4213 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004214 err_code |= ERR_ALERT | ERR_FATAL;
4215 goto out;
4216 }
4217 nw++;
4218 }
4219 *nw = '\0';
4220 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004221 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004222 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004223 if (*nw)
4224 *nw++ = '\0';
4225 type = stktable_get_data_type(cw);
4226 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004227 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4228 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004229 err_code |= ERR_ALERT | ERR_FATAL;
4230 goto out;
4231 }
Willy Tarreauac782882010-06-20 10:41:54 +02004232
4233 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4234 switch (err) {
4235 case PE_NONE: break;
4236 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004237 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4238 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004239 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004240 break;
4241
4242 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004243 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4244 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004245 err_code |= ERR_ALERT | ERR_FATAL;
4246 goto out;
4247
4248 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004249 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4250 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004251 err_code |= ERR_ALERT | ERR_FATAL;
4252 goto out;
4253
4254 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004255 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4256 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004257 err_code |= ERR_ALERT | ERR_FATAL;
4258 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004259 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004260 }
4261 myidx++;
4262 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004263 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004264 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4265 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004266 err_code |= ERR_ALERT | ERR_FATAL;
4267 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004268 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004269 }
4270
4271 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004272 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4273 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004274 err_code |= ERR_ALERT | ERR_FATAL;
4275 goto out;
4276 }
4277
4278 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004279 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4280 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004281 err_code |= ERR_ALERT | ERR_FATAL;
4282 goto out;
4283 }
4284 }
4285 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004286 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004287 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004288 int myidx = 0;
4289 const char *name = NULL;
4290 int flags;
4291
4292 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004293 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004294 err_code |= ERR_ALERT | ERR_FATAL;
4295 goto out;
4296 }
4297
4298 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4299 err_code |= ERR_WARN;
4300 goto out;
4301 }
4302
4303 myidx++;
4304 if ((strcmp(args[myidx], "store") == 0) ||
4305 (strcmp(args[myidx], "store-request") == 0)) {
4306 myidx++;
4307 flags = STK_IS_STORE;
4308 }
4309 else if (strcmp(args[myidx], "store-response") == 0) {
4310 myidx++;
4311 flags = STK_IS_STORE | STK_ON_RSP;
4312 }
4313 else if (strcmp(args[myidx], "match") == 0) {
4314 myidx++;
4315 flags = STK_IS_MATCH;
4316 }
4317 else if (strcmp(args[myidx], "on") == 0) {
4318 myidx++;
4319 flags = STK_IS_MATCH | STK_IS_STORE;
4320 }
4321 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004322 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004323 err_code |= ERR_ALERT | ERR_FATAL;
4324 goto out;
4325 }
4326
4327 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004328 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004329 err_code |= ERR_ALERT | ERR_FATAL;
4330 goto out;
4331 }
4332
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004333 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004334 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004335 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004336 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004337 err_code |= ERR_ALERT | ERR_FATAL;
4338 goto out;
4339 }
4340
4341 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004342 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004343 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4344 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004345 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004346 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004347 goto out;
4348 }
4349 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004350 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004351 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4352 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004353 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004354 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004355 goto out;
4356 }
4357 }
4358
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004359 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004360 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004361
Emeric Brunb982a3d2010-01-04 15:45:53 +01004362 if (strcmp(args[myidx], "table") == 0) {
4363 myidx++;
4364 name = args[myidx++];
4365 }
4366
Willy Tarreauef6494c2010-01-28 17:12:36 +01004367 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004368 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004369 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4370 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004371 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004372 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004373 goto out;
4374 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004375 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004376 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004377 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4378 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004379 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004380 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004381 goto out;
4382 }
Emeric Brun97679e72010-09-23 17:56:44 +02004383 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004384 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004385 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004386 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004387
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004388 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004389 rule->cond = cond;
4390 rule->expr = expr;
4391 rule->flags = flags;
4392 rule->table.name = name ? strdup(name) : NULL;
4393 LIST_INIT(&rule->list);
4394 if (flags & STK_ON_RSP)
4395 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4396 else
4397 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4398 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004399 else if (!strcmp(args[0], "stats")) {
4400 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4401 curproxy->uri_auth = NULL; /* we must detach from the default config */
4402
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004403 if (!*args[1]) {
4404 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004405 } else if (!strcmp(args[1], "admin")) {
4406 struct stats_admin_rule *rule;
4407
4408 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004409 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 +02004410 err_code |= ERR_ALERT | ERR_FATAL;
4411 goto out;
4412 }
4413
4414 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004415 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004416 err_code |= ERR_ALERT | ERR_ABORT;
4417 goto out;
4418 }
4419
4420 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004421 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4422 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004423 err_code |= ERR_ALERT | ERR_FATAL;
4424 goto out;
4425 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004426 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004427 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4428 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004429 err_code |= ERR_ALERT | ERR_FATAL;
4430 goto out;
4431 }
4432
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004433 err_code |= warnif_cond_conflicts(cond,
4434 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4435 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004436
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004437 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004438 rule->cond = cond;
4439 LIST_INIT(&rule->list);
4440 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004441 } else if (!strcmp(args[1], "uri")) {
4442 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004443 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004444 err_code |= ERR_ALERT | ERR_FATAL;
4445 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004446 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004447 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004448 err_code |= ERR_ALERT | ERR_ABORT;
4449 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004450 }
4451 } else if (!strcmp(args[1], "realm")) {
4452 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004453 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004454 err_code |= ERR_ALERT | ERR_FATAL;
4455 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004456 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004457 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004458 err_code |= ERR_ALERT | ERR_ABORT;
4459 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004460 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004461 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004462 unsigned interval;
4463
4464 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4465 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004466 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4467 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004468 err_code |= ERR_ALERT | ERR_FATAL;
4469 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004470 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004471 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004472 err_code |= ERR_ALERT | ERR_ABORT;
4473 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004474 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004475 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004476 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004477
4478 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004479 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004480 err_code |= ERR_ALERT | ERR_FATAL;
4481 goto out;
4482 }
4483
4484 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004485 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004486 err_code |= ERR_ALERT | ERR_ABORT;
4487 goto out;
4488 }
4489
Willy Tarreauff011f22011-01-06 17:51:27 +01004490 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004491 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004492 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4493 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004494 err_code |= ERR_WARN;
4495 }
4496
Willy Tarreauff011f22011-01-06 17:51:27 +01004497 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004498
Willy Tarreauff011f22011-01-06 17:51:27 +01004499 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004500 err_code |= ERR_ALERT | ERR_ABORT;
4501 goto out;
4502 }
4503
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004504 err_code |= warnif_cond_conflicts(rule->cond,
4505 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4506 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004507 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004508
Willy Tarreaubaaee002006-06-26 02:48:02 +02004509 } else if (!strcmp(args[1], "auth")) {
4510 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004511 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004512 err_code |= ERR_ALERT | ERR_FATAL;
4513 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004514 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004515 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004516 err_code |= ERR_ALERT | ERR_ABORT;
4517 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004518 }
4519 } else if (!strcmp(args[1], "scope")) {
4520 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004521 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004522 err_code |= ERR_ALERT | ERR_FATAL;
4523 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004524 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004525 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004526 err_code |= ERR_ALERT | ERR_ABORT;
4527 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004528 }
4529 } else if (!strcmp(args[1], "enable")) {
4530 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004531 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004532 err_code |= ERR_ALERT | ERR_ABORT;
4533 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004534 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004535 } else if (!strcmp(args[1], "hide-version")) {
4536 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004537 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004538 err_code |= ERR_ALERT | ERR_ABORT;
4539 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004540 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004541 } else if (!strcmp(args[1], "show-legends")) {
4542 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004543 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004544 err_code |= ERR_ALERT | ERR_ABORT;
4545 goto out;
4546 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004547 } else if (!strcmp(args[1], "show-node")) {
4548
4549 if (*args[2]) {
4550 int i;
4551 char c;
4552
4553 for (i=0; args[2][i]; i++) {
4554 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004555 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4556 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004557 break;
4558 }
4559
4560 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004561 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4562 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4563 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004564 err_code |= ERR_ALERT | ERR_FATAL;
4565 goto out;
4566 }
4567 }
4568
4569 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004570 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004571 err_code |= ERR_ALERT | ERR_ABORT;
4572 goto out;
4573 }
4574 } else if (!strcmp(args[1], "show-desc")) {
4575 char *desc = NULL;
4576
4577 if (*args[2]) {
4578 int i, len=0;
4579 char *d;
4580
Willy Tarreau348acfe2014-04-14 15:00:39 +02004581 for (i = 2; *args[i]; i++)
4582 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004583
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004584 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004585
Willy Tarreau348acfe2014-04-14 15:00:39 +02004586 d += snprintf(d, desc + len - d, "%s", args[2]);
4587 for (i = 3; *args[i]; i++)
4588 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004589 }
4590
4591 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004592 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4593 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004594 else {
4595 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4596 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004597 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004598 err_code |= ERR_ALERT | ERR_ABORT;
4599 goto out;
4600 }
4601 free(desc);
4602 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004603 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004604stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004605 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4606 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004607 err_code |= ERR_ALERT | ERR_FATAL;
4608 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004609 }
4610 }
4611 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004612 int optnum;
4613
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004614 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004615 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4616 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004617 err_code |= ERR_ALERT | ERR_FATAL;
4618 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004619 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004620
4621 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4622 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004623 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004624 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4625 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004626 err_code |= ERR_ALERT | ERR_FATAL;
4627 goto out;
4628 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004629 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4630 goto out;
4631
Willy Tarreau93893792009-07-23 13:19:11 +02004632 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4633 err_code |= ERR_WARN;
4634 goto out;
4635 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004636
Willy Tarreau3842f002009-06-14 11:39:52 +02004637 curproxy->no_options &= ~cfg_opts[optnum].val;
4638 curproxy->options &= ~cfg_opts[optnum].val;
4639
4640 switch (kwm) {
4641 case KWM_STD:
4642 curproxy->options |= cfg_opts[optnum].val;
4643 break;
4644 case KWM_NO:
4645 curproxy->no_options |= cfg_opts[optnum].val;
4646 break;
4647 case KWM_DEF: /* already cleared */
4648 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004649 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004650
Willy Tarreau93893792009-07-23 13:19:11 +02004651 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004652 }
4653 }
4654
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004655 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4656 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004657 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004658 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4659 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004660 err_code |= ERR_ALERT | ERR_FATAL;
4661 goto out;
4662 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004663 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4664 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004665 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4666 err_code |= ERR_WARN;
4667 goto out;
4668 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004669
Willy Tarreau3842f002009-06-14 11:39:52 +02004670 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4671 curproxy->options2 &= ~cfg_opts2[optnum].val;
4672
4673 switch (kwm) {
4674 case KWM_STD:
4675 curproxy->options2 |= cfg_opts2[optnum].val;
4676 break;
4677 case KWM_NO:
4678 curproxy->no_options2 |= cfg_opts2[optnum].val;
4679 break;
4680 case KWM_DEF: /* already cleared */
4681 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004682 }
Willy Tarreau93893792009-07-23 13:19:11 +02004683 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004684 }
4685 }
4686
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004687 /* HTTP options override each other. They can be cancelled using
4688 * "no option xxx" which only switches to default mode if the mode
4689 * was this one (useful for cancelling options set in defaults
4690 * sections).
4691 */
4692 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004693 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4694 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004695 if (kwm == KWM_STD) {
4696 curproxy->options &= ~PR_O_HTTP_MODE;
4697 curproxy->options |= PR_O_HTTP_PCL;
4698 goto out;
4699 }
4700 else if (kwm == KWM_NO) {
4701 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4702 curproxy->options &= ~PR_O_HTTP_MODE;
4703 goto out;
4704 }
4705 }
4706 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004707 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4708 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004709 if (kwm == KWM_STD) {
4710 curproxy->options &= ~PR_O_HTTP_MODE;
4711 curproxy->options |= PR_O_HTTP_FCL;
4712 goto out;
4713 }
4714 else if (kwm == KWM_NO) {
4715 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4716 curproxy->options &= ~PR_O_HTTP_MODE;
4717 goto out;
4718 }
4719 }
4720 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004721 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4722 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004723 if (kwm == KWM_STD) {
4724 curproxy->options &= ~PR_O_HTTP_MODE;
4725 curproxy->options |= PR_O_HTTP_SCL;
4726 goto out;
4727 }
4728 else if (kwm == KWM_NO) {
4729 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4730 curproxy->options &= ~PR_O_HTTP_MODE;
4731 goto out;
4732 }
4733 }
4734 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004735 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4736 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004737 if (kwm == KWM_STD) {
4738 curproxy->options &= ~PR_O_HTTP_MODE;
4739 curproxy->options |= PR_O_HTTP_KAL;
4740 goto out;
4741 }
4742 else if (kwm == KWM_NO) {
4743 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4744 curproxy->options &= ~PR_O_HTTP_MODE;
4745 goto out;
4746 }
4747 }
4748 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004749 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4750 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004751 if (kwm == KWM_STD) {
4752 curproxy->options &= ~PR_O_HTTP_MODE;
4753 curproxy->options |= PR_O_HTTP_TUN;
4754 goto out;
4755 }
4756 else if (kwm == KWM_NO) {
4757 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4758 curproxy->options &= ~PR_O_HTTP_MODE;
4759 goto out;
4760 }
4761 }
4762
Joseph Lynch726ab712015-05-11 23:25:34 -07004763 /* Redispatch can take an integer argument that control when the
4764 * resispatch occurs. All values are relative to the retries option.
4765 * This can be cancelled using "no option xxx".
4766 */
4767 if (strcmp(args[1], "redispatch") == 0) {
4768 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4769 err_code |= ERR_WARN;
4770 goto out;
4771 }
4772
4773 curproxy->no_options &= ~PR_O_REDISP;
4774 curproxy->options &= ~PR_O_REDISP;
4775
4776 switch (kwm) {
4777 case KWM_STD:
4778 curproxy->options |= PR_O_REDISP;
4779 curproxy->redispatch_after = -1;
4780 if(*args[2]) {
4781 curproxy->redispatch_after = atol(args[2]);
4782 }
4783 break;
4784 case KWM_NO:
4785 curproxy->no_options |= PR_O_REDISP;
4786 curproxy->redispatch_after = 0;
4787 break;
4788 case KWM_DEF: /* already cleared */
4789 break;
4790 }
4791 goto out;
4792 }
4793
Willy Tarreau3842f002009-06-14 11:39:52 +02004794 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004795 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4796 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004797 err_code |= ERR_ALERT | ERR_FATAL;
4798 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004799 }
4800
Emeric Brun3a058f32009-06-30 18:26:00 +02004801 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004802 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004803 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004804 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004805 if (*(args[2]) != '\0') {
4806 if (!strcmp(args[2], "clf")) {
4807 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004808 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004809 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004810 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004811 err_code |= ERR_ALERT | ERR_FATAL;
4812 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004813 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004814 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4815 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004816 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004817 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4818 char *oldlogformat = "log-format";
4819 char *clflogformat = "";
4820
4821 if (curproxy->conf.logformat_string == default_http_log_format)
4822 oldlogformat = "option httplog";
4823 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4824 oldlogformat = "option tcplog";
4825 else if (curproxy->conf.logformat_string == clf_http_log_format)
4826 oldlogformat = "option httplog clf";
4827 if (logformat == clf_http_log_format)
4828 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004829 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4830 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004831 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004832 if (curproxy->conf.logformat_string != default_http_log_format &&
4833 curproxy->conf.logformat_string != default_tcp_log_format &&
4834 curproxy->conf.logformat_string != clf_http_log_format)
4835 free(curproxy->conf.logformat_string);
4836 curproxy->conf.logformat_string = logformat;
4837
4838 free(curproxy->conf.lfs_file);
4839 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4840 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004841
4842 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4843 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4844 file, linenum, curproxy->id);
4845 err_code |= ERR_WARN;
4846 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004847 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004848 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004849 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4850 char *oldlogformat = "log-format";
4851
4852 if (curproxy->conf.logformat_string == default_http_log_format)
4853 oldlogformat = "option httplog";
4854 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4855 oldlogformat = "option tcplog";
4856 else if (curproxy->conf.logformat_string == clf_http_log_format)
4857 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004858 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4859 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004860 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004861 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004862 if (curproxy->conf.logformat_string != default_http_log_format &&
4863 curproxy->conf.logformat_string != default_tcp_log_format &&
4864 curproxy->conf.logformat_string != clf_http_log_format)
4865 free(curproxy->conf.logformat_string);
4866 curproxy->conf.logformat_string = default_tcp_log_format;
4867
4868 free(curproxy->conf.lfs_file);
4869 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4870 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004871
4872 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4873 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004874
4875 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4876 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4877 file, linenum, curproxy->id);
4878 err_code |= ERR_WARN;
4879 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004880 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004881 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004882 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004883 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004884 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004885
William Lallemanddf1425a2015-04-28 20:17:49 +02004886 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4887 goto out;
4888
Willy Tarreau13943ab2006-12-31 00:24:10 +01004889 if (curproxy->cap & PR_CAP_FE)
4890 curproxy->options |= PR_O_TCP_CLI_KA;
4891 if (curproxy->cap & PR_CAP_BE)
4892 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004893 }
4894 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004895 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004896 err_code |= ERR_WARN;
4897
Willy Tarreaubaaee002006-06-26 02:48:02 +02004898 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004899 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004900 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004901 curproxy->options2 &= ~PR_O2_CHK_ANY;
4902 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004903 if (!*args[2]) { /* no argument */
4904 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4905 curproxy->check_len = strlen(DEF_CHECK_REQ);
4906 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004907 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004908 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004909 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004910 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004911 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004912 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004913 if (*args[4])
4914 reqlen += strlen(args[4]);
4915 else
4916 reqlen += strlen("HTTP/1.0");
4917
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004918 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004919 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004920 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004921 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004922 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4923 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004924 }
4925 else if (!strcmp(args[1], "ssl-hello-chk")) {
4926 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004927 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004928 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004929
Willy Tarreaua534fea2008-08-03 12:19:50 +02004930 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004931 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004932 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004933 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004934
4935 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4936 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004937 }
Willy Tarreau23677902007-05-08 23:50:35 +02004938 else if (!strcmp(args[1], "smtpchk")) {
4939 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004940 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004941 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004942 curproxy->options2 &= ~PR_O2_CHK_ANY;
4943 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004944
4945 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4946 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4947 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4948 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4949 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4950 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004951 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004952 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4953 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4954 } else {
4955 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4956 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4957 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4958 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4959 }
4960 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004961 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4962 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004963 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004964 else if (!strcmp(args[1], "pgsql-check")) {
4965 /* use PostgreSQL request to check servers' health */
4966 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4967 err_code |= ERR_WARN;
4968
4969 free(curproxy->check_req);
4970 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004971 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004972 curproxy->options2 |= PR_O2_PGSQL_CHK;
4973
4974 if (*(args[2])) {
4975 int cur_arg = 2;
4976
4977 while (*(args[cur_arg])) {
4978 if (strcmp(args[cur_arg], "user") == 0) {
4979 char * packet;
4980 uint32_t packet_len;
4981 uint32_t pv;
4982
4983 /* suboption header - needs additional argument for it */
4984 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004985 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4986 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004987 err_code |= ERR_ALERT | ERR_FATAL;
4988 goto out;
4989 }
4990
4991 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4992 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4993 pv = htonl(0x30000); /* protocol version 3.0 */
4994
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004995 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004996
4997 memcpy(packet + 4, &pv, 4);
4998
4999 /* copy "user" */
5000 memcpy(packet + 8, "user", 4);
5001
5002 /* copy username */
5003 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
5004
5005 free(curproxy->check_req);
5006 curproxy->check_req = packet;
5007 curproxy->check_len = packet_len;
5008
5009 packet_len = htonl(packet_len);
5010 memcpy(packet, &packet_len, 4);
5011 cur_arg += 2;
5012 } else {
5013 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005014 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5015 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005016 err_code |= ERR_ALERT | ERR_FATAL;
5017 goto out;
5018 }
5019 } /* end while loop */
5020 }
William Lallemanddf1425a2015-04-28 20:17:49 +02005021 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
5022 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005023 }
5024
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005025 else if (!strcmp(args[1], "redis-check")) {
5026 /* use REDIS PING request to check servers' health */
5027 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5028 err_code |= ERR_WARN;
5029
5030 free(curproxy->check_req);
5031 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005032 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005033 curproxy->options2 |= PR_O2_REDIS_CHK;
5034
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005035 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005036 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5037 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005038
5039 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5040 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005041 }
5042
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005043 else if (!strcmp(args[1], "mysql-check")) {
5044 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005045 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5046 err_code |= ERR_WARN;
5047
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005048 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005049 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005050 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005051 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005052
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005053 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005054 * const char mysql40_client_auth_pkt[] = {
5055 * "\x0e\x00\x00" // packet length
5056 * "\x01" // packet number
5057 * "\x00\x00" // client capabilities
5058 * "\x00\x00\x01" // max packet
5059 * "haproxy\x00" // username (null terminated string)
5060 * "\x00" // filler (always 0x00)
5061 * "\x01\x00\x00" // packet length
5062 * "\x00" // packet number
5063 * "\x01" // COM_QUIT command
5064 * };
5065 */
5066
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005067 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5068 * const char mysql41_client_auth_pkt[] = {
5069 * "\x0e\x00\x00\" // packet length
5070 * "\x01" // packet number
5071 * "\x00\x00\x00\x00" // client capabilities
5072 * "\x00\x00\x00\x01" // max packet
5073 * "\x21" // character set (UTF-8)
5074 * char[23] // All zeroes
5075 * "haproxy\x00" // username (null terminated string)
5076 * "\x00" // filler (always 0x00)
5077 * "\x01\x00\x00" // packet length
5078 * "\x00" // packet number
5079 * "\x01" // COM_QUIT command
5080 * };
5081 */
5082
5083
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005084 if (*(args[2])) {
5085 int cur_arg = 2;
5086
5087 while (*(args[cur_arg])) {
5088 if (strcmp(args[cur_arg], "user") == 0) {
5089 char *mysqluser;
5090 int packetlen, reqlen, userlen;
5091
5092 /* suboption header - needs additional argument for it */
5093 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005094 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5095 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005096 err_code |= ERR_ALERT | ERR_FATAL;
5097 goto out;
5098 }
5099 mysqluser = args[cur_arg + 1];
5100 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005101
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005102 if (*(args[cur_arg+2])) {
5103 if (!strcmp(args[cur_arg+2], "post-41")) {
5104 packetlen = userlen + 7 + 27;
5105 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005106
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005107 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005108 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005109 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005110
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005111 snprintf(curproxy->check_req, 4, "%c%c%c",
5112 ((unsigned char) packetlen & 0xff),
5113 ((unsigned char) (packetlen >> 8) & 0xff),
5114 ((unsigned char) (packetlen >> 16) & 0xff));
5115
5116 curproxy->check_req[3] = 1;
5117 curproxy->check_req[5] = 130;
5118 curproxy->check_req[11] = 1;
5119 curproxy->check_req[12] = 33;
5120 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5121 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5122 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5123 cur_arg += 3;
5124 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005125 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 +02005126 err_code |= ERR_ALERT | ERR_FATAL;
5127 goto out;
5128 }
5129 } else {
5130 packetlen = userlen + 7;
5131 reqlen = packetlen + 9;
5132
5133 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005134 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005135 curproxy->check_len = reqlen;
5136
5137 snprintf(curproxy->check_req, 4, "%c%c%c",
5138 ((unsigned char) packetlen & 0xff),
5139 ((unsigned char) (packetlen >> 8) & 0xff),
5140 ((unsigned char) (packetlen >> 16) & 0xff));
5141
5142 curproxy->check_req[3] = 1;
5143 curproxy->check_req[5] = 128;
5144 curproxy->check_req[8] = 1;
5145 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5146 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5147 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5148 cur_arg += 2;
5149 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005150 } else {
5151 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005152 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5153 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005154 err_code |= ERR_ALERT | ERR_FATAL;
5155 goto out;
5156 }
5157 } /* end while loop */
5158 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005159 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005160 else if (!strcmp(args[1], "ldap-check")) {
5161 /* use LDAP request to check servers' health */
5162 free(curproxy->check_req);
5163 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005164 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005165 curproxy->options2 |= PR_O2_LDAP_CHK;
5166
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005167 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005168 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5169 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005170 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5171 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005172 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005173 else if (!strcmp(args[1], "spop-check")) {
5174 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005175 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5176 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005177 err_code |= ERR_ALERT | ERR_FATAL;
5178 goto out;
5179 }
5180 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005181 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5182 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005183 err_code |= ERR_ALERT | ERR_FATAL;
5184 goto out;
5185 }
5186
5187 /* use SPOE request to check servers' health */
5188 free(curproxy->check_req);
5189 curproxy->check_req = NULL;
5190 curproxy->options2 &= ~PR_O2_CHK_ANY;
5191 curproxy->options2 |= PR_O2_SPOP_CHK;
5192
Christopher Faulet8ef75252017-02-20 22:56:03 +01005193 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005194 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005195 err_code |= ERR_ALERT | ERR_FATAL;
5196 goto out;
5197 }
5198 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5199 goto out;
5200 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005201 else if (!strcmp(args[1], "tcp-check")) {
5202 /* use raw TCPCHK send/expect to check servers' health */
5203 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5204 err_code |= ERR_WARN;
5205
5206 free(curproxy->check_req);
5207 curproxy->check_req = NULL;
5208 curproxy->options2 &= ~PR_O2_CHK_ANY;
5209 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005210 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5211 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005212 }
Simon Horman98637e52014-06-20 12:30:16 +09005213 else if (!strcmp(args[1], "external-check")) {
5214 /* excute an external command to check servers' health */
5215 free(curproxy->check_req);
5216 curproxy->check_req = NULL;
5217 curproxy->options2 &= ~PR_O2_CHK_ANY;
5218 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005219 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5220 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005221 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005222 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005223 int cur_arg;
5224
5225 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5226 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005227 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005228
Willy Tarreau87cf5142011-08-19 22:57:24 +02005229 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005230
5231 free(curproxy->fwdfor_hdr_name);
5232 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5233 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5234
5235 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5236 cur_arg = 2;
5237 while (*(args[cur_arg])) {
5238 if (!strcmp(args[cur_arg], "except")) {
5239 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005240 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005241 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5242 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005243 err_code |= ERR_ALERT | ERR_FATAL;
5244 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005245 }
5246 /* flush useless bits */
5247 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005248 cur_arg += 2;
5249 } else if (!strcmp(args[cur_arg], "header")) {
5250 /* suboption header - needs additional argument for it */
5251 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005252 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5253 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005254 err_code |= ERR_ALERT | ERR_FATAL;
5255 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005256 }
5257 free(curproxy->fwdfor_hdr_name);
5258 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5259 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5260 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005261 } else if (!strcmp(args[cur_arg], "if-none")) {
5262 curproxy->options &= ~PR_O_FF_ALWAYS;
5263 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005264 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005265 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005266 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5267 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005268 err_code |= ERR_ALERT | ERR_FATAL;
5269 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005270 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005271 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005272 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005273 else if (!strcmp(args[1], "originalto")) {
5274 int cur_arg;
5275
5276 /* insert x-original-to field, but not for the IP address listed as an except.
5277 * set default options (ie: bitfield, header name, etc)
5278 */
5279
5280 curproxy->options |= PR_O_ORGTO;
5281
5282 free(curproxy->orgto_hdr_name);
5283 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5284 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5285
Willy Tarreau87cf5142011-08-19 22:57:24 +02005286 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005287 cur_arg = 2;
5288 while (*(args[cur_arg])) {
5289 if (!strcmp(args[cur_arg], "except")) {
5290 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005291 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 +01005292 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5293 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005294 err_code |= ERR_ALERT | ERR_FATAL;
5295 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005296 }
5297 /* flush useless bits */
5298 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5299 cur_arg += 2;
5300 } else if (!strcmp(args[cur_arg], "header")) {
5301 /* suboption header - needs additional argument for it */
5302 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005303 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5304 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005305 err_code |= ERR_ALERT | ERR_FATAL;
5306 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005307 }
5308 free(curproxy->orgto_hdr_name);
5309 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5310 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5311 cur_arg += 2;
5312 } else {
5313 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005314 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5315 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005316 err_code |= ERR_ALERT | ERR_FATAL;
5317 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005318 }
5319 } /* end while loop */
5320 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005321 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005322 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005323 err_code |= ERR_ALERT | ERR_FATAL;
5324 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005325 }
Willy Tarreau93893792009-07-23 13:19:11 +02005326 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005327 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005328 else if (!strcmp(args[0], "default_backend")) {
5329 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005330 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005331
5332 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005333 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005334 err_code |= ERR_ALERT | ERR_FATAL;
5335 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005336 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005337 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005338 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005339
5340 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5341 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005342 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005343 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005344 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005345 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005346
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005347 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005348 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5349 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005350 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005351 /* enable reconnections to dispatch */
5352 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005353
5354 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5355 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005356 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005357 else if (!strcmp(args[0], "http-reuse")) {
5358 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5359 err_code |= ERR_WARN;
5360
5361 if (strcmp(args[1], "never") == 0) {
5362 /* enable a graceful server shutdown on an HTTP 404 response */
5363 curproxy->options &= ~PR_O_REUSE_MASK;
5364 curproxy->options |= PR_O_REUSE_NEVR;
5365 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5366 goto out;
5367 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005368 else if (strcmp(args[1], "safe") == 0) {
5369 /* enable a graceful server shutdown on an HTTP 404 response */
5370 curproxy->options &= ~PR_O_REUSE_MASK;
5371 curproxy->options |= PR_O_REUSE_SAFE;
5372 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5373 goto out;
5374 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005375 else if (strcmp(args[1], "aggressive") == 0) {
5376 curproxy->options &= ~PR_O_REUSE_MASK;
5377 curproxy->options |= PR_O_REUSE_AGGR;
5378 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5379 goto out;
5380 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005381 else if (strcmp(args[1], "always") == 0) {
5382 /* enable a graceful server shutdown on an HTTP 404 response */
5383 curproxy->options &= ~PR_O_REUSE_MASK;
5384 curproxy->options |= PR_O_REUSE_ALWS;
5385 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5386 goto out;
5387 }
5388 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005389 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005390 err_code |= ERR_ALERT | ERR_FATAL;
5391 goto out;
5392 }
5393 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005394 else if (!strcmp(args[0], "http-check")) {
5395 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005396 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005397
5398 if (strcmp(args[1], "disable-on-404") == 0) {
5399 /* enable a graceful server shutdown on an HTTP 404 response */
5400 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005401 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5402 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005403 }
Willy Tarreauef781042010-01-27 11:53:01 +01005404 else if (strcmp(args[1], "send-state") == 0) {
5405 /* enable emission of the apparent state of a server in HTTP checks */
5406 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005407 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5408 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005409 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005410 else if (strcmp(args[1], "expect") == 0) {
5411 const char *ptr_arg;
5412 int cur_arg;
5413
5414 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005415 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005416 err_code |= ERR_ALERT | ERR_FATAL;
5417 goto out;
5418 }
5419
5420 cur_arg = 2;
5421 /* consider exclamation marks, sole or at the beginning of a word */
5422 while (*(ptr_arg = args[cur_arg])) {
5423 while (*ptr_arg == '!') {
5424 curproxy->options2 ^= PR_O2_EXP_INV;
5425 ptr_arg++;
5426 }
5427 if (*ptr_arg)
5428 break;
5429 cur_arg++;
5430 }
5431 /* now ptr_arg points to the beginning of a word past any possible
5432 * exclamation mark, and cur_arg is the argument which holds this word.
5433 */
5434 if (strcmp(ptr_arg, "status") == 0) {
5435 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005436 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5437 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005438 err_code |= ERR_ALERT | ERR_FATAL;
5439 goto out;
5440 }
5441 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005442 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005443 curproxy->expect_str = strdup(args[cur_arg + 1]);
5444 }
5445 else if (strcmp(ptr_arg, "string") == 0) {
5446 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005447 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5448 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005449 err_code |= ERR_ALERT | ERR_FATAL;
5450 goto out;
5451 }
5452 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005453 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005454 curproxy->expect_str = strdup(args[cur_arg + 1]);
5455 }
5456 else if (strcmp(ptr_arg, "rstatus") == 0) {
5457 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005458 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5459 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005460 err_code |= ERR_ALERT | ERR_FATAL;
5461 goto out;
5462 }
5463 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005464 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005465 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005466 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005467 free(curproxy->expect_regex);
5468 curproxy->expect_regex = NULL;
5469 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005470 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005471 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5472 error = NULL;
5473 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005474 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5475 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005476 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005477 err_code |= ERR_ALERT | ERR_FATAL;
5478 goto out;
5479 }
5480 }
5481 else if (strcmp(ptr_arg, "rstring") == 0) {
5482 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005483 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5484 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005485 err_code |= ERR_ALERT | ERR_FATAL;
5486 goto out;
5487 }
5488 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005489 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005490 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005491 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005492 free(curproxy->expect_regex);
5493 curproxy->expect_regex = NULL;
5494 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005495 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005496 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5497 error = NULL;
5498 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005499 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5500 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005501 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005502 err_code |= ERR_ALERT | ERR_FATAL;
5503 goto out;
5504 }
5505 }
5506 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005507 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5508 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005509 err_code |= ERR_ALERT | ERR_FATAL;
5510 goto out;
5511 }
5512 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005513 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005514 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 +02005515 err_code |= ERR_ALERT | ERR_FATAL;
5516 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005517 }
5518 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005519 else if (!strcmp(args[0], "tcp-check")) {
5520 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5521 err_code |= ERR_WARN;
5522
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005523 if (strcmp(args[1], "comment") == 0) {
5524 int cur_arg;
5525 struct tcpcheck_rule *tcpcheck;
5526
5527 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005528 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005529 tcpcheck->action = TCPCHK_ACT_COMMENT;
5530
5531 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005532 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5533 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005534 err_code |= ERR_ALERT | ERR_FATAL;
5535 goto out;
5536 }
5537
5538 tcpcheck->comment = strdup(args[cur_arg + 1]);
5539
5540 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005541 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5542 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005543 }
5544 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005545 const char *ptr_arg;
5546 int cur_arg;
5547 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005548
5549 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005550 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5551 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5552 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5553 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5554 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005555
Willy Tarreau5581c272015-05-13 12:24:53 +02005556 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5557 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005558 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5559 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005560 err_code |= ERR_ALERT | ERR_FATAL;
5561 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005562 }
5563
5564 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005565 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005566 tcpcheck->action = TCPCHK_ACT_CONNECT;
5567
5568 /* parsing each parameters to fill up the rule */
5569 while (*(ptr_arg = args[cur_arg])) {
5570 /* tcp port */
5571 if (strcmp(args[cur_arg], "port") == 0) {
5572 if ( (atol(args[cur_arg + 1]) > 65535) ||
5573 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005574 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5575 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005576 err_code |= ERR_ALERT | ERR_FATAL;
5577 goto out;
5578 }
5579 tcpcheck->port = atol(args[cur_arg + 1]);
5580 cur_arg += 2;
5581 }
5582 /* send proxy protocol */
5583 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5584 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5585 cur_arg++;
5586 }
5587#ifdef USE_OPENSSL
5588 else if (strcmp(args[cur_arg], "ssl") == 0) {
5589 curproxy->options |= PR_O_TCPCHK_SSL;
5590 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5591 cur_arg++;
5592 }
5593#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005594 /* comment for this tcpcheck line */
5595 else if (strcmp(args[cur_arg], "comment") == 0) {
5596 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005597 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5598 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005599 err_code |= ERR_ALERT | ERR_FATAL;
5600 goto out;
5601 }
5602 tcpcheck->comment = strdup(args[cur_arg + 1]);
5603 cur_arg += 2;
5604 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005605 else {
5606#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005607 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 +01005608#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005609 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 +01005610#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005611 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005612 err_code |= ERR_ALERT | ERR_FATAL;
5613 goto out;
5614 }
5615
5616 }
5617
5618 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5619 }
5620 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005621 if (! *(args[2]) ) {
5622 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005623 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5624 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005625 err_code |= ERR_ALERT | ERR_FATAL;
5626 goto out;
5627 } else {
5628 struct tcpcheck_rule *tcpcheck;
5629
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005630 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005631
5632 tcpcheck->action = TCPCHK_ACT_SEND;
5633 tcpcheck->string_len = strlen(args[2]);
5634 tcpcheck->string = strdup(args[2]);
5635 tcpcheck->expect_regex = NULL;
5636
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005637 /* comment for this tcpcheck line */
5638 if (strcmp(args[3], "comment") == 0) {
5639 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005640 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5641 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005642 err_code |= ERR_ALERT | ERR_FATAL;
5643 goto out;
5644 }
5645 tcpcheck->comment = strdup(args[4]);
5646 }
5647
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005648 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5649 }
5650 }
5651 else if (strcmp(args[1], "send-binary") == 0) {
5652 if (! *(args[2]) ) {
5653 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005654 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5655 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005656 err_code |= ERR_ALERT | ERR_FATAL;
5657 goto out;
5658 } else {
5659 struct tcpcheck_rule *tcpcheck;
5660 char *err = NULL;
5661
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005662 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005663
5664 tcpcheck->action = TCPCHK_ACT_SEND;
5665 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005666 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5667 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005668 err_code |= ERR_ALERT | ERR_FATAL;
5669 goto out;
5670 }
5671 tcpcheck->expect_regex = NULL;
5672
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005673 /* comment for this tcpcheck line */
5674 if (strcmp(args[3], "comment") == 0) {
5675 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005676 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5677 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005678 err_code |= ERR_ALERT | ERR_FATAL;
5679 goto out;
5680 }
5681 tcpcheck->comment = strdup(args[4]);
5682 }
5683
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005684 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5685 }
5686 }
5687 else if (strcmp(args[1], "expect") == 0) {
5688 const char *ptr_arg;
5689 int cur_arg;
5690 int inverse = 0;
5691
5692 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005693 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005694 err_code |= ERR_ALERT | ERR_FATAL;
5695 goto out;
5696 }
5697
5698 cur_arg = 2;
5699 /* consider exclamation marks, sole or at the beginning of a word */
5700 while (*(ptr_arg = args[cur_arg])) {
5701 while (*ptr_arg == '!') {
5702 inverse = !inverse;
5703 ptr_arg++;
5704 }
5705 if (*ptr_arg)
5706 break;
5707 cur_arg++;
5708 }
5709 /* now ptr_arg points to the beginning of a word past any possible
5710 * exclamation mark, and cur_arg is the argument which holds this word.
5711 */
5712 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005713 struct tcpcheck_rule *tcpcheck;
5714 char *err = NULL;
5715
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005716 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005717 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5718 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005719 err_code |= ERR_ALERT | ERR_FATAL;
5720 goto out;
5721 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005722
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005723 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005724
5725 tcpcheck->action = TCPCHK_ACT_EXPECT;
5726 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005727 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5728 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005729 err_code |= ERR_ALERT | ERR_FATAL;
5730 goto out;
5731 }
5732 tcpcheck->expect_regex = NULL;
5733 tcpcheck->inverse = inverse;
5734
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005735 /* tcpcheck comment */
5736 cur_arg += 2;
5737 if (strcmp(args[cur_arg], "comment") == 0) {
5738 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005739 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5740 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005741 err_code |= ERR_ALERT | ERR_FATAL;
5742 goto out;
5743 }
5744 tcpcheck->comment = strdup(args[cur_arg + 1]);
5745 }
5746
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005747 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5748 }
5749 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005750 struct tcpcheck_rule *tcpcheck;
5751
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005752 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005753 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5754 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005755 err_code |= ERR_ALERT | ERR_FATAL;
5756 goto out;
5757 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005758
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005759 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005760
5761 tcpcheck->action = TCPCHK_ACT_EXPECT;
5762 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5763 tcpcheck->string = strdup(args[cur_arg + 1]);
5764 tcpcheck->expect_regex = NULL;
5765 tcpcheck->inverse = inverse;
5766
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005767 /* tcpcheck comment */
5768 cur_arg += 2;
5769 if (strcmp(args[cur_arg], "comment") == 0) {
5770 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005771 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5772 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005773 err_code |= ERR_ALERT | ERR_FATAL;
5774 goto out;
5775 }
5776 tcpcheck->comment = strdup(args[cur_arg + 1]);
5777 }
5778
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005779 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5780 }
5781 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005782 struct tcpcheck_rule *tcpcheck;
5783
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005784 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005785 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5786 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005787 err_code |= ERR_ALERT | ERR_FATAL;
5788 goto out;
5789 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005790
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005791 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005792
5793 tcpcheck->action = TCPCHK_ACT_EXPECT;
5794 tcpcheck->string_len = 0;
5795 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005796 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5797 error = NULL;
5798 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005799 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5800 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005801 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005802 err_code |= ERR_ALERT | ERR_FATAL;
5803 goto out;
5804 }
5805 tcpcheck->inverse = inverse;
5806
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005807 /* tcpcheck comment */
5808 cur_arg += 2;
5809 if (strcmp(args[cur_arg], "comment") == 0) {
5810 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005811 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5812 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005813 err_code |= ERR_ALERT | ERR_FATAL;
5814 goto out;
5815 }
5816 tcpcheck->comment = strdup(args[cur_arg + 1]);
5817 }
5818
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005819 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5820 }
5821 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005822 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5823 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005824 err_code |= ERR_ALERT | ERR_FATAL;
5825 goto out;
5826 }
5827 }
5828 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005829 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 +02005830 err_code |= ERR_ALERT | ERR_FATAL;
5831 goto out;
5832 }
5833 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005834 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005835 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005836 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005837 err_code |= ERR_ALERT | ERR_FATAL;
5838 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005839 }
5840
Willy Tarreaub80c2302007-11-30 20:51:32 +01005841 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005842 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005843
5844 if (strcmp(args[1], "fail") == 0) {
5845 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005846 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005847 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5848 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005849 err_code |= ERR_ALERT | ERR_FATAL;
5850 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005851 }
5852
Willy Tarreau721d8e02017-12-01 18:25:08 +01005853 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005854 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005855 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5856 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005857 err_code |= ERR_ALERT | ERR_FATAL;
5858 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005859 }
5860 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5861 }
5862 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005863 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005864 err_code |= ERR_ALERT | ERR_FATAL;
5865 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005866 }
5867 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005868#ifdef TPROXY
5869 else if (!strcmp(args[0], "transparent")) {
5870 /* enable transparent proxy connections */
5871 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005872 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5873 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005874 }
5875#endif
5876 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005877 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005878 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005879
Willy Tarreaubaaee002006-06-26 02:48:02 +02005880 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005881 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005882 err_code |= ERR_ALERT | ERR_FATAL;
5883 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005884 }
5885 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005886 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5887 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005888 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005889 else if (!strcmp(args[0], "backlog")) { /* backlog */
5890 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005891 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005892
5893 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005894 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005895 err_code |= ERR_ALERT | ERR_FATAL;
5896 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005897 }
5898 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005899 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5900 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005901 }
Willy Tarreau86034312006-12-29 00:10:33 +01005902 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005903 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005904 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005905
Willy Tarreau86034312006-12-29 00:10:33 +01005906 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005907 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005908 err_code |= ERR_ALERT | ERR_FATAL;
5909 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005910 }
5911 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005912 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5913 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005914 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005915 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5916 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005917 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005918 err_code |= ERR_ALERT | ERR_FATAL;
5919 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005920 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005921 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5922 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005923 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5924 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005925 err_code |= ERR_ALERT | ERR_FATAL;
5926 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005927 }
5928 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005929 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5930 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005931 }
5932 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005933 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005934 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005935 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005936
Willy Tarreaubaaee002006-06-26 02:48:02 +02005937 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005938 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005939 err_code |= ERR_ALERT | ERR_FATAL;
5940 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005941 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005942 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005943 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005944
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005945 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005946 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005947 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005948 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005949 goto out;
5950 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005951
5952 proto = protocol_by_family(sk->ss_family);
5953 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005954 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5955 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005956 err_code |= ERR_ALERT | ERR_FATAL;
5957 goto out;
5958 }
5959
5960 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005961 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5962 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005963 err_code |= ERR_ALERT | ERR_FATAL;
5964 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005965 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005966
5967 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005968 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5969 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005970 err_code |= ERR_ALERT | ERR_FATAL;
5971 goto out;
5972 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005973
William Lallemanddf1425a2015-04-28 20:17:49 +02005974 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5975 goto out;
5976
Willy Tarreaud5191e72010-02-09 20:50:45 +01005977 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005978 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005979 }
5980 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005981 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005982 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005983
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005984 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005985 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005986 err_code |= ERR_ALERT | ERR_FATAL;
5987 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005988 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005989 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005990 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005991 /**
5992 * The syntax for hash-type config element is
5993 * hash-type {map-based|consistent} [[<algo>] avalanche]
5994 *
5995 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5996 */
5997 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005998
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005999 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
6000 err_code |= ERR_WARN;
6001
6002 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006003 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
6004 }
6005 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006006 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
6007 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006008 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006009 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 -05006010 err_code |= ERR_ALERT | ERR_FATAL;
6011 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01006012 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006013 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006014 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006015 err_code |= ERR_ALERT | ERR_FATAL;
6016 goto out;
6017 }
Bhaskar98634f02013-10-29 23:30:51 -04006018
6019 /* set the hash function to use */
6020 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006021 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04006022 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006023
6024 /* if consistent with no argument, then avalanche modifier is also applied */
6025 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6026 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006027 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006028 /* set the hash function */
6029 if (!strcmp(args[2], "sdbm")) {
6030 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6031 }
6032 else if (!strcmp(args[2], "djb2")) {
6033 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006034 }
6035 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006036 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006037 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006038 else if (!strcmp(args[2], "crc32")) {
6039 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6040 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006041 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006042 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 -05006043 err_code |= ERR_ALERT | ERR_FATAL;
6044 goto out;
6045 }
6046
6047 /* set the hash modifier */
6048 if (!strcmp(args[3], "avalanche")) {
6049 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6050 }
6051 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006052 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 -05006053 err_code |= ERR_ALERT | ERR_FATAL;
6054 goto out;
6055 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006056 }
William Lallemanda73203e2012-03-12 12:48:57 +01006057 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006058 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6059 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006060 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006061 err_code |= ERR_ALERT | ERR_FATAL;
6062 goto out;
6063 }
6064 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6065 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006066 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 -04006067 err_code |= ERR_ALERT | ERR_FATAL;
6068 goto out;
6069 }
6070 }
William Lallemanda73203e2012-03-12 12:48:57 +01006071 else if (strcmp(args[0], "unique-id-format") == 0) {
6072 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006073 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006074 err_code |= ERR_ALERT | ERR_FATAL;
6075 goto out;
6076 }
William Lallemand3203ff42012-11-11 17:30:56 +01006077 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006078 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 +01006079 err_code |= ERR_ALERT | ERR_FATAL;
6080 goto out;
6081 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006082 free(curproxy->conf.uniqueid_format_string);
6083 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006084
Willy Tarreau62a61232013-04-12 18:13:46 +02006085 free(curproxy->conf.uif_file);
6086 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6087 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006088 }
William Lallemanda73203e2012-03-12 12:48:57 +01006089
6090 else if (strcmp(args[0], "unique-id-header") == 0) {
6091 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006092 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006093 err_code |= ERR_ALERT | ERR_FATAL;
6094 goto out;
6095 }
6096 free(curproxy->header_unique_id);
6097 curproxy->header_unique_id = strdup(args[1]);
6098 }
6099
William Lallemand723b73a2012-02-08 16:37:49 +01006100 else if (strcmp(args[0], "log-format") == 0) {
6101 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006102 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006103 err_code |= ERR_ALERT | ERR_FATAL;
6104 goto out;
6105 }
William Lallemand3203ff42012-11-11 17:30:56 +01006106 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006107 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 +01006108 err_code |= ERR_ALERT | ERR_FATAL;
6109 goto out;
6110 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006111 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6112 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006113
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006114 if (curproxy->conf.logformat_string == default_http_log_format)
6115 oldlogformat = "option httplog";
6116 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6117 oldlogformat = "option tcplog";
6118 else if (curproxy->conf.logformat_string == clf_http_log_format)
6119 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006120 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6121 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006122 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006123 if (curproxy->conf.logformat_string != default_http_log_format &&
6124 curproxy->conf.logformat_string != default_tcp_log_format &&
6125 curproxy->conf.logformat_string != clf_http_log_format)
6126 free(curproxy->conf.logformat_string);
6127 curproxy->conf.logformat_string = strdup(args[1]);
6128
6129 free(curproxy->conf.lfs_file);
6130 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6131 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006132
6133 /* get a chance to improve log-format error reporting by
6134 * reporting the correct line-number when possible.
6135 */
6136 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006137 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6138 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006139 err_code |= ERR_WARN;
6140 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006141 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006142 else if (!strcmp(args[0], "log-format-sd")) {
6143 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006144 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006145 err_code |= ERR_ALERT | ERR_FATAL;
6146 goto out;
6147 }
6148 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006149 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 +02006150 err_code |= ERR_ALERT | ERR_FATAL;
6151 goto out;
6152 }
6153
6154 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6155 free(curproxy->conf.logformat_sd_string);
6156 curproxy->conf.logformat_sd_string = strdup(args[1]);
6157
6158 free(curproxy->conf.lfsd_file);
6159 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6160 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6161
6162 /* get a chance to improve log-format-sd error reporting by
6163 * reporting the correct line-number when possible.
6164 */
6165 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006166 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6167 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006168 err_code |= ERR_WARN;
6169 }
6170 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006171 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6172 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006173 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 +01006174 err_code |= ERR_ALERT | ERR_FATAL;
6175 goto out;
6176 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006177 chunk_destroy(&curproxy->log_tag);
6178 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006179 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006180 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6181 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6182 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006183 err_code |= ERR_ALERT | ERR_FATAL;
6184 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006185 }
6186 }
6187 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006188 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006189 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006190 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006191 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006192
Willy Tarreau977b8e42006-12-29 14:19:17 +01006193 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006194 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006195
Willy Tarreaubaaee002006-06-26 02:48:02 +02006196 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006197 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6198 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006199 err_code |= ERR_ALERT | ERR_FATAL;
6200 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006201 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006202
6203 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006204 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6205 free(curproxy->conn_src.iface_name);
6206 curproxy->conn_src.iface_name = NULL;
6207 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006208
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006209 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006210 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006211 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6212 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006213 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006214 goto out;
6215 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006216
6217 proto = protocol_by_family(sk->ss_family);
6218 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006219 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6220 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006221 err_code |= ERR_ALERT | ERR_FATAL;
6222 goto out;
6223 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006224
6225 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006226 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6227 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006228 err_code |= ERR_ALERT | ERR_FATAL;
6229 goto out;
6230 }
6231
Willy Tarreauef9a3602012-12-08 22:29:20 +01006232 curproxy->conn_src.source_addr = *sk;
6233 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006234
6235 cur_arg = 2;
6236 while (*(args[cur_arg])) {
6237 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006238#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006239 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006240 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6241 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006242 err_code |= ERR_ALERT | ERR_FATAL;
6243 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006244 }
6245
6246 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006247 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6248 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006249 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006250 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6251 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006252 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6253 char *name, *end;
6254
6255 name = args[cur_arg+1] + 7;
6256 while (isspace(*name))
6257 name++;
6258
6259 end = name;
6260 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6261 end++;
6262
Willy Tarreauef9a3602012-12-08 22:29:20 +01006263 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6264 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6265 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6266 curproxy->conn_src.bind_hdr_len = end - name;
6267 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6268 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6269 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006270
6271 /* now look for an occurrence number */
6272 while (isspace(*end))
6273 end++;
6274 if (*end == ',') {
6275 end++;
6276 name = end;
6277 if (*end == '-')
6278 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006279 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006280 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006281 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006282 }
6283
Willy Tarreauef9a3602012-12-08 22:29:20 +01006284 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006285 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6286 " occurrences values smaller than %d.\n",
6287 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006288 err_code |= ERR_ALERT | ERR_FATAL;
6289 goto out;
6290 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006291 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006292 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006293
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006294 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006295 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006296 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6297 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006298 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006299 goto out;
6300 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006301
6302 proto = protocol_by_family(sk->ss_family);
6303 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006304 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6305 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006306 err_code |= ERR_ALERT | ERR_FATAL;
6307 goto out;
6308 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006309
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006310 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006311 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6312 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006313 err_code |= ERR_ALERT | ERR_FATAL;
6314 goto out;
6315 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006316 curproxy->conn_src.tproxy_addr = *sk;
6317 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006318 }
6319 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006320#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006321 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6322 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006323 err_code |= ERR_ALERT | ERR_FATAL;
6324 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006325#endif
6326 cur_arg += 2;
6327 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006328 }
6329
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006330 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6331#ifdef SO_BINDTODEVICE
6332 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006333 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6334 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006335 err_code |= ERR_ALERT | ERR_FATAL;
6336 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006337 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006338 free(curproxy->conn_src.iface_name);
6339 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6340 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006341 global.last_checks |= LSTCHK_NETADM;
6342#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006343 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6344 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006345 err_code |= ERR_ALERT | ERR_FATAL;
6346 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006347#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006348 cur_arg += 2;
6349 continue;
6350 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006351 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6352 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006353 err_code |= ERR_ALERT | ERR_FATAL;
6354 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006355 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006356 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006357 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006358 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6359 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006360 err_code |= ERR_ALERT | ERR_FATAL;
6361 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006362 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006363 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006364 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006365 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6366 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006367 err_code |= ERR_ALERT | ERR_FATAL;
6368 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006369 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006370
6371 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006372 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006373 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006374 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006375 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006376 }
6377 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006378 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006379 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006380 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006381 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006382 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006383 }
6384 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006385 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006386 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006387 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006388 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006389 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006390 }
6391 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006392 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006393 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006394 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006395 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006396 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006397 }
6398 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006399 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006400 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006401 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006402 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006403 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006404 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006405 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006406 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006407 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006408 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006409 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006410 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006411 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006412 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006413 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006414 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6415 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006416 err_code |= ERR_ALERT | ERR_FATAL;
6417 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006418 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006419
6420 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006421 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006422 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006423 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006424 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006425 }
6426 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006427 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006428 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006429 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006430 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006431 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006432 }
6433 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006434 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006435 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006436 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006437 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006438 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006439 }
6440 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006441 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006442 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006443 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006444 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006445 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006446 }
6447 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006448 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006449 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006450 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006451 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006452 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006453 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006454 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006455 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006456 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006457 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006458 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006459 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006460 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006461 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006462 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006463
Willy Tarreaubaaee002006-06-26 02:48:02 +02006464 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006465 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006466 err_code |= ERR_ALERT | ERR_FATAL;
6467 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006468 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006469 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006470 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006471
Willy Tarreaubaaee002006-06-26 02:48:02 +02006472 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006473 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006474 err_code |= ERR_ALERT | ERR_FATAL;
6475 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006476 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006477
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006478 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006479 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006480 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6481 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006482 err_code |= ERR_ALERT | ERR_FATAL;
6483 goto out;
6484 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006485 err_code |= warnif_cond_conflicts(cond,
6486 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6487 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006488 }
6489 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006490 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6491 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006492 err_code |= ERR_ALERT | ERR_FATAL;
6493 goto out;
6494 }
6495
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006496 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006497 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006498 wl->s = strdup(args[1]);
6499 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006500 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006501 }
6502 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006503 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006504 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6505 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006506 err_code |= ERR_ALERT | ERR_FATAL;
6507 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006508 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006509
Willy Tarreauade5ec42010-01-28 19:33:49 +01006510 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006511 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006512 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006513 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006514 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006515 }
6516 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006517 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006518 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006519 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006520 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006521 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006522 }
6523 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006524 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006525 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006526 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006527 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006528 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006529 }
6530 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006531 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006532 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6533 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006534 err_code |= ERR_ALERT | ERR_FATAL;
6535 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006536 }
6537
Willy Tarreauade5ec42010-01-28 19:33:49 +01006538 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006539 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006540 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006541 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006542 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006543 }
6544 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006545 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006546 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006547 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006548 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006549 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006550 }
6551 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006552 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006553 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006554 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006555 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006556 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006557 }
6558 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006559 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006560
Willy Tarreaubaaee002006-06-26 02:48:02 +02006561 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006562 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006563 err_code |= ERR_ALERT | ERR_FATAL;
6564 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006565 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006566 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006567 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006568
Willy Tarreaubaaee002006-06-26 02:48:02 +02006569 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006570 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006571 err_code |= ERR_ALERT | ERR_FATAL;
6572 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006573 }
6574
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006575 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006576 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006577 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6578 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006579 err_code |= ERR_ALERT | ERR_FATAL;
6580 goto out;
6581 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006582 err_code |= warnif_cond_conflicts(cond,
6583 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6584 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006585 }
6586 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006587 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6588 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006589 err_code |= ERR_ALERT | ERR_FATAL;
6590 goto out;
6591 }
6592
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006593 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006594 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006595 wl->s = strdup(args[1]);
6596 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006597 }
6598 else if (!strcmp(args[0], "errorloc") ||
6599 !strcmp(args[0], "errorloc302") ||
6600 !strcmp(args[0], "errorloc303")) { /* error location */
6601 int errnum, errlen;
6602 char *err;
6603
Willy Tarreau977b8e42006-12-29 14:19:17 +01006604 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006605 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006606
Willy Tarreaubaaee002006-06-26 02:48:02 +02006607 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006608 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 +02006609 err_code |= ERR_ALERT | ERR_FATAL;
6610 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006611 }
6612
6613 errnum = atol(args[1]);
6614 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006615 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6616 err = malloc(errlen);
6617 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006618 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006619 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6620 err = malloc(errlen);
6621 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006622 }
6623
Willy Tarreau0f772532006-12-23 20:51:41 +01006624 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6625 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006626 chunk_destroy(&curproxy->errmsg[rc]);
6627 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006628 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006629 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006630 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006631
6632 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006633 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6634 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006635 free(err);
6636 }
6637 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006638 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6639 int errnum, errlen, fd;
6640 char *err;
6641 struct stat stat;
6642
6643 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006644 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006645
6646 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006647 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 +02006648 err_code |= ERR_ALERT | ERR_FATAL;
6649 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006650 }
6651
6652 fd = open(args[2], O_RDONLY);
6653 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006654 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6655 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006656 if (fd >= 0)
6657 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006658 err_code |= ERR_ALERT | ERR_FATAL;
6659 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006660 }
6661
Willy Tarreau27a674e2009-08-17 07:23:33 +02006662 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006663 errlen = stat.st_size;
6664 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006665 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6666 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006667 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006668 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006669 }
6670
6671 err = malloc(errlen); /* malloc() must succeed during parsing */
6672 errnum = read(fd, err, errlen);
6673 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006674 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6675 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006676 close(fd);
6677 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006678 err_code |= ERR_ALERT | ERR_FATAL;
6679 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006680 }
6681 close(fd);
6682
6683 errnum = atol(args[1]);
6684 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6685 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006686 chunk_destroy(&curproxy->errmsg[rc]);
6687 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006688 break;
6689 }
6690 }
6691
6692 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006693 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6694 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006695 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006696 free(err);
6697 }
6698 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006699 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006700 struct cfg_kw_list *kwl;
6701 int index;
6702
6703 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6704 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6705 if (kwl->kw[index].section != CFG_LISTEN)
6706 continue;
6707 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6708 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006709 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006710 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006711 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006712 err_code |= ERR_ALERT | ERR_FATAL;
6713 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006714 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006715 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006716 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006717 err_code |= ERR_WARN;
6718 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006719 }
Willy Tarreau93893792009-07-23 13:19:11 +02006720 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006721 }
6722 }
6723 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006724
Christopher Faulet767a84b2017-11-24 16:50:31 +01006725 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006726 err_code |= ERR_ALERT | ERR_FATAL;
6727 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006728 }
Willy Tarreau93893792009-07-23 13:19:11 +02006729 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006730 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006731 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006732}
6733
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006734int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006735cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6736{
6737#ifdef CONFIG_HAP_NS
6738 const char *err;
6739 const char *item = args[0];
6740
6741 if (!strcmp(item, "namespace_list")) {
6742 return 0;
6743 }
6744 else if (!strcmp(item, "namespace")) {
6745 size_t idx = 1;
6746 const char *current;
6747 while (*(current = args[idx++])) {
6748 err = invalid_char(current);
6749 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006750 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6751 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006752 return ERR_ALERT | ERR_FATAL;
6753 }
6754
6755 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006756 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6757 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006758 return ERR_ALERT | ERR_FATAL;
6759 }
6760 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006761 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6762 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006763 return ERR_ALERT | ERR_FATAL;
6764 }
6765 }
6766 }
6767
6768 return 0;
6769#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006770 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6771 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006772 return ERR_ALERT | ERR_FATAL;
6773#endif
6774}
6775
6776int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006777cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6778{
6779
6780 int err_code = 0;
6781 const char *err;
6782
6783 if (!strcmp(args[0], "userlist")) { /* new userlist */
6784 struct userlist *newul;
6785
6786 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006787 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6788 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006789 err_code |= ERR_ALERT | ERR_FATAL;
6790 goto out;
6791 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006792 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6793 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006794
6795 err = invalid_char(args[1]);
6796 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006797 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6798 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006799 err_code |= ERR_ALERT | ERR_FATAL;
6800 goto out;
6801 }
6802
6803 for (newul = userlist; newul; newul = newul->next)
6804 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006805 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6806 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006807 err_code |= ERR_WARN;
6808 goto out;
6809 }
6810
Vincent Bernat02779b62016-04-03 13:48:43 +02006811 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006812 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006813 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006814 err_code |= ERR_ALERT | ERR_ABORT;
6815 goto out;
6816 }
6817
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006818 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006819 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006820 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006821 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006822 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006823 goto out;
6824 }
6825
6826 newul->next = userlist;
6827 userlist = newul;
6828
6829 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006830 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006831 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006832 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006833
6834 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006835 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6836 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006837 err_code |= ERR_ALERT | ERR_FATAL;
6838 goto out;
6839 }
6840
6841 err = invalid_char(args[1]);
6842 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006843 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6844 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006845 err_code |= ERR_ALERT | ERR_FATAL;
6846 goto out;
6847 }
6848
William Lallemand4ac9f542015-05-28 18:03:51 +02006849 if (!userlist)
6850 goto out;
6851
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006852 for (ag = userlist->groups; ag; ag = ag->next)
6853 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006854 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6855 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006856 err_code |= ERR_ALERT;
6857 goto out;
6858 }
6859
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006860 ag = calloc(1, sizeof(*ag));
6861 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006862 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006863 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006864 goto out;
6865 }
6866
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006867 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006868 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006869 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006870 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006871 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006872 goto out;
6873 }
6874
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006875 cur_arg = 2;
6876
6877 while (*args[cur_arg]) {
6878 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006879 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006880 cur_arg += 2;
6881 continue;
6882 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006883 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6884 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006885 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006886 free(ag->groupusers);
6887 free(ag->name);
6888 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006889 goto out;
6890 }
6891 }
6892
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006893 ag->next = userlist->groups;
6894 userlist->groups = ag;
6895
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006896 } else if (!strcmp(args[0], "user")) { /* new user */
6897 struct auth_users *newuser;
6898 int cur_arg;
6899
6900 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006901 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6902 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006903 err_code |= ERR_ALERT | ERR_FATAL;
6904 goto out;
6905 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006906 if (!userlist)
6907 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006908
6909 for (newuser = userlist->users; newuser; newuser = newuser->next)
6910 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006911 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6912 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006913 err_code |= ERR_ALERT;
6914 goto out;
6915 }
6916
Vincent Bernat02779b62016-04-03 13:48:43 +02006917 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006918 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006919 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006920 err_code |= ERR_ALERT | ERR_ABORT;
6921 goto out;
6922 }
6923
6924 newuser->user = strdup(args[1]);
6925
6926 newuser->next = userlist->users;
6927 userlist->users = newuser;
6928
6929 cur_arg = 2;
6930
6931 while (*args[cur_arg]) {
6932 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006933#ifdef CONFIG_HAP_CRYPT
6934 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006935 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6936 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006937 err_code |= ERR_ALERT | ERR_FATAL;
6938 goto out;
6939 }
6940#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006941 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6942 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006943 err_code |= ERR_ALERT;
6944#endif
6945 newuser->pass = strdup(args[cur_arg + 1]);
6946 cur_arg += 2;
6947 continue;
6948 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6949 newuser->pass = strdup(args[cur_arg + 1]);
6950 newuser->flags |= AU_O_INSECURE;
6951 cur_arg += 2;
6952 continue;
6953 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006954 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006955 cur_arg += 2;
6956 continue;
6957 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006958 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6959 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006960 err_code |= ERR_ALERT | ERR_FATAL;
6961 goto out;
6962 }
6963 }
6964 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006965 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 +01006966 err_code |= ERR_ALERT | ERR_FATAL;
6967 }
6968
6969out:
6970 return err_code;
6971}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006972
Christopher Faulet79bdef32016-11-04 22:36:15 +01006973int
6974cfg_parse_scope(const char *file, int linenum, char *line)
6975{
6976 char *beg, *end, *scope = NULL;
6977 int err_code = 0;
6978 const char *err;
6979
6980 beg = line + 1;
6981 end = strchr(beg, ']');
6982
6983 /* Detect end of scope declaration */
6984 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006985 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
6986 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006987 err_code |= ERR_ALERT | ERR_FATAL;
6988 goto out;
6989 }
6990
6991 /* Get scope name and check its validity */
6992 scope = my_strndup(beg, end-beg);
6993 err = invalid_char(scope);
6994 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006995 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
6996 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006997 err_code |= ERR_ALERT | ERR_ABORT;
6998 goto out;
6999 }
7000
7001 /* Be sure to have a scope declaration alone on its line */
7002 line = end+1;
7003 while (isspace((unsigned char)*line))
7004 line++;
7005 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007006 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7007 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007008 err_code |= ERR_ALERT | ERR_ABORT;
7009 goto out;
7010 }
7011
7012 /* We have a valid scope declaration, save it */
7013 free(cfg_scope);
7014 cfg_scope = scope;
7015 scope = NULL;
7016
7017 out:
7018 free(scope);
7019 return err_code;
7020}
7021
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01007022int
7023cfg_parse_track_sc_num(unsigned int *track_sc_num,
7024 const char *arg, const char *end, char **errmsg)
7025{
7026 const char *p;
7027 unsigned int num;
7028
7029 p = arg;
7030 num = read_uint64(&arg, end);
7031
7032 if (arg != end) {
7033 memprintf(errmsg, "Wrong track-sc number '%s'", p);
7034 return -1;
7035 }
7036
7037 if (num >= MAX_SESS_STKCTR) {
7038 memprintf(errmsg, "%u track-sc number exceeding "
7039 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
7040 return -1;
7041 }
7042
7043 *track_sc_num = num;
7044 return 0;
7045}
7046
Willy Tarreaubaaee002006-06-26 02:48:02 +02007047/*
7048 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007049 * Returns the error code, 0 if OK, or any combination of :
7050 * - ERR_ABORT: must abort ASAP
7051 * - ERR_FATAL: we can continue parsing but not start the service
7052 * - ERR_WARN: a warning has been emitted
7053 * - ERR_ALERT: an alert has been emitted
7054 * Only the two first ones can stop processing, the two others are just
7055 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007056 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007057int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007058{
William Lallemand64e84512015-05-12 14:25:37 +02007059 char *thisline;
7060 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007061 FILE *f;
7062 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007063 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007064 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007065 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007066 int readbytes = 0;
7067
7068 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007069 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007070 return -1;
7071 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007072
David Carlier97880bb2016-04-08 10:35:26 +01007073 if ((f=fopen(file,"r")) == NULL) {
7074 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007075 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007076 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007077
William Lallemandb2f07452015-05-12 14:27:13 +02007078next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007079 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007080 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007081 char *end;
7082 char *args[MAX_LINE_ARGS + 1];
7083 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007084 int dquote = 0; /* double quote */
7085 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007086
Willy Tarreaubaaee002006-06-26 02:48:02 +02007087 linenum++;
7088
7089 end = line + strlen(line);
7090
William Lallemand64e84512015-05-12 14:25:37 +02007091 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007092 /* Check if we reached the limit and the last char is not \n.
7093 * Watch out for the last line without the terminating '\n'!
7094 */
William Lallemand64e84512015-05-12 14:25:37 +02007095 char *newline;
7096 int newlinesize = linesize * 2;
7097
7098 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7099 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007100 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7101 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007102 err_code |= ERR_ALERT | ERR_FATAL;
7103 continue;
7104 }
7105
7106 readbytes = linesize - 1;
7107 linesize = newlinesize;
7108 thisline = newline;
7109 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007110 }
7111
William Lallemand64e84512015-05-12 14:25:37 +02007112 readbytes = 0;
7113
Willy Tarreaubaaee002006-06-26 02:48:02 +02007114 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007115 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007116 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007117
Christopher Faulet79bdef32016-11-04 22:36:15 +01007118
7119 if (*line == '[') {/* This is the begining if a scope */
7120 err_code |= cfg_parse_scope(file, linenum, line);
7121 goto next_line;
7122 }
7123
Willy Tarreaubaaee002006-06-26 02:48:02 +02007124 arg = 0;
7125 args[arg] = line;
7126
7127 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007128 if (*line == '"' && !squote) { /* double quote outside single quotes */
7129 if (dquote)
7130 dquote = 0;
7131 else
7132 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007133 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007134 end--;
7135 }
7136 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7137 if (squote)
7138 squote = 0;
7139 else
7140 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007141 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007142 end--;
7143 }
7144 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007145 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7146 * C equivalent value. Other combinations left unchanged (eg: \1).
7147 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007148 int skip = 0;
7149 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7150 *line = line[1];
7151 skip = 1;
7152 }
7153 else if (line[1] == 'r') {
7154 *line = '\r';
7155 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007156 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007157 else if (line[1] == 'n') {
7158 *line = '\n';
7159 skip = 1;
7160 }
7161 else if (line[1] == 't') {
7162 *line = '\t';
7163 skip = 1;
7164 }
7165 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007166 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007167 unsigned char hex1, hex2;
7168 hex1 = toupper(line[2]) - '0';
7169 hex2 = toupper(line[3]) - '0';
7170 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7171 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7172 *line = (hex1<<4) + hex2;
7173 skip = 3;
7174 }
7175 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007176 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007177 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007178 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007179 } else if (line[1] == '"') {
7180 *line = '"';
7181 skip = 1;
7182 } else if (line[1] == '\'') {
7183 *line = '\'';
7184 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007185 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7186 *line = '$';
7187 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007188 }
7189 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007190 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007191 end -= skip;
7192 }
7193 line++;
7194 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007195 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007196 /* end of string, end of loop */
7197 *line = 0;
7198 break;
7199 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007200 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007201 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007202 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007203 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007204 line++;
7205 args[++arg] = line;
7206 }
William Lallemandb2f07452015-05-12 14:27:13 +02007207 else if (dquote && *line == '$') {
7208 /* environment variables are evaluated inside double quotes */
7209 char *var_beg;
7210 char *var_end;
7211 char save_char;
7212 char *value;
7213 int val_len;
7214 int newlinesize;
7215 int braces = 0;
7216
7217 var_beg = line + 1;
7218 var_end = var_beg;
7219
7220 if (*var_beg == '{') {
7221 var_beg++;
7222 var_end++;
7223 braces = 1;
7224 }
7225
7226 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007227 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 +02007228 err_code |= ERR_ALERT | ERR_FATAL;
7229 goto next_line; /* skip current line */
7230 }
7231
7232 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7233 var_end++;
7234
7235 save_char = *var_end;
7236 *var_end = '\0';
7237 value = getenv(var_beg);
7238 *var_end = save_char;
7239 val_len = value ? strlen(value) : 0;
7240
7241 if (braces) {
7242 if (*var_end == '}') {
7243 var_end++;
7244 braces = 0;
7245 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007246 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007247 err_code |= ERR_ALERT | ERR_FATAL;
7248 goto next_line; /* skip current line */
7249 }
7250 }
7251
7252 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7253
7254 /* if not enough space in thisline */
7255 if (newlinesize > linesize) {
7256 char *newline;
7257
7258 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7259 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007260 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007261 err_code |= ERR_ALERT | ERR_FATAL;
7262 goto next_line; /* slip current line */
7263 }
7264 /* recompute pointers if realloc returns a new pointer */
7265 if (newline != thisline) {
7266 int i;
7267 int diff;
7268
7269 for (i = 0; i <= arg; i++) {
7270 diff = args[i] - thisline;
7271 args[i] = newline + diff;
7272 }
7273
7274 diff = var_end - thisline;
7275 var_end = newline + diff;
7276 diff = end - thisline;
7277 end = newline + diff;
7278 diff = line - thisline;
7279 line = newline + diff;
7280 thisline = newline;
7281 }
7282 linesize = newlinesize;
7283 }
7284
7285 /* insert value inside the line */
7286 memmove(line + val_len, var_end, end - var_end + 1);
7287 memcpy(line, value, val_len);
7288 end += val_len - (var_end - line);
7289 line += val_len;
7290 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007291 else {
7292 line++;
7293 }
7294 }
William Lallemandb2f07452015-05-12 14:27:13 +02007295
William Lallemandf9873ba2015-05-05 17:37:14 +02007296 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007297 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007298 err_code |= ERR_ALERT | ERR_FATAL;
7299 }
7300
7301 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007302 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007303 err_code |= ERR_ALERT | ERR_FATAL;
7304 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007305
7306 /* empty line */
7307 if (!**args)
7308 continue;
7309
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007310 if (*line) {
7311 /* we had to stop due to too many args.
7312 * Let's terminate the string, print the offending part then cut the
7313 * last arg.
7314 */
7315 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7316 line++;
7317 *line = '\0';
7318
Christopher Faulet767a84b2017-11-24 16:50:31 +01007319 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7320 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007321 err_code |= ERR_ALERT | ERR_FATAL;
7322 args[arg] = line;
7323 }
7324
Willy Tarreau540abe42007-05-02 20:50:16 +02007325 /* zero out remaining args and ensure that at least one entry
7326 * is zeroed out.
7327 */
7328 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007329 args[arg] = line;
7330 }
7331
Willy Tarreau3842f002009-06-14 11:39:52 +02007332 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007333 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007334 char *tmp;
7335
Willy Tarreau3842f002009-06-14 11:39:52 +02007336 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007337 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007338 for (arg=0; *args[arg+1]; arg++)
7339 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007340 *tmp = '\0'; // fix the next arg to \0
7341 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007342 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007343 else if (!strcmp(args[0], "default")) {
7344 kwm = KWM_DEF;
7345 for (arg=0; *args[arg+1]; arg++)
7346 args[arg] = args[arg+1]; // shift args after inversion
7347 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007348
William Lallemand0f99e342011-10-12 17:50:54 +02007349 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7350 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007351 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007352 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007353 }
7354
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007355 /* detect section start */
7356 list_for_each_entry(ics, &sections, list) {
7357 if (strcmp(args[0], ics->section_name) == 0) {
7358 cursection = ics->section_name;
7359 cs = ics;
7360 break;
7361 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007362 }
7363
William Lallemandd2ff56d2017-10-16 11:06:50 +02007364 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007365 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007366 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007367 } else {
7368 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007369
William Lallemandd2ff56d2017-10-16 11:06:50 +02007370 if (pcs != cs && pcs && pcs->post_section_parser) {
7371 err_code |= pcs->post_section_parser();
7372 if (err_code & ERR_ABORT)
7373 goto err;
7374 }
7375
7376 err_code |= cs->section_parser(file, linenum, args, kwm);
7377 if (err_code & ERR_ABORT)
7378 goto err;
7379 }
7380 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007381 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007382
7383 if (pcs == cs && pcs && pcs->post_section_parser)
7384 err_code |= pcs->post_section_parser();
7385
7386err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007387 free(cfg_scope);
7388 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007389 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007390 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007391 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007392 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007393}
7394
Willy Tarreau64ab6072014-09-16 12:17:36 +02007395/* This function propagates processes from frontend <from> to backend <to> so
7396 * that it is always guaranteed that a backend pointed to by a frontend is
7397 * bound to all of its processes. After that, if the target is a "listen"
7398 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007399 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007400 * checked first to ensure that <to> is already bound to all processes of
7401 * <from>, there is no risk of looping and we ensure to follow the shortest
7402 * path to the destination.
7403 *
7404 * It is possible to set <to> to NULL for the first call so that the function
7405 * takes care of visiting the initial frontend in <from>.
7406 *
7407 * It is important to note that the function relies on the fact that all names
7408 * have already been resolved.
7409 */
7410void propagate_processes(struct proxy *from, struct proxy *to)
7411{
7412 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007413
7414 if (to) {
7415 /* check whether we need to go down */
7416 if (from->bind_proc &&
7417 (from->bind_proc & to->bind_proc) == from->bind_proc)
7418 return;
7419
7420 if (!from->bind_proc && !to->bind_proc)
7421 return;
7422
7423 to->bind_proc = from->bind_proc ?
7424 (to->bind_proc | from->bind_proc) : 0;
7425
7426 /* now propagate down */
7427 from = to;
7428 }
7429
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007430 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007431 return;
7432
Willy Tarreauf6b70012014-12-18 14:00:43 +01007433 if (from->state == PR_STSTOPPED)
7434 return;
7435
Willy Tarreau64ab6072014-09-16 12:17:36 +02007436 /* default_backend */
7437 if (from->defbe.be)
7438 propagate_processes(from, from->defbe.be);
7439
7440 /* use_backend */
7441 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007442 if (rule->dynamic)
7443 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007444 to = rule->be.backend;
7445 propagate_processes(from, to);
7446 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007447}
7448
Willy Tarreaubb925012009-07-23 13:36:36 +02007449/*
7450 * Returns the error code, 0 if OK, or any combination of :
7451 * - ERR_ABORT: must abort ASAP
7452 * - ERR_FATAL: we can continue parsing but not start the service
7453 * - ERR_WARN: a warning has been emitted
7454 * - ERR_ALERT: an alert has been emitted
7455 * Only the two first ones can stop processing, the two others are just
7456 * indicators.
7457 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007458int check_config_validity()
7459{
7460 int cfgerr = 0;
7461 struct proxy *curproxy = NULL;
7462 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007463 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007464 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007465 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007466 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007467 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06007468 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007469
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007470 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007471 /*
7472 * Now, check for the integrity of all that we have collected.
7473 */
7474
7475 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007476 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007477
Willy Tarreau193b8c62012-11-22 00:17:38 +01007478 if (!global.tune.max_http_hdr)
7479 global.tune.max_http_hdr = MAX_HTTP_HDR;
7480
7481 if (!global.tune.cookie_len)
7482 global.tune.cookie_len = CAPTURE_LEN;
7483
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007484 if (!global.tune.requri_len)
7485 global.tune.requri_len = REQURI_LEN;
7486
Willy Tarreaubafbe012017-11-24 17:34:44 +01007487 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007488
Willy Tarreaubafbe012017-11-24 17:34:44 +01007489 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007490
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007491 /* Post initialisation of the users and groups lists. */
7492 err_code = userlist_postinit();
7493 if (err_code != ERR_NONE)
7494 goto out;
7495
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007496 /* first, we will invert the proxy list order */
7497 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007498 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007499 struct proxy *next;
7500
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007501 next = proxies_list->next;
7502 proxies_list->next = curproxy;
7503 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007504 if (!next)
7505 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007506 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007507 }
7508
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007509 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007510 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007511 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007512 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007513 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007514 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007515 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007516 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007517
Willy Tarreau050536d2012-10-04 08:47:34 +02007518 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007519 /* proxy ID not set, use automatic numbering with first
7520 * spare entry starting with next_pxid.
7521 */
7522 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7523 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7524 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007525 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007526 next_pxid++;
7527
Willy Tarreau55ea7572007-06-17 19:56:27 +02007528
Willy Tarreaubaaee002006-06-26 02:48:02 +02007529 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007530 /* ensure we don't keep listeners uselessly bound */
7531 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007532 free((void *)curproxy->table.peers.name);
7533 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007534 continue;
7535 }
7536
Willy Tarreau102df612014-05-07 23:56:38 +02007537 /* Check multi-process mode compatibility for the current proxy */
7538
7539 if (curproxy->bind_proc) {
7540 /* an explicit bind-process was specified, let's check how many
7541 * processes remain.
7542 */
David Carliere6c39412015-07-02 07:00:17 +00007543 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007544
7545 curproxy->bind_proc &= nbits(global.nbproc);
7546 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007547 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 +02007548 curproxy->bind_proc = 1;
7549 }
7550 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007551 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 +02007552 curproxy->bind_proc = 0;
7553 }
7554 }
7555
Willy Tarreau3d209582014-05-09 17:06:11 +02007556 /* check and reduce the bind-proc of each listener */
7557 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7558 unsigned long mask;
7559
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007560 /* HTTP frontends with "h2" as ALPN/NPN will work in
7561 * HTTP/2 and absolutely require buffers 16kB or larger.
7562 */
7563#ifdef USE_OPENSSL
7564 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7565#ifdef OPENSSL_NPN_NEGOTIATED
7566 /* check NPN */
7567 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007568 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",
7569 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007570 cfgerr++;
7571 }
7572#endif
7573#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7574 /* check ALPN */
7575 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007576 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",
7577 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007578 cfgerr++;
7579 }
7580#endif
7581 } /* HTTP && bufsize < 16384 */
7582#endif
7583
Willy Tarreau3d209582014-05-09 17:06:11 +02007584 if (!bind_conf->bind_proc)
7585 continue;
7586
7587 mask = nbits(global.nbproc);
7588 if (curproxy->bind_proc)
7589 mask &= curproxy->bind_proc;
7590 /* mask cannot be null here thanks to the previous checks */
7591
David Carliere6c39412015-07-02 07:00:17 +00007592 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007593 bind_conf->bind_proc &= mask;
7594
7595 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007596 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",
7597 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007598 bind_conf->bind_proc = mask & ~(mask - 1);
7599 }
7600 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007601 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",
7602 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007603 bind_conf->bind_proc = 0;
7604 }
7605 }
7606
Willy Tarreauff01a212009-03-15 13:46:16 +01007607 switch (curproxy->mode) {
7608 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007609 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007610 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007611 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7612 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007613 cfgerr++;
7614 }
7615
7616 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007617 ha_warning("config : servers will be ignored for %s '%s'.\n",
7618 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007619 break;
7620
7621 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007622 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007623 break;
7624
7625 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007626 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007627 break;
7628 }
7629
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007630 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007631 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7632 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007633 err_code |= ERR_WARN;
7634 }
7635
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007636 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007637 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007638 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007639 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7640 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007641 cfgerr++;
7642 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007643#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007644 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007645 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7646 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007647 cfgerr++;
7648 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007649#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007650 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007651 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7652 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007653 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007654 }
7655 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007656 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007657 /* If no LB algo is set in a backend, and we're not in
7658 * transparent mode, dispatch mode nor proxy mode, we
7659 * want to use balance roundrobin by default.
7660 */
7661 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7662 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007663 }
7664 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007665
Willy Tarreau1620ec32011-08-06 17:05:02 +02007666 if (curproxy->options & PR_O_DISPATCH)
7667 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7668 else if (curproxy->options & PR_O_HTTP_PROXY)
7669 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7670 else if (curproxy->options & PR_O_TRANSP)
7671 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007672
Willy Tarreau1620ec32011-08-06 17:05:02 +02007673 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7674 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007675 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7676 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007677 err_code |= ERR_WARN;
7678 curproxy->options &= ~PR_O_DISABLE404;
7679 }
7680 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007681 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7682 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007683 err_code |= ERR_WARN;
7684 curproxy->options &= ~PR_O2_CHK_SNDST;
7685 }
Willy Tarreauef781042010-01-27 11:53:01 +01007686 }
7687
Simon Horman98637e52014-06-20 12:30:16 +09007688 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7689 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007690 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7691 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007692 cfgerr++;
7693 }
7694 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007695 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7696 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007697 cfgerr++;
7698 }
7699 }
7700
Simon Horman64e34162015-02-06 11:11:57 +09007701 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007702 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007703 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7704 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7705 "'email-alert myhostname', or 'email-alert to' "
7706 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7707 "to be present).\n",
7708 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007709 err_code |= ERR_WARN;
7710 free_email_alert(curproxy);
7711 }
7712 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007713 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007714 }
7715
Simon Horman98637e52014-06-20 12:30:16 +09007716 if (curproxy->check_command) {
7717 int clear = 0;
7718 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007719 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7720 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007721 err_code |= ERR_WARN;
7722 clear = 1;
7723 }
7724 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007725 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7726 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007727 cfgerr++;
7728 }
7729 if (clear) {
7730 free(curproxy->check_command);
7731 curproxy->check_command = NULL;
7732 }
7733 }
7734
7735 if (curproxy->check_path) {
7736 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007737 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7738 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007739 err_code |= ERR_WARN;
7740 free(curproxy->check_path);
7741 curproxy->check_path = NULL;
7742 }
7743 }
7744
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007745 /* if a default backend was specified, let's find it */
7746 if (curproxy->defbe.name) {
7747 struct proxy *target;
7748
Willy Tarreauafb39922015-05-26 12:04:09 +02007749 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007750 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007751 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7752 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007753 cfgerr++;
7754 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007755 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7756 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007757 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007758 } else if (target->mode != curproxy->mode &&
7759 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7760
Christopher Faulet767a84b2017-11-24 16:50:31 +01007761 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7762 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7763 curproxy->conf.file, curproxy->conf.line,
7764 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7765 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007766 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007767 } else {
7768 free(curproxy->defbe.name);
7769 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007770 /* Update tot_fe_maxconn for a further fullconn's computation */
7771 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007772 /* Emit a warning if this proxy also has some servers */
7773 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007774 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7775 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007776 err_code |= ERR_WARN;
7777 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007778 }
7779 }
7780
Emeric Brun3f783572017-01-12 11:21:28 +01007781 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7782 /* Case of listen without default backend
7783 * The curproxy will be its own default backend
7784 * so we update tot_fe_maxconn for a further
7785 * fullconn's computation */
7786 curproxy->tot_fe_maxconn += curproxy->maxconn;
7787 }
7788
Willy Tarreau55ea7572007-06-17 19:56:27 +02007789 /* find the target proxy for 'use_backend' rules */
7790 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007791 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007792 struct logformat_node *node;
7793 char *pxname;
7794
7795 /* Try to parse the string as a log format expression. If the result
7796 * of the parsing is only one entry containing a simple string, then
7797 * it's a standard string corresponding to a static rule, thus the
7798 * parsing is cancelled and be.name is restored to be resolved.
7799 */
7800 pxname = rule->be.name;
7801 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007802 curproxy->conf.args.ctx = ARGC_UBK;
7803 curproxy->conf.args.file = rule->file;
7804 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007805 err = NULL;
7806 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007807 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7808 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007809 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007810 cfgerr++;
7811 continue;
7812 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007813 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7814
7815 if (!LIST_ISEMPTY(&rule->be.expr)) {
7816 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7817 rule->dynamic = 1;
7818 free(pxname);
7819 continue;
7820 }
7821 /* simple string: free the expression and fall back to static rule */
7822 free(node->arg);
7823 free(node);
7824 }
7825
7826 rule->dynamic = 0;
7827 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007828
Willy Tarreauafb39922015-05-26 12:04:09 +02007829 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007830 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007831 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7832 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007833 cfgerr++;
7834 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007835 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7836 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007837 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007838 } else if (target->mode != curproxy->mode &&
7839 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7840
Christopher Faulet767a84b2017-11-24 16:50:31 +01007841 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7842 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7843 curproxy->conf.file, curproxy->conf.line,
7844 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7845 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007846 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007847 } else {
7848 free((void *)rule->be.name);
7849 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007850 /* For each target of switching rules, we update
7851 * their tot_fe_maxconn, except if a previous rule point
7852 * on the same backend or on the default backend */
7853 if (rule->be.backend != curproxy->defbe.be) {
7854 struct switching_rule *swrule;
7855
7856 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7857 if (rule == swrule) {
7858 target->tot_fe_maxconn += curproxy->maxconn;
7859 break;
7860 }
7861 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7862 /* there is multiple ref of this backend */
7863 break;
7864 }
7865 }
7866 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007867 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007868 }
7869
Willy Tarreau64ab6072014-09-16 12:17:36 +02007870 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007871 list_for_each_entry(srule, &curproxy->server_rules, list) {
7872 struct server *target = findserver(curproxy, srule->srv.name);
7873
7874 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007875 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7876 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007877 cfgerr++;
7878 continue;
7879 }
7880 free((void *)srule->srv.name);
7881 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007882 }
7883
Emeric Brunb982a3d2010-01-04 15:45:53 +01007884 /* find the target table for 'stick' rules */
7885 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7886 struct proxy *target;
7887
Emeric Brun1d33b292010-01-04 15:47:17 +01007888 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7889 if (mrule->flags & STK_IS_STORE)
7890 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7891
Emeric Brunb982a3d2010-01-04 15:45:53 +01007892 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007893 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007894 else
7895 target = curproxy;
7896
7897 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007898 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7899 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007900 cfgerr++;
7901 }
7902 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007903 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7904 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007905 cfgerr++;
7906 }
Willy Tarreau12785782012-04-27 21:37:17 +02007907 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007908 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7909 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007910 cfgerr++;
7911 }
7912 else {
7913 free((void *)mrule->table.name);
7914 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007915 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007916 }
7917 }
7918
7919 /* find the target table for 'store response' rules */
7920 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7921 struct proxy *target;
7922
Emeric Brun1d33b292010-01-04 15:47:17 +01007923 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7924
Emeric Brunb982a3d2010-01-04 15:45:53 +01007925 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007926 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007927 else
7928 target = curproxy;
7929
7930 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007931 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7932 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007933 cfgerr++;
7934 }
7935 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007936 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7937 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007938 cfgerr++;
7939 }
Willy Tarreau12785782012-04-27 21:37:17 +02007940 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007941 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7942 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007943 cfgerr++;
7944 }
7945 else {
7946 free((void *)mrule->table.name);
7947 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007948 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007949 }
7950 }
7951
Christopher Faulete4e830d2017-09-18 14:51:41 +02007952 /* check validity for 'tcp-request' layer 4 rules */
7953 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
7954 err = NULL;
7955 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007956 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007957 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01007958 cfgerr++;
7959 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02007960 }
7961
Christopher Faulete4e830d2017-09-18 14:51:41 +02007962 /* check validity for 'tcp-request' layer 5 rules */
7963 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
7964 err = NULL;
7965 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007966 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007967 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007968 cfgerr++;
7969 }
7970 }
7971
Christopher Faulete4e830d2017-09-18 14:51:41 +02007972 /* check validity for 'tcp-request' layer 6 rules */
7973 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
7974 err = NULL;
7975 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007976 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007977 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007978 cfgerr++;
7979 }
7980 }
7981
Christopher Faulete4e830d2017-09-18 14:51:41 +02007982 /* check validity for 'http-request' layer 7 rules */
7983 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
7984 err = NULL;
7985 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007986 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007987 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007988 cfgerr++;
7989 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007990 }
7991
Christopher Faulete4e830d2017-09-18 14:51:41 +02007992 /* check validity for 'http-response' layer 7 rules */
7993 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
7994 err = NULL;
7995 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007996 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007997 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02007998 cfgerr++;
7999 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008000 }
8001
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008002 /* move any "block" rules at the beginning of the http-request rules */
8003 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8004 /* insert block_rules into http_req_rules at the beginning */
8005 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8006 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8007 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8008 curproxy->http_req_rules.n = curproxy->block_rules.n;
8009 LIST_INIT(&curproxy->block_rules);
8010 }
8011
Emeric Brun32da3c42010-09-23 18:39:19 +02008012 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008013 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008014
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008015 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008016 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8017 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008018 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008019 break;
8020 }
8021 }
8022
8023 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008024 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8025 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008026 free((void *)curproxy->table.peers.name);
8027 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008028 cfgerr++;
8029 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008030 else if (curpeers->state == PR_STSTOPPED) {
8031 /* silently disable this peers section */
8032 curproxy->table.peers.p = NULL;
8033 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008034 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008035 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8036 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008037 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008038 cfgerr++;
8039 }
8040 }
8041
Simon Horman9dc49962015-01-30 11:22:59 +09008042
8043 if (curproxy->email_alert.mailers.name) {
8044 struct mailers *curmailers = mailers;
8045
8046 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008047 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008048 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008049 }
Simon Horman9dc49962015-01-30 11:22:59 +09008050 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008051 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8052 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008053 free_email_alert(curproxy);
8054 cfgerr++;
8055 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008056 else {
8057 err = NULL;
8058 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008059 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008060 free(err);
8061 cfgerr++;
8062 }
8063 }
Simon Horman9dc49962015-01-30 11:22:59 +09008064 }
8065
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008066 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008067 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008068 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008069 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8070 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008071 cfgerr++;
8072 goto out_uri_auth_compat;
8073 }
8074
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008075 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008076 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008077 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008078 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008079
Willy Tarreau95fa4692010-02-01 13:05:50 +01008080 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8081 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008082
8083 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008084 uri_auth_compat_req[i++] = "realm";
8085 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8086 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008087
Willy Tarreau95fa4692010-02-01 13:05:50 +01008088 uri_auth_compat_req[i++] = "unless";
8089 uri_auth_compat_req[i++] = "{";
8090 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8091 uri_auth_compat_req[i++] = "}";
8092 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008093
Willy Tarreauff011f22011-01-06 17:51:27 +01008094 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8095 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008096 cfgerr++;
8097 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008098 }
8099
Willy Tarreauff011f22011-01-06 17:51:27 +01008100 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008101
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008102 if (curproxy->uri_auth->auth_realm) {
8103 free(curproxy->uri_auth->auth_realm);
8104 curproxy->uri_auth->auth_realm = NULL;
8105 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008106
8107 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008108 }
8109out_uri_auth_compat:
8110
Dragan Dosen43885c72015-10-01 13:18:13 +02008111 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008112 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008113 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8114 if (!curproxy->conf.logformat_sd_string) {
8115 /* set the default logformat_sd_string */
8116 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8117 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008118 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008119 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008120 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008121
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008122 /* compile the log format */
8123 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008124 if (curproxy->conf.logformat_string != default_http_log_format &&
8125 curproxy->conf.logformat_string != default_tcp_log_format &&
8126 curproxy->conf.logformat_string != clf_http_log_format)
8127 free(curproxy->conf.logformat_string);
8128 curproxy->conf.logformat_string = NULL;
8129 free(curproxy->conf.lfs_file);
8130 curproxy->conf.lfs_file = NULL;
8131 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008132
8133 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8134 free(curproxy->conf.logformat_sd_string);
8135 curproxy->conf.logformat_sd_string = NULL;
8136 free(curproxy->conf.lfsd_file);
8137 curproxy->conf.lfsd_file = NULL;
8138 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008139 }
8140
Willy Tarreau62a61232013-04-12 18:13:46 +02008141 if (curproxy->conf.logformat_string) {
8142 curproxy->conf.args.ctx = ARGC_LOG;
8143 curproxy->conf.args.file = curproxy->conf.lfs_file;
8144 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008145 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008146 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008147 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008148 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8149 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008150 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008151 cfgerr++;
8152 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008153 curproxy->conf.args.file = NULL;
8154 curproxy->conf.args.line = 0;
8155 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008156
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008157 if (curproxy->conf.logformat_sd_string) {
8158 curproxy->conf.args.ctx = ARGC_LOGSD;
8159 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8160 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008161 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008162 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 +01008163 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008164 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8165 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008166 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008167 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008168 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008169 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8170 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008171 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008172 cfgerr++;
8173 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008174 curproxy->conf.args.file = NULL;
8175 curproxy->conf.args.line = 0;
8176 }
8177
Willy Tarreau62a61232013-04-12 18:13:46 +02008178 if (curproxy->conf.uniqueid_format_string) {
8179 curproxy->conf.args.ctx = ARGC_UIF;
8180 curproxy->conf.args.file = curproxy->conf.uif_file;
8181 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008182 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008183 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 +01008184 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008185 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8186 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008187 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008188 cfgerr++;
8189 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008190 curproxy->conf.args.file = NULL;
8191 curproxy->conf.args.line = 0;
8192 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008193
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008194 /* only now we can check if some args remain unresolved.
8195 * This must be done after the users and groups resolution.
8196 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008197 cfgerr += smp_resolve_args(curproxy);
8198 if (!cfgerr)
8199 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008200
Willy Tarreau2738a142006-07-08 17:28:09 +02008201 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008202 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008203 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008204 (!curproxy->timeout.connect ||
8205 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008206 ha_warning("config : missing timeouts for %s '%s'.\n"
8207 " | While not properly invalid, you will certainly encounter various problems\n"
8208 " | with such a configuration. To fix this, please ensure that all following\n"
8209 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8210 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008211 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008212 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008213
Willy Tarreau1fa31262007-12-03 00:36:16 +01008214 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8215 * We must still support older configurations, so let's find out whether those
8216 * parameters have been set or must be copied from contimeouts.
8217 */
8218 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008219 if (!curproxy->timeout.tarpit ||
8220 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008221 /* tarpit timeout not set. We search in the following order:
8222 * default.tarpit, curr.connect, default.connect.
8223 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008224 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008225 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008226 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008227 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008228 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008229 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008230 }
8231 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008232 (!curproxy->timeout.queue ||
8233 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008234 /* queue timeout not set. We search in the following order:
8235 * default.queue, curr.connect, default.connect.
8236 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008237 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008238 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008239 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008240 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008241 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008242 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008243 }
8244 }
8245
Willy Tarreau1620ec32011-08-06 17:05:02 +02008246 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008247 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008248 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008249 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008250 }
8251
Willy Tarreau215663d2014-06-13 18:30:23 +02008252 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8253 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008254 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8255 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008256 err_code |= ERR_WARN;
8257 }
8258
Willy Tarreau193b8c62012-11-22 00:17:38 +01008259 /* ensure that cookie capture length is not too large */
8260 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008261 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8262 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008263 err_code |= ERR_WARN;
8264 curproxy->capture_len = global.tune.cookie_len - 1;
8265 }
8266
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008267 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008268 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008269 curproxy->req_cap_pool = create_pool("ptrcap",
8270 curproxy->nb_req_cap * sizeof(char *),
8271 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008272 }
8273
8274 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008275 curproxy->rsp_cap_pool = create_pool("ptrcap",
8276 curproxy->nb_rsp_cap * sizeof(char *),
8277 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008278 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008279
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008280 switch (curproxy->load_server_state_from_file) {
8281 case PR_SRV_STATE_FILE_UNSPEC:
8282 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8283 break;
8284 case PR_SRV_STATE_FILE_GLOBAL:
8285 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008286 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",
8287 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008288 err_code |= ERR_WARN;
8289 }
8290 break;
8291 }
8292
Willy Tarreaubaaee002006-06-26 02:48:02 +02008293 /* first, we will invert the servers list order */
8294 newsrv = NULL;
8295 while (curproxy->srv) {
8296 struct server *next;
8297
8298 next = curproxy->srv->next;
8299 curproxy->srv->next = newsrv;
8300 newsrv = curproxy->srv;
8301 if (!next)
8302 break;
8303 curproxy->srv = next;
8304 }
8305
Willy Tarreau17edc812014-01-03 12:14:34 +01008306 /* Check that no server name conflicts. This causes trouble in the stats.
8307 * We only emit a warning for the first conflict affecting each server,
8308 * in order to avoid combinatory explosion if all servers have the same
8309 * name. We do that only for servers which do not have an explicit ID,
8310 * because these IDs were made also for distinguishing them and we don't
8311 * want to annoy people who correctly manage them.
8312 */
8313 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8314 struct server *other_srv;
8315
8316 if (newsrv->puid)
8317 continue;
8318
8319 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8320 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008321 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",
8322 newsrv->conf.file, newsrv->conf.line,
8323 proxy_type_str(curproxy), curproxy->id,
8324 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008325 break;
8326 }
8327 }
8328 }
8329
Willy Tarreaudd701652010-05-25 23:03:02 +02008330 /* assign automatic UIDs to servers which don't have one yet */
8331 next_id = 1;
8332 newsrv = curproxy->srv;
8333 while (newsrv != NULL) {
8334 if (!newsrv->puid) {
8335 /* server ID not set, use automatic numbering with first
8336 * spare entry starting with next_svid.
8337 */
8338 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8339 newsrv->conf.id.key = newsrv->puid = next_id;
8340 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8341 }
8342 next_id++;
8343 newsrv = newsrv->next;
8344 }
8345
Willy Tarreau20697042007-11-15 23:26:18 +01008346 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008347 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008348
Willy Tarreau62c3be22012-01-20 13:12:32 +01008349 /*
8350 * If this server supports a maxconn parameter, it needs a dedicated
8351 * tasks to fill the emptied slots when a connection leaves.
8352 * Also, resolve deferred tracking dependency if needed.
8353 */
8354 newsrv = curproxy->srv;
8355 while (newsrv != NULL) {
8356 if (newsrv->minconn > newsrv->maxconn) {
8357 /* Only 'minconn' was specified, or it was higher than or equal
8358 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8359 * this will avoid further useless expensive computations.
8360 */
8361 newsrv->maxconn = newsrv->minconn;
8362 } else if (newsrv->maxconn && !newsrv->minconn) {
8363 /* minconn was not specified, so we set it to maxconn */
8364 newsrv->minconn = newsrv->maxconn;
8365 }
8366
Willy Tarreau17d45382016-12-22 21:16:08 +01008367 /* this will also properly set the transport layer for prod and checks */
8368 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8369 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8370 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8371 }
Emeric Brun94324a42012-10-11 14:00:19 +02008372
Willy Tarreau2f075e92013-12-03 11:11:34 +01008373 /* set the check type on the server */
8374 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8375
Willy Tarreau62c3be22012-01-20 13:12:32 +01008376 if (newsrv->trackit) {
8377 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008378 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008379 char *pname, *sname;
8380
8381 pname = newsrv->trackit;
8382 sname = strrchr(pname, '/');
8383
8384 if (sname)
8385 *sname++ = '\0';
8386 else {
8387 sname = pname;
8388 pname = NULL;
8389 }
8390
8391 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008392 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008393 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008394 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8395 proxy_type_str(curproxy), curproxy->id,
8396 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008397 cfgerr++;
8398 goto next_srv;
8399 }
8400 } else
8401 px = curproxy;
8402
8403 srv = findserver(px, sname);
8404 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008405 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8406 proxy_type_str(curproxy), curproxy->id,
8407 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008408 cfgerr++;
8409 goto next_srv;
8410 }
8411
Willy Tarreau32091232014-05-16 13:52:00 +02008412 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8413 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8414 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008415 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8416 "tracking as it does not have any check nor agent enabled.\n",
8417 proxy_type_str(curproxy), curproxy->id,
8418 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008419 cfgerr++;
8420 goto next_srv;
8421 }
8422
8423 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8424
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008425 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008426 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8427 "belongs to a tracking chain looping back to %s/%s.\n",
8428 proxy_type_str(curproxy), curproxy->id,
8429 newsrv->id, px->id, srv->id, px->id,
8430 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008431 cfgerr++;
8432 goto next_srv;
8433 }
8434
8435 if (curproxy != px &&
8436 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008437 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8438 "tracking: disable-on-404 option inconsistency.\n",
8439 proxy_type_str(curproxy), curproxy->id,
8440 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008441 cfgerr++;
8442 goto next_srv;
8443 }
8444
Willy Tarreau62c3be22012-01-20 13:12:32 +01008445 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008446 newsrv->tracknext = srv->trackers;
8447 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008448
8449 free(newsrv->trackit);
8450 newsrv->trackit = NULL;
8451 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008452
Willy Tarreau62c3be22012-01-20 13:12:32 +01008453 next_srv:
8454 newsrv = newsrv->next;
8455 }
8456
Olivier Houchard4e694042017-03-14 20:01:29 +01008457 /*
8458 * Try to generate dynamic cookies for servers now.
8459 * It couldn't be done earlier, since at the time we parsed
8460 * the server line, we may not have known yet that we
8461 * should use dynamic cookies, or the secret key may not
8462 * have been provided yet.
8463 */
8464 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8465 newsrv = curproxy->srv;
8466 while (newsrv != NULL) {
8467 srv_set_dyncookie(newsrv);
8468 newsrv = newsrv->next;
8469 }
8470
8471 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008472 /* We have to initialize the server lookup mechanism depending
8473 * on what LB algorithm was choosen.
8474 */
8475
8476 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8477 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8478 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008479 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8480 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8481 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02008482 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
8483 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8484 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02008485 } else {
8486 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8487 fwrr_init_server_groups(curproxy);
8488 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008489 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008490
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008491 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008492 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8493 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8494 fwlc_init_server_tree(curproxy);
8495 } else {
8496 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8497 fas_init_server_tree(curproxy);
8498 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008499 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008500
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008501 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008502 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8503 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8504 chash_init_server_tree(curproxy);
8505 } else {
8506 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8507 init_server_map(curproxy);
8508 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008509 break;
8510 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008511 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008512
8513 if (curproxy->options & PR_O_LOGASAP)
8514 curproxy->to_log &= ~LW_BYTES;
8515
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008516 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008517 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8518 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008519 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8520 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008521 err_code |= ERR_WARN;
8522 }
8523
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008524 if (curproxy->mode != PR_MODE_HTTP) {
8525 int optnum;
8526
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008527 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008528 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8529 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008530 err_code |= ERR_WARN;
8531 curproxy->uri_auth = NULL;
8532 }
8533
Willy Tarreaude7dc882017-03-10 11:49:21 +01008534 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008535 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8536 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008537 err_code |= ERR_WARN;
8538 }
8539
8540 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008541 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8542 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008543 err_code |= ERR_WARN;
8544 }
8545
8546 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008547 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8548 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008549 err_code |= ERR_WARN;
8550 }
8551
8552 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008553 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8554 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008555 err_code |= ERR_WARN;
8556 }
8557
8558 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008559 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8560 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008561 err_code |= ERR_WARN;
8562 }
8563
Willy Tarreau87cf5142011-08-19 22:57:24 +02008564 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008565 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8566 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008567 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008568 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008569 }
8570
8571 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008572 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8573 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008574 err_code |= ERR_WARN;
8575 curproxy->options &= ~PR_O_ORGTO;
8576 }
8577
8578 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8579 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8580 (curproxy->cap & cfg_opts[optnum].cap) &&
8581 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008582 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8583 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008584 err_code |= ERR_WARN;
8585 curproxy->options &= ~cfg_opts[optnum].val;
8586 }
8587 }
8588
8589 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8590 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8591 (curproxy->cap & cfg_opts2[optnum].cap) &&
8592 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008593 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8594 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008595 err_code |= ERR_WARN;
8596 curproxy->options2 &= ~cfg_opts2[optnum].val;
8597 }
8598 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008599
Willy Tarreau29fbe512015-08-20 19:35:14 +02008600#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008601 if (curproxy->conn_src.bind_hdr_occ) {
8602 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008603 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8604 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008605 err_code |= ERR_WARN;
8606 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008607#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008608 }
8609
Willy Tarreaubaaee002006-06-26 02:48:02 +02008610 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008611 * ensure that we're not cross-dressing a TCP server into HTTP.
8612 */
8613 newsrv = curproxy->srv;
8614 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008615 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008616 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8617 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008618 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008619 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008620
Willy Tarreau0cec3312011-10-31 13:49:26 +01008621 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008622 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8623 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008624 err_code |= ERR_WARN;
8625 }
8626
Willy Tarreauc93cd162014-05-13 15:54:22 +02008627 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008628 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8629 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008630 err_code |= ERR_WARN;
8631 }
8632
Willy Tarreau29fbe512015-08-20 19:35:14 +02008633#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008634 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8635 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008636 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8637 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008638 err_code |= ERR_WARN;
8639 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008640#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008641
Willy Tarreau46deab62018-04-28 07:18:15 +02008642 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
8643 curproxy->options &= ~PR_O_REUSE_MASK;
8644
Willy Tarreau4c183462017-01-06 12:21:38 +01008645 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8646 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8647 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8648 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8649 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008650 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",
8651 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008652 err_code |= ERR_WARN;
8653 }
8654
8655
8656 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008657 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",
8658 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008659 err_code |= ERR_WARN;
8660 }
8661 }
8662
Willy Tarreau21d2af32008-02-14 20:25:24 +01008663 newsrv = newsrv->next;
8664 }
8665
Willy Tarreaue42bd962014-09-16 16:21:19 +02008666 /* check if we have a frontend with "tcp-request content" looking at L7
8667 * with no inspect-delay
8668 */
8669 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008670 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8671 if (arule->action == ACT_TCP_CAPTURE &&
8672 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008673 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008674 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8675 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008676 break;
8677 }
8678
Christopher Faulete4e830d2017-09-18 14:51:41 +02008679 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008680 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8681 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8682 " This means that these rules will randomly find their contents. This can be fixed by"
8683 " setting the tcp-request inspect-delay.\n",
8684 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008685 err_code |= ERR_WARN;
8686 }
8687 }
8688
Christopher Fauletd7c91962015-04-30 11:48:27 +02008689 /* Check filter configuration, if any */
8690 cfgerr += flt_check(curproxy);
8691
Willy Tarreauc1a21672009-08-16 22:37:44 +02008692 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008693 if (!curproxy->accept)
8694 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008695
Willy Tarreauc1a21672009-08-16 22:37:44 +02008696 if (curproxy->tcp_req.inspect_delay ||
8697 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008698 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008699
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008700 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008701 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008702 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008703 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008704
8705 /* both TCP and HTTP must check switching rules */
8706 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008707
8708 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008709 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008710 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8711 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 +01008712 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008713 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8714 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008715 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008716 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008717 }
8718
8719 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008720 if (curproxy->tcp_req.inspect_delay ||
8721 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8722 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8723
Emeric Brun97679e72010-09-23 17:56:44 +02008724 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8725 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8726
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008727 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008728 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008729 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008730 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008731
8732 /* If the backend does requires RDP cookie persistence, we have to
8733 * enable the corresponding analyser.
8734 */
8735 if (curproxy->options2 & PR_O2_RDPC_PRST)
8736 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008737
8738 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008739 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008740 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8741 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 +01008742 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008743 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8744 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008745 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008746 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008747 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008748 }
8749
8750 /***********************************************************/
8751 /* At this point, target names have already been resolved. */
8752 /***********************************************************/
8753
8754 /* Check multi-process mode compatibility */
8755
8756 if (global.nbproc > 1 && global.stats_fe) {
8757 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8758 unsigned long mask;
8759
8760 mask = nbits(global.nbproc);
8761 if (global.stats_fe->bind_proc)
8762 mask &= global.stats_fe->bind_proc;
8763
8764 if (bind_conf->bind_proc)
8765 mask &= bind_conf->bind_proc;
8766
8767 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008768 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008769 break;
8770 }
8771 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008772 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 +02008773 }
8774 }
8775
8776 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008777 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008778 if (curproxy->bind_proc)
8779 continue;
8780
8781 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8782 unsigned long mask;
8783
Willy Tarreaue428b082015-05-04 21:57:58 +02008784 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008785 curproxy->bind_proc |= mask;
8786 }
8787
8788 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008789 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008790 }
8791
8792 if (global.stats_fe) {
8793 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8794 unsigned long mask;
8795
Cyril Bonté06181952016-02-24 00:14:54 +01008796 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008797 global.stats_fe->bind_proc |= mask;
8798 }
8799 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008800 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008801 }
8802
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008803 /* propagate bindings from frontends to backends. Don't do it if there
8804 * are any fatal errors as we must not call it with unresolved proxies.
8805 */
8806 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008807 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008808 if (curproxy->cap & PR_CAP_FE)
8809 propagate_processes(curproxy, NULL);
8810 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008811 }
8812
8813 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008814 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008815 if (curproxy->bind_proc)
8816 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008817 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008818 }
8819
8820 /*******************************************************/
8821 /* At this step, all proxies have a non-null bind_proc */
8822 /*******************************************************/
8823
8824 /* perform the final checks before creating tasks */
8825
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008826 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008827 struct listener *listener;
8828 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008829
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008830 /* Configure SSL for each bind line.
8831 * Note: if configuration fails at some point, the ->ctx member
8832 * remains NULL so that listeners can later detach.
8833 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008834 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008835 if (bind_conf->xprt->prepare_bind_conf &&
8836 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008837 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008838 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008839
Willy Tarreaue6b98942007-10-29 01:09:36 +01008840 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008841 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008842 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008843 int nbproc;
8844
8845 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008846 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008847 nbits(global.nbproc));
8848
8849 if (!nbproc) /* no intersection between listener and frontend */
8850 nbproc = 1;
8851
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008852 if (!listener->luid) {
8853 /* listener ID not set, use automatic numbering with first
8854 * spare entry starting with next_luid.
8855 */
8856 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8857 listener->conf.id.key = listener->luid = next_id;
8858 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008859 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008860 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008861
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008862 /* enable separate counters */
8863 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008864 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008865 if (!listener->name)
8866 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008867 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008868
Willy Tarreaue6b98942007-10-29 01:09:36 +01008869 if (curproxy->options & PR_O_TCP_NOLING)
8870 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008871 if (!listener->maxconn)
8872 listener->maxconn = curproxy->maxconn;
8873 if (!listener->backlog)
8874 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008875 if (!listener->maxaccept)
8876 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8877
8878 /* we want to have an optimal behaviour on single process mode to
8879 * maximize the work at once, but in multi-process we want to keep
8880 * some fairness between processes, so we target half of the max
8881 * number of events to be balanced over all the processes the proxy
8882 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8883 * used to disable the limit.
8884 */
8885 if (listener->maxaccept > 0) {
8886 if (nbproc > 1)
8887 listener->maxaccept = (listener->maxaccept + 1) / 2;
8888 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8889 }
8890
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008891 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008892 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008893 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008894
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008895 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008896 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008897
Willy Tarreau620408f2016-10-21 16:37:51 +02008898 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8899 listener->options |= LI_O_TCP_L5_RULES;
8900
Willy Tarreaude3041d2010-05-31 10:56:17 +02008901 if (curproxy->mon_mask.s_addr)
8902 listener->options |= LI_O_CHK_MONNET;
8903
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008904 /* smart accept mode is automatic in HTTP mode */
8905 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008906 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008907 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8908 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008909 }
8910
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008911 /* Release unused SSL configs */
8912 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008913 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8914 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008915 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008916
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008917 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008918 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008919 int count, maxproc = 0;
8920
8921 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008922 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008923 if (count > maxproc)
8924 maxproc = count;
8925 }
8926 /* backends have 0, frontends have 1 or more */
8927 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008928 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8929 " limited to process assigned to the current request.\n",
8930 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008931
Willy Tarreau102df612014-05-07 23:56:38 +02008932 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008933 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
8934 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008935 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008936 }
Willy Tarreau102df612014-05-07 23:56:38 +02008937 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008938 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
8939 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008940 }
8941 }
Willy Tarreau918ff602011-07-25 16:33:49 +02008942
8943 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02008944 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02008945 if (curproxy->task) {
8946 curproxy->task->context = curproxy;
8947 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02008948 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008949 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
8950 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02008951 cfgerr++;
8952 }
Willy Tarreaub369a042014-09-16 13:21:03 +02008953 }
8954
Willy Tarreaufbb78422011-06-05 15:38:35 +02008955 /* automatically compute fullconn if not set. We must not do it in the
8956 * loop above because cross-references are not yet fully resolved.
8957 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008958 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008959 /* If <fullconn> is not set, let's set it to 10% of the sum of
8960 * the possible incoming frontend's maxconns.
8961 */
8962 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008963 /* we have the sum of the maxconns in <total>. We only
8964 * keep 10% of that sum to set the default fullconn, with
8965 * a hard minimum of 1 (to avoid a divide by zero).
8966 */
Emeric Brun3f783572017-01-12 11:21:28 +01008967 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02008968 if (!curproxy->fullconn)
8969 curproxy->fullconn = 1;
8970 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01008971 }
8972
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008973 /*
8974 * Recount currently required checks.
8975 */
8976
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008977 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008978 int optnum;
8979
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008980 for (optnum = 0; cfg_opts[optnum].name; optnum++)
8981 if (curproxy->options & cfg_opts[optnum].val)
8982 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008983
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008984 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
8985 if (curproxy->options2 & cfg_opts2[optnum].val)
8986 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008987 }
8988
Willy Tarreau0fca4832015-05-01 19:12:05 +02008989 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008990 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02008991 if (curproxy->table.peers.p)
8992 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
8993
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008994 if (cfg_peers) {
8995 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02008996 struct peer *p, *pb;
8997
Willy Tarreau1e273012015-05-01 19:15:17 +02008998 /* Remove all peers sections which don't have a valid listener,
8999 * which are not used by any table, or which are bound to more
9000 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009001 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009002 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009003 while (*last) {
9004 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009005
9006 if (curpeers->state == PR_STSTOPPED) {
9007 /* the "disabled" keyword was present */
9008 if (curpeers->peers_fe)
9009 stop_proxy(curpeers->peers_fe);
9010 curpeers->peers_fe = NULL;
9011 }
9012 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009013 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9014 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009015 }
David Carliere6c39412015-07-02 07:00:17 +00009016 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009017 /* either it's totally stopped or too much used */
9018 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009019 ha_alert("Peers section '%s': peers referenced by sections "
9020 "running in different processes (%d different ones). "
9021 "Check global.nbproc and all tables' bind-process "
9022 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009023 cfgerr++;
9024 }
9025 stop_proxy(curpeers->peers_fe);
9026 curpeers->peers_fe = NULL;
9027 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009028 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009029 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009030 last = &curpeers->next;
9031 continue;
9032 }
9033
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009034 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009035 p = curpeers->remote;
9036 while (p) {
9037 pb = p->next;
9038 free(p->id);
9039 free(p);
9040 p = pb;
9041 }
9042
9043 /* Destroy and unlink this curpeers section.
9044 * Note: curpeers is backed up into *last.
9045 */
9046 free(curpeers->id);
9047 curpeers = curpeers->next;
9048 free(*last);
9049 *last = curpeers;
9050 }
9051 }
9052
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009053 /* initialize stick-tables on backend capable proxies. This must not
9054 * be done earlier because the data size may be discovered while parsing
9055 * other proxies.
9056 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009057 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009058 if (curproxy->state == PR_STSTOPPED)
9059 continue;
9060
9061 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009062 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009063 cfgerr++;
9064 }
9065 }
9066
Simon Horman0d16a402015-01-30 11:22:58 +09009067 if (mailers) {
9068 struct mailers *curmailers = mailers, **last;
9069 struct mailer *m, *mb;
9070
9071 /* Remove all mailers sections which don't have a valid listener.
9072 * This can happen when a mailers section is never referenced.
9073 */
9074 last = &mailers;
9075 while (*last) {
9076 curmailers = *last;
9077 if (curmailers->users) {
9078 last = &curmailers->next;
9079 continue;
9080 }
9081
Christopher Faulet767a84b2017-11-24 16:50:31 +01009082 ha_warning("Removing incomplete section 'mailers %s'.\n",
9083 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009084
9085 m = curmailers->mailer_list;
9086 while (m) {
9087 mb = m->next;
9088 free(m->id);
9089 free(m);
9090 m = mb;
9091 }
9092
9093 /* Destroy and unlink this curmailers section.
9094 * Note: curmailers is backed up into *last.
9095 */
9096 free(curmailers->id);
9097 curmailers = curmailers->next;
9098 free(*last);
9099 *last = curmailers;
9100 }
9101 }
9102
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009103 /* Update server_state_file_name to backend name if backend is supposed to use
9104 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009105 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009106 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9107 curproxy->server_state_file_name == NULL)
9108 curproxy->server_state_file_name = strdup(curproxy->id);
9109 }
9110
Willy Tarreaubafbe012017-11-24 17:34:44 +01009111 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009112 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009113 MEM_F_SHARED);
9114
Ben Draut054fbee2018-04-13 15:43:04 -06009115 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
9116 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
9117 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
9118 curr_resolvers->id, curr_resolvers->conf.file,
9119 curr_resolvers->conf.line);
9120 err_code |= ERR_WARN;
9121 }
9122 }
9123
William Lallemand48b4bb42017-10-23 14:36:34 +02009124 list_for_each_entry(postparser, &postparsers, list) {
9125 if (postparser->func)
9126 cfgerr += postparser->func();
9127 }
9128
Willy Tarreaubb925012009-07-23 13:36:36 +02009129 if (cfgerr > 0)
9130 err_code |= ERR_ALERT | ERR_FATAL;
9131 out:
9132 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009133}
9134
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009135/*
9136 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9137 * parsing sessions.
9138 */
9139void cfg_register_keywords(struct cfg_kw_list *kwl)
9140{
9141 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9142}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009143
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009144/*
9145 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9146 */
9147void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9148{
9149 LIST_DEL(&kwl->list);
9150 LIST_INIT(&kwl->list);
9151}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009152
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009153/* this function register new section in the haproxy configuration file.
9154 * <section_name> is the name of this new section and <section_parser>
9155 * is the called parser. If two section declaration have the same name,
9156 * only the first declared is used.
9157 */
9158int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009159 int (*section_parser)(const char *, int, char **, int),
9160 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009161{
9162 struct cfg_section *cs;
9163
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009164 list_for_each_entry(cs, &sections, list) {
9165 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009166 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009167 return 0;
9168 }
9169 }
9170
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009171 cs = calloc(1, sizeof(*cs));
9172 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009173 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009174 return 0;
9175 }
9176
9177 cs->section_name = section_name;
9178 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009179 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009180
9181 LIST_ADDQ(&sections, &cs->list);
9182
9183 return 1;
9184}
9185
William Lallemand48b4bb42017-10-23 14:36:34 +02009186/* this function register a new function which will be called once the haproxy
9187 * configuration file has been parsed. It's useful to check dependencies
9188 * between sections or to resolve items once everything is parsed.
9189 */
9190int cfg_register_postparser(char *name, int (*func)())
9191{
9192 struct cfg_postparser *cp;
9193
9194 cp = calloc(1, sizeof(*cp));
9195 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009196 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009197 return 0;
9198 }
9199 cp->name = name;
9200 cp->func = func;
9201
9202 LIST_ADDQ(&postparsers, &cp->list);
9203
9204 return 1;
9205}
9206
Willy Tarreaubaaee002006-06-26 02:48:02 +02009207/*
David Carlier845efb52015-09-25 11:49:18 +01009208 * free all config section entries
9209 */
9210void cfg_unregister_sections(void)
9211{
9212 struct cfg_section *cs, *ics;
9213
9214 list_for_each_entry_safe(cs, ics, &sections, list) {
9215 LIST_DEL(&cs->list);
9216 free(cs);
9217 }
9218}
9219
Christopher Faulet7110b402016-10-26 11:09:44 +02009220void cfg_backup_sections(struct list *backup_sections)
9221{
9222 struct cfg_section *cs, *ics;
9223
9224 list_for_each_entry_safe(cs, ics, &sections, list) {
9225 LIST_DEL(&cs->list);
9226 LIST_ADDQ(backup_sections, &cs->list);
9227 }
9228}
9229
9230void cfg_restore_sections(struct list *backup_sections)
9231{
9232 struct cfg_section *cs, *ics;
9233
9234 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9235 LIST_DEL(&cs->list);
9236 LIST_ADDQ(&sections, &cs->list);
9237 }
9238}
9239
Willy Tarreau659fbf02016-05-26 17:55:28 +02009240__attribute__((constructor))
9241static void cfgparse_init(void)
9242{
9243 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009244 cfg_register_section("listen", cfg_parse_listen, NULL);
9245 cfg_register_section("frontend", cfg_parse_listen, NULL);
9246 cfg_register_section("backend", cfg_parse_listen, NULL);
9247 cfg_register_section("defaults", cfg_parse_listen, NULL);
9248 cfg_register_section("global", cfg_parse_global, NULL);
9249 cfg_register_section("userlist", cfg_parse_users, NULL);
9250 cfg_register_section("peers", cfg_parse_peers, NULL);
9251 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9252 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9253 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009254}
9255
David Carlier845efb52015-09-25 11:49:18 +01009256/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009257 * Local variables:
9258 * c-indent-level: 8
9259 * c-basic-offset: 8
9260 * End:
9261 */