blob: e20ab72daa4d4f036d22951690e6916359ff0bae [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);
William Lallemand2fe7dd02018-09-11 16:51:29 +0200298
299 } else if (ss2->ss_family == AF_CUST_SOCKPAIR) {
300 socklen_t addr_len;
301 inherited = 1;
302
303 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
304 addr_len = sizeof(*ss2);
305 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
306 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
307 goto fail;
308 }
309
310 ss2->ss_family = AF_CUST_SOCKPAIR; /* reassign AF_CUST_SOCKPAIR because of getsockname */
311 port = end = 0;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100312 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200313
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100314 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100315 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200316 memprintf(err, "%s for address '%s'.\n", *err, str);
317 goto fail;
318 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200319 } /* end while(next) */
320 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200321 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200322 fail:
323 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200324 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200325}
326
William Lallemand6e62fb62015-04-28 16:55:23 +0200327/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100328 * Report an error in <msg> when there are too many arguments. This version is
329 * intended to be used by keyword parsers so that the message will be included
330 * into the general error message. The index is the current keyword in args.
331 * Return 0 if the number of argument is correct, otherwise build a message and
332 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
333 * message may also be null, it will simply not be produced (useful to check only).
334 * <msg> and <err_code> are only affected on error.
335 */
336int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
337{
338 int i;
339
340 if (!*args[index + maxarg + 1])
341 return 0;
342
343 if (msg) {
344 *msg = NULL;
345 memprintf(msg, "%s", args[0]);
346 for (i = 1; i <= index; i++)
347 memprintf(msg, "%s %s", *msg, args[i]);
348
349 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
350 }
351 if (err_code)
352 *err_code |= ERR_ALERT | ERR_FATAL;
353
354 return 1;
355}
356
357/*
358 * same as too_many_args_idx with a 0 index
359 */
360int too_many_args(int maxarg, char **args, char **msg, int *err_code)
361{
362 return too_many_args_idx(maxarg, 0, args, msg, err_code);
363}
364
365/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200366 * Report a fatal Alert when there is too much arguments
367 * The index is the current keyword in args
368 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
369 * Fill err_code with an ERR_ALERT and an ERR_FATAL
370 */
371int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
372{
373 char *kw = NULL;
374 int i;
375
376 if (!*args[index + maxarg + 1])
377 return 0;
378
379 memprintf(&kw, "%s", args[0]);
380 for (i = 1; i <= index; i++) {
381 memprintf(&kw, "%s %s", kw, args[i]);
382 }
383
Christopher Faulet767a84b2017-11-24 16:50:31 +0100384 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 +0200385 free(kw);
386 *err_code |= ERR_ALERT | ERR_FATAL;
387 return 1;
388}
389
390/*
391 * same as alertif_too_many_args_idx with a 0 index
392 */
393int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
394{
395 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
396}
397
Willy Tarreau620408f2016-10-21 16:37:51 +0200398/* Report a warning if a rule is placed after a 'tcp-request session' rule.
399 * Return 1 if the warning has been emitted, otherwise 0.
400 */
401int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
402{
403 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100404 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
405 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200406 return 1;
407 }
408 return 0;
409}
410
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200411/* Report a warning if a rule is placed after a 'tcp-request content' rule.
412 * Return 1 if the warning has been emitted, otherwise 0.
413 */
414int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
415{
416 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100417 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
418 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200419 return 1;
420 }
421 return 0;
422}
423
Willy Tarreau721d8e02017-12-01 18:25:08 +0100424/* Report a warning if a rule is placed after a 'monitor fail' rule.
425 * Return 1 if the warning has been emitted, otherwise 0.
426 */
427int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
428{
429 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
430 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
431 file, line, arg);
432 return 1;
433 }
434 return 0;
435}
436
Willy Tarreau61d18892009-03-31 10:49:21 +0200437/* Report a warning if a rule is placed after a 'block' rule.
438 * Return 1 if the warning has been emitted, otherwise 0.
439 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100440int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200441{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200442 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100443 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
444 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200445 return 1;
446 }
447 return 0;
448}
449
Willy Tarreau5002f572014-04-23 01:32:02 +0200450/* Report a warning if a rule is placed after an 'http_request' rule.
451 * Return 1 if the warning has been emitted, otherwise 0.
452 */
453int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
454{
455 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100456 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
457 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200458 return 1;
459 }
460 return 0;
461}
462
Willy Tarreau61d18892009-03-31 10:49:21 +0200463/* Report a warning if a rule is placed after a reqrewrite rule.
464 * Return 1 if the warning has been emitted, otherwise 0.
465 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100466int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200467{
468 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100469 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
470 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200471 return 1;
472 }
473 return 0;
474}
475
476/* Report a warning if a rule is placed after a reqadd rule.
477 * Return 1 if the warning has been emitted, otherwise 0.
478 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100479int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200480{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100481 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100482 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
483 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200484 return 1;
485 }
486 return 0;
487}
488
489/* Report a warning if a rule is placed after a redirect rule.
490 * Return 1 if the warning has been emitted, otherwise 0.
491 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100492int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200493{
494 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100495 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
496 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200497 return 1;
498 }
499 return 0;
500}
501
502/* Report a warning if a rule is placed after a 'use_backend' rule.
503 * Return 1 if the warning has been emitted, otherwise 0.
504 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100505int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200506{
507 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100508 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
509 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200510 return 1;
511 }
512 return 0;
513}
514
Willy Tarreauee445d92014-04-23 01:39:04 +0200515/* Report a warning if a rule is placed after a 'use-server' rule.
516 * Return 1 if the warning has been emitted, otherwise 0.
517 */
518int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
519{
520 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100521 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
522 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200523 return 1;
524 }
525 return 0;
526}
527
Willy Tarreaud39ad442016-11-25 15:16:12 +0100528/* report a warning if a redirect rule is dangerously placed */
529int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200530{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100531 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200532 warnif_rule_after_use_server(proxy, file, line, arg);
533}
534
Willy Tarreaud39ad442016-11-25 15:16:12 +0100535/* report a warning if a reqadd rule is dangerously placed */
536int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200537{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100538 return warnif_rule_after_redirect(proxy, file, line, arg) ||
539 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200540}
541
Willy Tarreaud39ad442016-11-25 15:16:12 +0100542/* report a warning if a reqxxx rule is dangerously placed */
543int warnif_misplaced_reqxxx(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_reqadd(proxy, file, line, arg) ||
546 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200547}
548
549/* report a warning if an http-request rule is dangerously placed */
550int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
551{
Willy Tarreau61d18892009-03-31 10:49:21 +0200552 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100553 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200554}
555
Willy Tarreaud39ad442016-11-25 15:16:12 +0100556/* report a warning if a block rule is dangerously placed */
557int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200558{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100559 return warnif_rule_after_http_req(proxy, file, line, arg) ||
560 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200561}
562
Willy Tarreau721d8e02017-12-01 18:25:08 +0100563/* report a warning if a block rule is dangerously placed */
564int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200565{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100566 return warnif_rule_after_block(proxy, file, line, arg) ||
567 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200568}
569
Willy Tarreau721d8e02017-12-01 18:25:08 +0100570/* report a warning if a "tcp request content" rule is dangerously placed */
571int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
572{
573 return warnif_rule_after_monitor(proxy, file, line, arg) ||
574 warnif_misplaced_monitor(proxy, file, line, arg);
575}
576
Willy Tarreaud39ad442016-11-25 15:16:12 +0100577/* report a warning if a "tcp request session" rule is dangerously placed */
578int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200579{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100580 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
581 warnif_misplaced_tcp_cont(proxy, file, line, arg);
582}
583
584/* report a warning if a "tcp request connection" rule is dangerously placed */
585int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
586{
587 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
588 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200589}
590
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100591/* Report it if a request ACL condition uses some keywords that are incompatible
592 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
593 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
594 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100595 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100596static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100597{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100598 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200599 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100600
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100601 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100602 return 0;
603
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100604 acl = acl_cond_conflicts(cond, where);
605 if (acl) {
606 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100607 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
608 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100609 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100610 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
611 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100612 return ERR_WARN;
613 }
614 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100615 return 0;
616
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100617 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100618 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
619 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100620 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100621 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
622 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100623 return ERR_WARN;
624}
625
Christopher Faulet62519022017-10-16 15:49:32 +0200626/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100627 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100628 * two such numbers delimited by a dash ('-'). On success, it returns
629 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200630 *
631 * Note: this function can also be used to parse a thread number or a set of
632 * threads.
633 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100634int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200635{
Christopher Faulet26028f62017-11-22 15:01:51 +0100636 if (autoinc) {
637 *autoinc = 0;
638 if (strncmp(arg, "auto:", 5) == 0) {
639 arg += 5;
640 *autoinc = 1;
641 }
642 }
643
Christopher Faulet62519022017-10-16 15:49:32 +0200644 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100645 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200646 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100647 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200648 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100649 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200650 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100651 char *dash;
652 unsigned int low, high;
653
Christopher Faulet5ab51772017-11-22 11:21:58 +0100654 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100655 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100656 return -1;
657 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100658
659 low = high = str2uic(arg);
660 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100661 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
662
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100663 if (high < low) {
664 unsigned int swap = low;
665 low = high;
666 high = swap;
667 }
668
Christopher Faulet5ab51772017-11-22 11:21:58 +0100669 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100670 memprintf(err, "'%s' is not a valid number/range."
671 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100672 arg, LONGBITS);
673 return 1;
674 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100675
676 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100677 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200678 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100679
Christopher Faulet5ab51772017-11-22 11:21:58 +0100680 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200681}
682
David Carlier7e351ee2017-12-01 09:14:02 +0000683#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200684/* Parse cpu sets. Each CPU set is either a unique number between 0 and
685 * <LONGBITS> or a range with two such numbers delimited by a dash
686 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
687 * returns 0. otherwise it returns 1 with an error message in <err>.
688 */
689static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
690{
691 int cur_arg = 0;
692
693 *cpu_set = 0;
694 while (*args[cur_arg]) {
695 char *dash;
696 unsigned int low, high;
697
698 if (!isdigit((int)*args[cur_arg])) {
699 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
700 return -1;
701 }
702
703 low = high = str2uic(args[cur_arg]);
704 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100705 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200706
707 if (high < low) {
708 unsigned int swap = low;
709 low = high;
710 high = swap;
711 }
712
713 if (high >= LONGBITS) {
714 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
715 return 1;
716 }
717
718 while (low <= high)
719 *cpu_set |= 1UL << low++;
720
721 cur_arg++;
722 }
723 return 0;
724}
David Carlier7e351ee2017-12-01 09:14:02 +0000725#endif
726
Willy Tarreaubaaee002006-06-26 02:48:02 +0200727/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200728 * parse a line in a <global> section. Returns the error code, 0 if OK, or
729 * any combination of :
730 * - ERR_ABORT: must abort ASAP
731 * - ERR_FATAL: we can continue parsing but not start the service
732 * - ERR_WARN: a warning has been emitted
733 * - ERR_ALERT: an alert has been emitted
734 * Only the two first ones can stop processing, the two others are just
735 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200736 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200737int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200738{
Willy Tarreau058e9072009-07-20 09:30:05 +0200739 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200740 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200741
742 if (!strcmp(args[0], "global")) { /* new section */
743 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200744 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200745 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200746 }
747 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200748 if (alertif_too_many_args(0, file, linenum, args, &err_code))
749 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200750 global.mode |= MODE_DAEMON;
751 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200752 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200753 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200754 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200755 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100756 if (!strcmp(args[1], "no-exit-on-failure")) {
757 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200758 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100759 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 +0200760 err_code |= ERR_ALERT | ERR_FATAL;
761 goto out;
762 }
763 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200764 global.mode |= MODE_MWORKER;
765 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200766 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200767 if (alertif_too_many_args(0, file, linenum, args, &err_code))
768 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200769 global.mode |= MODE_DEBUG;
770 }
771 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200772 if (alertif_too_many_args(0, file, linenum, args, &err_code))
773 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100774 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200775 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200776 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200777 if (alertif_too_many_args(0, file, linenum, args, &err_code))
778 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100779 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200780 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200781 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200782 if (alertif_too_many_args(0, file, linenum, args, &err_code))
783 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100784 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200785 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100786 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200787 if (alertif_too_many_args(0, file, linenum, args, &err_code))
788 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100789 global.tune.options &= ~GTUNE_USE_SPLICE;
790 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200791 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200792 if (alertif_too_many_args(0, file, linenum, args, &err_code))
793 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200794 global.tune.options &= ~GTUNE_USE_GAI;
795 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000796 else if (!strcmp(args[0], "noreuseport")) {
797 if (alertif_too_many_args(0, file, linenum, args, &err_code))
798 goto out;
799 global.tune.options &= ~GTUNE_USE_REUSEPORT;
800 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200801 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200802 if (alertif_too_many_args(0, file, linenum, args, &err_code))
803 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200804 global.mode |= MODE_QUIET;
805 }
Olivier Houchard1599b802018-05-24 18:59:04 +0200806 else if (!strcmp(args[0], "tune.runqueue-depth")) {
807 if (alertif_too_many_args(1, file, linenum, args, &err_code))
808 goto out;
809 if (global.tune.runqueue_depth != 0) {
810 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
811 err_code |= ERR_ALERT;
812 goto out;
813 }
814 if (*(args[1]) == 0) {
815 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
816 err_code |= ERR_ALERT | ERR_FATAL;
817 goto out;
818 }
819 global.tune.runqueue_depth = atol(args[1]);
820
821 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200822 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200823 if (alertif_too_many_args(1, file, linenum, args, &err_code))
824 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200825 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100826 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200827 err_code |= ERR_ALERT;
828 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200829 }
830 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100831 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200832 err_code |= ERR_ALERT | ERR_FATAL;
833 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200834 }
835 global.tune.maxpollevents = atol(args[1]);
836 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100837 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200838 if (alertif_too_many_args(1, file, linenum, args, &err_code))
839 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100840 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100841 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200842 err_code |= ERR_ALERT;
843 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100844 }
845 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100846 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200847 err_code |= ERR_ALERT | ERR_FATAL;
848 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100849 }
850 global.tune.maxaccept = atol(args[1]);
851 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200852 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200853 if (alertif_too_many_args(1, file, linenum, args, &err_code))
854 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200855 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100856 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200857 err_code |= ERR_ALERT | ERR_FATAL;
858 goto out;
859 }
860 global.tune.chksize = atol(args[1]);
861 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100862 else if (!strcmp(args[0], "tune.recv_enough")) {
863 if (alertif_too_many_args(1, file, linenum, args, &err_code))
864 goto out;
865 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100866 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100867 err_code |= ERR_ALERT | ERR_FATAL;
868 goto out;
869 }
870 global.tune.recv_enough = atol(args[1]);
871 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100872 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200873 if (alertif_too_many_args(1, file, linenum, args, &err_code))
874 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100875 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100876 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100877 err_code |= ERR_ALERT | ERR_FATAL;
878 goto out;
879 }
880 global.tune.buf_limit = atol(args[1]);
881 if (global.tune.buf_limit) {
882 if (global.tune.buf_limit < 3)
883 global.tune.buf_limit = 3;
884 if (global.tune.buf_limit <= global.tune.reserved_bufs)
885 global.tune.buf_limit = global.tune.reserved_bufs + 1;
886 }
887 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100888 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200889 if (alertif_too_many_args(1, file, linenum, args, &err_code))
890 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100891 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 Tarreau1058ae72014-12-23 22:40:40 +0100893 err_code |= ERR_ALERT | ERR_FATAL;
894 goto out;
895 }
896 global.tune.reserved_bufs = atol(args[1]);
897 if (global.tune.reserved_bufs < 2)
898 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100899 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
900 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100901 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200902 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200903 if (alertif_too_many_args(1, file, linenum, args, &err_code))
904 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200905 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100906 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200907 err_code |= ERR_ALERT | ERR_FATAL;
908 goto out;
909 }
910 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200911 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100912 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200913 err_code |= ERR_ALERT | ERR_FATAL;
914 goto out;
915 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200916 }
917 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200918 if (alertif_too_many_args(1, file, linenum, args, &err_code))
919 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200920 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100921 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200922 err_code |= ERR_ALERT | ERR_FATAL;
923 goto out;
924 }
925 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200926 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100927 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200928 err_code |= ERR_ALERT | ERR_FATAL;
929 goto out;
930 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200931 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100932 else if (!strcmp(args[0], "tune.idletimer")) {
933 unsigned int idle;
934 const char *res;
935
William Lallemand1a748ae2015-05-19 16:37:23 +0200936 if (alertif_too_many_args(1, file, linenum, args, &err_code))
937 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100938 if (*(args[1]) == 0) {
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
944 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
945 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100946 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100947 file, linenum, *res, args[0]);
948 err_code |= ERR_ALERT | ERR_FATAL;
949 goto out;
950 }
951
952 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100953 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 +0100954 err_code |= ERR_ALERT | ERR_FATAL;
955 goto out;
956 }
957 global.tune.idle_timer = idle;
958 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100959 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200960 if (alertif_too_many_args(1, file, linenum, args, &err_code))
961 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100962 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100963 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100964 err_code |= ERR_ALERT;
965 goto out;
966 }
967 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100968 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100969 err_code |= ERR_ALERT | ERR_FATAL;
970 goto out;
971 }
972 global.tune.client_rcvbuf = atol(args[1]);
973 }
974 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200975 if (alertif_too_many_args(1, file, linenum, args, &err_code))
976 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100977 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100978 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100979 err_code |= ERR_ALERT;
980 goto out;
981 }
982 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100983 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100984 err_code |= ERR_ALERT | ERR_FATAL;
985 goto out;
986 }
987 global.tune.server_rcvbuf = atol(args[1]);
988 }
989 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200990 if (alertif_too_many_args(1, file, linenum, args, &err_code))
991 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100992 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100993 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100994 err_code |= ERR_ALERT;
995 goto out;
996 }
997 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100998 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100999 err_code |= ERR_ALERT | ERR_FATAL;
1000 goto out;
1001 }
1002 global.tune.client_sndbuf = atol(args[1]);
1003 }
1004 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001005 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1006 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +01001007 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001008 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001009 err_code |= ERR_ALERT;
1010 goto out;
1011 }
1012 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001013 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001014 err_code |= ERR_ALERT | ERR_FATAL;
1015 goto out;
1016 }
1017 global.tune.server_sndbuf = atol(args[1]);
1018 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001019 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001020 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1021 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001022 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001023 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001024 err_code |= ERR_ALERT | ERR_FATAL;
1025 goto out;
1026 }
1027 global.tune.pipesize = atol(args[1]);
1028 }
Willy Tarreau193b8c62012-11-22 00:17:38 +01001029 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001030 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1031 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001032 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001033 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001034 err_code |= ERR_ALERT | ERR_FATAL;
1035 goto out;
1036 }
1037 global.tune.cookie_len = atol(args[1]) + 1;
1038 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001039 else if (!strcmp(args[0], "tune.http.logurilen")) {
1040 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1041 goto out;
1042 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001043 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001044 err_code |= ERR_ALERT | ERR_FATAL;
1045 goto out;
1046 }
1047 global.tune.requri_len = atol(args[1]) + 1;
1048 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001049 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001050 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1051 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001052 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001053 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001054 err_code |= ERR_ALERT | ERR_FATAL;
1055 goto out;
1056 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001057 global.tune.max_http_hdr = atoi(args[1]);
1058 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001059 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1060 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001061 err_code |= ERR_ALERT | ERR_FATAL;
1062 goto out;
1063 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001064 }
William Lallemandf3747832012-11-09 12:33:10 +01001065 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001066 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1067 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001068 if (*args[1]) {
1069 global.tune.comp_maxlevel = atoi(args[1]);
1070 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001071 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1072 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001073 err_code |= ERR_ALERT | ERR_FATAL;
1074 goto out;
1075 }
1076 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001077 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1078 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001079 err_code |= ERR_ALERT | ERR_FATAL;
1080 goto out;
1081 }
1082 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001083 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1084 if (*args[1]) {
1085 global.tune.pattern_cache = atoi(args[1]);
1086 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001087 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1088 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001089 err_code |= ERR_ALERT | ERR_FATAL;
1090 goto out;
1091 }
1092 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001093 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1094 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001095 err_code |= ERR_ALERT | ERR_FATAL;
1096 goto out;
1097 }
1098 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001099 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001100 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1101 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001102 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001103 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001104 err_code |= ERR_ALERT;
1105 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001106 }
1107 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001108 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001109 err_code |= ERR_ALERT | ERR_FATAL;
1110 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001111 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001112 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001113 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 +01001114 err_code |= ERR_WARN;
1115 goto out;
1116 }
1117
Willy Tarreaubaaee002006-06-26 02:48:02 +02001118 }
1119 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001120 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1121 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001122 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001123 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001124 err_code |= ERR_ALERT;
1125 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001126 }
1127 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001128 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001129 err_code |= ERR_ALERT | ERR_FATAL;
1130 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001131 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001132 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001133 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 +01001134 err_code |= ERR_WARN;
1135 goto out;
1136 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001137 }
Simon Horman98637e52014-06-20 12:30:16 +09001138 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001139 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1140 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001141 global.external_check = 1;
1142 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001143 /* user/group name handling */
1144 else if (!strcmp(args[0], "user")) {
1145 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001146 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1147 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001148 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001149 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001150 err_code |= ERR_ALERT;
1151 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001152 }
1153 errno = 0;
1154 ha_user = getpwnam(args[1]);
1155 if (ha_user != NULL) {
1156 global.uid = (int)ha_user->pw_uid;
1157 }
1158 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001159 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 +02001160 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001161 }
1162 }
1163 else if (!strcmp(args[0], "group")) {
1164 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001165 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1166 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001167 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001168 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001169 err_code |= ERR_ALERT;
1170 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001171 }
1172 errno = 0;
1173 ha_group = getgrnam(args[1]);
1174 if (ha_group != NULL) {
1175 global.gid = (int)ha_group->gr_gid;
1176 }
1177 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001178 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 +02001179 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001180 }
1181 }
1182 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001183 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001184 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1185 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001186 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001187 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001188 err_code |= ERR_ALERT | ERR_FATAL;
1189 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001190 }
1191 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001192 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001193 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1194 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001195 err_code |= ERR_ALERT | ERR_FATAL;
1196 goto out;
1197 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001198 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001199 else if (!strcmp(args[0], "nbthread")) {
1200 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1201 goto out;
1202 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001203 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001204 err_code |= ERR_ALERT | ERR_FATAL;
1205 goto out;
1206 }
Willy Tarreau0ccd3222018-07-30 10:34:35 +02001207 global.nbthread = parse_nbthread(args[1], &errmsg);
1208 if (!global.nbthread) {
1209 ha_alert("parsing [%s:%d] : '%s' %s.\n",
1210 file, linenum, args[0], errmsg);
Willy Tarreau421f02e2018-01-20 18:19:22 +01001211 err_code |= ERR_ALERT | ERR_FATAL;
1212 goto out;
1213 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001214 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001215 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001216 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1217 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001218 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001219 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001220 err_code |= ERR_ALERT;
1221 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001222 }
1223 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001224 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001225 err_code |= ERR_ALERT | ERR_FATAL;
1226 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001227 }
1228 global.maxconn = atol(args[1]);
1229#ifdef SYSTEM_MAXCONN
1230 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001231 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 +02001232 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001233 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001234 }
1235#endif /* SYSTEM_MAXCONN */
1236 }
Emeric Brun850efd52014-01-29 12:24:34 +01001237 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001238 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1239 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001240 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001241 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001242 err_code |= ERR_ALERT | ERR_FATAL;
1243 goto out;
1244 }
1245 if (strcmp(args[1],"none") == 0)
1246 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1247 else if (strcmp(args[1],"required") == 0)
1248 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1249 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001250 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001251 err_code |= ERR_ALERT | ERR_FATAL;
1252 goto out;
1253 }
1254 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001255 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001256 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1257 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001258 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001259 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001260 err_code |= ERR_ALERT;
1261 goto out;
1262 }
1263 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001264 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001265 err_code |= ERR_ALERT | ERR_FATAL;
1266 goto out;
1267 }
1268 global.cps_lim = atol(args[1]);
1269 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001270 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001271 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1272 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001273 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001274 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001275 err_code |= ERR_ALERT;
1276 goto out;
1277 }
1278 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001279 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001280 err_code |= ERR_ALERT | ERR_FATAL;
1281 goto out;
1282 }
1283 global.sps_lim = atol(args[1]);
1284 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001285 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001286 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1287 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001288 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001289 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001290 err_code |= ERR_ALERT;
1291 goto out;
1292 }
1293 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001294 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001295 err_code |= ERR_ALERT | ERR_FATAL;
1296 goto out;
1297 }
1298 global.ssl_lim = atol(args[1]);
1299 }
William Lallemandd85f9172012-11-09 17:05:39 +01001300 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001301 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1302 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001303 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001304 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 +01001305 err_code |= ERR_ALERT | ERR_FATAL;
1306 goto out;
1307 }
1308 global.comp_rate_lim = atoi(args[1]) * 1024;
1309 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001310 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001311 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1312 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001313 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001314 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001315 err_code |= ERR_ALERT;
1316 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001317 }
1318 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001319 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001320 err_code |= ERR_ALERT | ERR_FATAL;
1321 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001322 }
1323 global.maxpipes = atol(args[1]);
1324 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001325 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001326 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1327 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001328 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001329 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001330 err_code |= ERR_ALERT | ERR_FATAL;
1331 goto out;
1332 }
William Lallemande3a7d992012-11-20 11:25:20 +01001333 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001334 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001335 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001336 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1337 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001338 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001339 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
William Lallemand072a2bf2012-11-20 17:01:01 +01001340 err_code |= ERR_ALERT | ERR_FATAL;
1341 goto out;
1342 }
1343 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001344 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001345 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 +01001346 err_code |= ERR_ALERT | ERR_FATAL;
1347 goto out;
1348 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001349 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001350
Willy Tarreaubaaee002006-06-26 02:48:02 +02001351 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001352 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1353 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001354 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001355 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001356 err_code |= ERR_ALERT;
1357 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001358 }
1359 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001360 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001361 err_code |= ERR_ALERT | ERR_FATAL;
1362 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001363 }
1364 global.rlimit_nofile = atol(args[1]);
1365 }
1366 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001367 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1368 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001369 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001370 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001371 err_code |= ERR_ALERT;
1372 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001373 }
1374 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001375 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001376 err_code |= ERR_ALERT | ERR_FATAL;
1377 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001378 }
1379 global.chroot = strdup(args[1]);
1380 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001381 else if (!strcmp(args[0], "description")) {
1382 int i, len=0;
1383 char *d;
1384
1385 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001386 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1387 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001388 err_code |= ERR_ALERT | ERR_FATAL;
1389 goto out;
1390 }
1391
Willy Tarreau348acfe2014-04-14 15:00:39 +02001392 for (i = 1; *args[i]; i++)
1393 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001394
1395 if (global.desc)
1396 free(global.desc);
1397
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001398 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001399
Willy Tarreau348acfe2014-04-14 15:00:39 +02001400 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1401 for (i = 2; *args[i]; i++)
1402 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001403 }
1404 else if (!strcmp(args[0], "node")) {
1405 int i;
1406 char c;
1407
William Lallemand1a748ae2015-05-19 16:37:23 +02001408 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1409 goto out;
1410
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001411 for (i=0; args[1][i]; i++) {
1412 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001413 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1414 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001415 break;
1416 }
1417
1418 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001419 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1420 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1421 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001422 err_code |= ERR_ALERT | ERR_FATAL;
1423 goto out;
1424 }
1425
1426 if (global.node)
1427 free(global.node);
1428
1429 global.node = strdup(args[1]);
1430 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001431 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001432 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1433 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001434 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001435 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001436 err_code |= ERR_ALERT;
1437 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001438 }
1439 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001440 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 +02001441 err_code |= ERR_ALERT | ERR_FATAL;
1442 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001443 }
1444 global.pidfile = strdup(args[1]);
1445 }
Emeric Bruned760922010-10-22 17:59:25 +02001446 else if (!strcmp(args[0], "unix-bind")) {
1447 int cur_arg = 1;
1448 while (*(args[cur_arg])) {
1449 if (!strcmp(args[cur_arg], "prefix")) {
1450 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001451 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001452 err_code |= ERR_ALERT;
1453 cur_arg += 2;
1454 continue;
1455 }
1456
1457 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001458 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 +02001459 err_code |= ERR_ALERT | ERR_FATAL;
1460 goto out;
1461 }
1462 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1463 cur_arg += 2;
1464 continue;
1465 }
1466
1467 if (!strcmp(args[cur_arg], "mode")) {
1468
1469 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1470 cur_arg += 2;
1471 continue;
1472 }
1473
1474 if (!strcmp(args[cur_arg], "uid")) {
1475
1476 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1477 cur_arg += 2;
1478 continue;
1479 }
1480
1481 if (!strcmp(args[cur_arg], "gid")) {
1482
1483 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1484 cur_arg += 2;
1485 continue;
1486 }
1487
1488 if (!strcmp(args[cur_arg], "user")) {
1489 struct passwd *user;
1490
1491 user = getpwnam(args[cur_arg + 1]);
1492 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001493 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1494 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001495 err_code |= ERR_ALERT | ERR_FATAL;
1496 goto out;
1497 }
1498
1499 global.unix_bind.ux.uid = user->pw_uid;
1500 cur_arg += 2;
1501 continue;
1502 }
1503
1504 if (!strcmp(args[cur_arg], "group")) {
1505 struct group *group;
1506
1507 group = getgrnam(args[cur_arg + 1]);
1508 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001509 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1510 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001511 err_code |= ERR_ALERT | ERR_FATAL;
1512 goto out;
1513 }
1514
1515 global.unix_bind.ux.gid = group->gr_gid;
1516 cur_arg += 2;
1517 continue;
1518 }
1519
Christopher Faulet767a84b2017-11-24 16:50:31 +01001520 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1521 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001522 err_code |= ERR_ALERT | ERR_FATAL;
1523 goto out;
1524 }
1525 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001526 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1527 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1528 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001529 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001530 goto out;
1531 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001532 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001533 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1534 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001535
1536 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001537 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001538 err_code |= ERR_ALERT;
1539 goto out;
1540 }
1541
1542 if (*(args[1]))
1543 name = args[1];
1544 else
1545 name = hostname;
1546
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001547 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001548 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001549 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001550 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1551 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001552 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001553 err_code |= ERR_ALERT;
1554 goto out;
1555 }
1556
1557 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001558 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001559 err_code |= ERR_FATAL;
1560 goto out;
1561 }
1562
1563 global.server_state_base = strdup(args[1]);
1564 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001565 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1566 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001567 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001568 err_code |= ERR_ALERT;
1569 goto out;
1570 }
1571
1572 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001573 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001574 err_code |= ERR_FATAL;
1575 goto out;
1576 }
1577
1578 global.server_state_file = strdup(args[1]);
1579 }
Kevinm48936af2010-12-22 16:08:21 +00001580 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001581 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1582 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001583 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001584 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001585 err_code |= ERR_ALERT | ERR_FATAL;
1586 goto out;
1587 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001588 chunk_destroy(&global.log_tag);
1589 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001590 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001591 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001592 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1593 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001594 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001595 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001596 err_code |= ERR_ALERT;
1597 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001598 }
1599 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001600 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001601 err_code |= ERR_ALERT | ERR_FATAL;
1602 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001603 }
1604 global.spread_checks = atol(args[1]);
1605 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001606 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 +02001607 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001608 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001609 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001610 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1611 const char *err;
1612 unsigned int val;
1613
William Lallemand1a748ae2015-05-19 16:37:23 +02001614 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1615 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001616 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001617 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001618 err_code |= ERR_ALERT | ERR_FATAL;
1619 goto out;
1620 }
1621
1622 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1623 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001624 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 +02001625 err_code |= ERR_ALERT | ERR_FATAL;
1626 }
1627 global.max_spread_checks = val;
1628 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001629 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001630 err_code |= ERR_ALERT | ERR_FATAL;
1631 }
1632 }
Christopher Faulet62519022017-10-16 15:49:32 +02001633 else if (strcmp(args[0], "cpu-map") == 0) {
1634 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001635#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001636 char *slash;
1637 unsigned long proc = 0, thread = 0, cpus;
1638 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001639
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001640 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001641 ha_alert("parsing [%s:%d] : %s expects a process number "
1642 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1643 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1644 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001645 err_code |= ERR_ALERT | ERR_FATAL;
1646 goto out;
1647 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001648
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001649 if ((slash = strchr(args[1], '/')) != NULL)
1650 *slash = 0;
1651
Christopher Faulet26028f62017-11-22 15:01:51 +01001652 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001653 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001654 err_code |= ERR_ALERT | ERR_FATAL;
1655 goto out;
1656 }
1657
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001658 if (slash) {
1659 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001660 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001661 err_code |= ERR_ALERT | ERR_FATAL;
1662 goto out;
1663 }
1664 *slash = '/';
1665
1666 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001667 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1668 "a process range _AND_ a thread range\n",
1669 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001670 err_code |= ERR_ALERT | ERR_FATAL;
1671 goto out;
1672 }
1673 }
1674
Christopher Faulet62519022017-10-16 15:49:32 +02001675 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001676 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001677 err_code |= ERR_ALERT | ERR_FATAL;
1678 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001679 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001680
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001681 if (autoinc &&
1682 my_popcountl(proc) != my_popcountl(cpus) &&
1683 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001684 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1685 "must have the same size to be automatically bound\n",
1686 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001687 err_code |= ERR_ALERT | ERR_FATAL;
1688 goto out;
1689 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001690
Christopher Faulet26028f62017-11-22 15:01:51 +01001691 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001692 /* No mapping for this process */
1693 if (!(proc & (1UL << i)))
1694 continue;
1695
1696 /* Mapping at the process level */
1697 if (!thread) {
1698 if (!autoinc)
1699 global.cpu_map.proc[i] = cpus;
1700 else {
1701 n += my_ffsl(cpus >> n);
1702 global.cpu_map.proc[i] = (1UL << (n-1));
1703 }
1704 continue;
1705 }
1706
1707 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001708 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001709 /* Np mapping for this thread */
1710 if (!(thread & (1UL << j)))
1711 continue;
1712
1713 if (!autoinc)
1714 global.cpu_map.thread[i][j] = cpus;
1715 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001716 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001717 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001718 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001719 }
1720 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001721#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001722 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1723 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001724 err_code |= ERR_ALERT | ERR_FATAL;
1725 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001726#endif /* ! USE_CPU_AFFINITY */
1727 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001728 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1729 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1730 goto out;
1731
1732 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001733 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001734 err_code |= ERR_ALERT | ERR_FATAL;
1735 goto out;
1736 }
1737
1738 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1739 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001740 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 +01001741 err_code |= ERR_ALERT | ERR_FATAL;
1742 goto out;
1743 }
1744 }
1745 else if (!strcmp(args[0], "unsetenv")) {
1746 int arg;
1747
1748 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001749 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001750 err_code |= ERR_ALERT | ERR_FATAL;
1751 goto out;
1752 }
1753
1754 for (arg = 1; *args[arg]; arg++) {
1755 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001756 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 +01001757 err_code |= ERR_ALERT | ERR_FATAL;
1758 goto out;
1759 }
1760 }
1761 }
1762 else if (!strcmp(args[0], "resetenv")) {
1763 extern char **environ;
1764 char **env = environ;
1765
1766 /* args contain variable names to keep, one per argument */
1767 while (*env) {
1768 int arg;
1769
1770 /* look for current variable in among all those we want to keep */
1771 for (arg = 1; *args[arg]; arg++) {
1772 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1773 (*env)[strlen(args[arg])] == '=')
1774 break;
1775 }
1776
1777 /* delete this variable */
1778 if (!*args[arg]) {
1779 char *delim = strchr(*env, '=');
1780
1781 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001782 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 +01001783 err_code |= ERR_ALERT | ERR_FATAL;
1784 goto out;
1785 }
1786
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001787 memcpy(trash.area, *env, delim - *env);
1788 trash.area[delim - *env] = 0;
Willy Tarreau1d549722016-02-16 12:41:57 +01001789
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001790 if (unsetenv(trash.area) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001791 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 +01001792 err_code |= ERR_ALERT | ERR_FATAL;
1793 goto out;
1794 }
1795 }
1796 else
1797 env++;
1798 }
1799 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001800 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001801 struct cfg_kw_list *kwl;
1802 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001803 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001804
1805 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1806 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1807 if (kwl->kw[index].section != CFG_GLOBAL)
1808 continue;
1809 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001810 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001811 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001812 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001813 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001814 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001815 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001816 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001817 err_code |= ERR_WARN;
1818 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001819 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001820 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001821 }
1822 }
1823 }
1824
Christopher Faulet767a84b2017-11-24 16:50:31 +01001825 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001826 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001827 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001828
Willy Tarreau058e9072009-07-20 09:30:05 +02001829 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001830 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001831 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001832}
1833
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001834void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001835{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001836 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001837 defproxy.mode = PR_MODE_TCP;
1838 defproxy.state = PR_STNEW;
1839 defproxy.maxconn = cfg_maxpconn;
1840 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001841 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001842 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001843
Simon Horman66183002013-02-23 10:16:43 +09001844 defproxy.defsrv.check.inter = DEF_CHKINTR;
1845 defproxy.defsrv.check.fastinter = 0;
1846 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001847 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1848 defproxy.defsrv.agent.fastinter = 0;
1849 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001850 defproxy.defsrv.check.rise = DEF_RISETIME;
1851 defproxy.defsrv.check.fall = DEF_FALLTIME;
1852 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1853 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001854 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001855 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001856 defproxy.defsrv.maxqueue = 0;
1857 defproxy.defsrv.minconn = 0;
1858 defproxy.defsrv.maxconn = 0;
1859 defproxy.defsrv.slowstart = 0;
1860 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1861 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1862 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001863
1864 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001865 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001866}
1867
Willy Tarreauade5ec42010-01-28 19:33:49 +01001868
Willy Tarreau63af98d2014-05-18 08:11:41 +02001869/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1870 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1871 * ERR_FATAL in case of error.
1872 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001873static int create_cond_regex_rule(const char *file, int line,
1874 struct proxy *px, int dir, int action, int flags,
1875 const char *cmd, const char *reg, const char *repl,
1876 const char **cond_start)
1877{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001878 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001879 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001880 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001881 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001882 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001883 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001884 int cs;
1885 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001886
1887 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001888 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001889 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001890 goto err;
1891 }
1892
1893 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001894 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001895 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001896 goto err;
1897 }
1898
Christopher Faulet898566e2016-10-26 11:06:28 +02001899 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001900 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001901
Willy Tarreau5321c422010-01-28 20:35:13 +01001902 if (cond_start &&
1903 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001904 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001905 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1906 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001907 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001908 goto err;
1909 }
1910 }
1911 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001912 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1913 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001914 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001915 goto err;
1916 }
1917
Willy Tarreau63af98d2014-05-18 08:11:41 +02001918 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001919 (dir == SMP_OPT_DIR_REQ) ?
1920 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1921 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1922 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001923
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001924 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001925 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001926 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001927 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001928 goto err;
1929 }
1930
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001931 cs = !(flags & REG_ICASE);
1932 cap = !(flags & REG_NOSUB);
1933 error = NULL;
1934 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001935 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001936 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001937 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001938 goto err;
1939 }
1940
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001941 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001942 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001943 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001944 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1945 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001946 ret_code |= ERR_ALERT | ERR_FATAL;
1947 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001948 }
1949
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001950 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001951 ret_code |= ERR_WARN;
1952
1953 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001954
Willy Tarreau63af98d2014-05-18 08:11:41 +02001955 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001956 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001957 err:
1958 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001959 free(errmsg);
1960 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001961}
1962
Willy Tarreaubaaee002006-06-26 02:48:02 +02001963/*
William Lallemand51097192015-04-14 16:35:22 +02001964 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001965 * Returns the error code, 0 if OK, or any combination of :
1966 * - ERR_ABORT: must abort ASAP
1967 * - ERR_FATAL: we can continue parsing but not start the service
1968 * - ERR_WARN: a warning has been emitted
1969 * - ERR_ALERT: an alert has been emitted
1970 * Only the two first ones can stop processing, the two others are just
1971 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001972 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001973int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1974{
1975 static struct peers *curpeers = NULL;
1976 struct peer *newpeer = NULL;
1977 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001978 struct bind_conf *bind_conf;
1979 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001980 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001981 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001982
1983 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001984 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001985 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001986 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001987 goto out;
1988 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001989
William Lallemand6e62fb62015-04-28 16:55:23 +02001990 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1991 goto out;
1992
Emeric Brun32da3c42010-09-23 18:39:19 +02001993 err = invalid_char(args[1]);
1994 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001995 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1996 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001997 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001998 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02001999 }
2000
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002001 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02002002 /*
2003 * If there are two proxies with the same name only following
2004 * combinations are allowed:
2005 */
2006 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002007 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2008 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002009 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002010 }
2011 }
2012
Vincent Bernat02779b62016-04-03 13:48:43 +02002013 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002014 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002015 err_code |= ERR_ALERT | ERR_ABORT;
2016 goto out;
2017 }
2018
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002019 curpeers->next = cfg_peers;
2020 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002021 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002022 curpeers->conf.line = linenum;
2023 curpeers->last_change = now.tv_sec;
2024 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002025 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002026 }
2027 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002028 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002029 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002030 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002031
2032 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002033 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2034 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002035 err_code |= ERR_ALERT | ERR_FATAL;
2036 goto out;
2037 }
2038
2039 err = invalid_char(args[1]);
2040 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002041 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2042 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002043 err_code |= ERR_ALERT | ERR_FATAL;
2044 goto out;
2045 }
2046
Vincent Bernat02779b62016-04-03 13:48:43 +02002047 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002048 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002049 err_code |= ERR_ALERT | ERR_ABORT;
2050 goto out;
2051 }
2052
2053 /* the peers are linked backwards first */
2054 curpeers->count++;
2055 newpeer->next = curpeers->remote;
2056 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002057 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002058 newpeer->conf.line = linenum;
2059
2060 newpeer->last_change = now.tv_sec;
2061 newpeer->id = strdup(args[1]);
2062
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002063 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002064 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002065 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002066 err_code |= ERR_ALERT | ERR_FATAL;
2067 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002068 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002069
2070 proto = protocol_by_family(sk->ss_family);
2071 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002072 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2073 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002074 err_code |= ERR_ALERT | ERR_FATAL;
2075 goto out;
2076 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002077
2078 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002079 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2080 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002081 err_code |= ERR_ALERT | ERR_FATAL;
2082 goto out;
2083 }
2084
Willy Tarreau2aa38802013-02-20 19:20:59 +01002085 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002086 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2087 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002088 err_code |= ERR_ALERT | ERR_FATAL;
2089 goto out;
2090 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002091
Emeric Brun32da3c42010-09-23 18:39:19 +02002092 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002093 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002094 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002095 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002096 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002097
Emeric Brun32da3c42010-09-23 18:39:19 +02002098 if (strcmp(newpeer->id, localpeer) == 0) {
2099 /* Current is local peer, it define a frontend */
2100 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002101 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002102
2103 if (!curpeers->peers_fe) {
2104 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002105 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002106 err_code |= ERR_ALERT | ERR_ABORT;
2107 goto out;
2108 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002109
Willy Tarreau237250c2011-07-29 01:49:03 +02002110 init_new_proxy(curpeers->peers_fe);
2111 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002112 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002113 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2114 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002115 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002116
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002117 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002118
Willy Tarreau902636f2013-03-10 19:44:48 +01002119 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2120 if (errmsg && *errmsg) {
2121 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002122 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002123 }
2124 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002125 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2126 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002127 err_code |= ERR_FATAL;
2128 goto out;
2129 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002130
2131 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002132 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002133 l->maxconn = curpeers->peers_fe->maxconn;
2134 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002135 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002136 l->analysers |= curpeers->peers_fe->fe_req_ana;
2137 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002138 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2139 global.maxsock += l->maxconn;
2140 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002141 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002142 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002143 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2144 file, linenum, args[0], args[1],
2145 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002146 err_code |= ERR_FATAL;
2147 goto out;
2148 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002149 }
2150 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002151 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2152 curpeers->state = PR_STSTOPPED;
2153 }
2154 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2155 curpeers->state = PR_STNEW;
2156 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002157 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002158 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002159 err_code |= ERR_ALERT | ERR_FATAL;
2160 goto out;
2161 }
2162
2163out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002164 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002165 return err_code;
2166}
2167
Baptiste Assmann325137d2015-04-13 23:40:55 +02002168/*
2169 * Parse a <resolvers> section.
2170 * Returns the error code, 0 if OK, or any combination of :
2171 * - ERR_ABORT: must abort ASAP
2172 * - ERR_FATAL: we can continue parsing but not start the service
2173 * - ERR_WARN: a warning has been emitted
2174 * - ERR_ALERT: an alert has been emitted
2175 * Only the two first ones can stop processing, the two others are just
2176 * indicators.
2177 */
2178int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2179{
2180 static struct dns_resolvers *curr_resolvers = NULL;
2181 struct dns_nameserver *newnameserver = NULL;
2182 const char *err;
2183 int err_code = 0;
2184 char *errmsg = NULL;
2185
2186 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2187 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002188 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002189 err_code |= ERR_ALERT | ERR_ABORT;
2190 goto out;
2191 }
2192
2193 err = invalid_char(args[1]);
2194 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002195 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2196 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002197 err_code |= ERR_ALERT | ERR_ABORT;
2198 goto out;
2199 }
2200
2201 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2202 /* Error if two resolvers owns the same name */
2203 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002204 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2205 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002206 err_code |= ERR_ALERT | ERR_ABORT;
2207 }
2208 }
2209
Vincent Bernat02779b62016-04-03 13:48:43 +02002210 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002211 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002212 err_code |= ERR_ALERT | ERR_ABORT;
2213 goto out;
2214 }
2215
2216 /* default values */
2217 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2218 curr_resolvers->conf.file = strdup(file);
2219 curr_resolvers->conf.line = linenum;
2220 curr_resolvers->id = strdup(args[1]);
2221 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002222 /* default maximum response size */
2223 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002224 /* default hold period for nx, other, refuse and timeout is 30s */
2225 curr_resolvers->hold.nx = 30000;
2226 curr_resolvers->hold.other = 30000;
2227 curr_resolvers->hold.refused = 30000;
2228 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002229 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002230 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002231 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002232 curr_resolvers->timeout.resolve = 1000;
2233 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002234 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002235 curr_resolvers->nb_nameservers = 0;
2236 LIST_INIT(&curr_resolvers->nameservers);
2237 LIST_INIT(&curr_resolvers->resolutions.curr);
2238 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002239 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002240 }
2241 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2242 struct sockaddr_storage *sk;
2243 int port1, port2;
2244 struct protocol *proto;
2245
2246 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002247 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2248 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002249 err_code |= ERR_ALERT | ERR_FATAL;
2250 goto out;
2251 }
2252
2253 err = invalid_char(args[1]);
2254 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002255 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2256 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002257 err_code |= ERR_ALERT | ERR_FATAL;
2258 goto out;
2259 }
2260
Christopher Faulet67957bd2017-09-27 11:00:59 +02002261 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002262 /* Error if two resolvers owns the same name */
2263 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002264 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 -06002265 file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002266 err_code |= ERR_ALERT | ERR_FATAL;
2267 }
2268 }
2269
Vincent Bernat02779b62016-04-03 13:48:43 +02002270 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002271 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002272 err_code |= ERR_ALERT | ERR_ABORT;
2273 goto out;
2274 }
2275
2276 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002277 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002278 newnameserver->resolvers = curr_resolvers;
2279 newnameserver->conf.file = strdup(file);
2280 newnameserver->conf.line = linenum;
2281 newnameserver->id = strdup(args[1]);
2282
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002283 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002284 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002285 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002286 err_code |= ERR_ALERT | ERR_FATAL;
2287 goto out;
2288 }
2289
2290 proto = protocol_by_family(sk->ss_family);
2291 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002292 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002293 file, linenum, args[0], args[1]);
2294 err_code |= ERR_ALERT | ERR_FATAL;
2295 goto out;
2296 }
2297
2298 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002299 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2300 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002301 err_code |= ERR_ALERT | ERR_FATAL;
2302 goto out;
2303 }
2304
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002305 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002306 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2307 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002308 err_code |= ERR_ALERT | ERR_FATAL;
2309 goto out;
2310 }
2311
Baptiste Assmann325137d2015-04-13 23:40:55 +02002312 newnameserver->addr = *sk;
2313 }
Ben Draut44e609b2018-05-29 15:40:08 -06002314 else if (strcmp(args[0], "parse-resolv-conf") == 0) {
2315 const char *whitespace = "\r\n\t ";
2316 char *resolv_line = NULL;
2317 int resolv_linenum = 0;
2318 FILE *f = NULL;
2319 char *address = NULL;
2320 struct sockaddr_storage *sk = NULL;
2321 struct protocol *proto;
2322 int duplicate_name = 0;
2323
2324 if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
2325 ha_alert("parsing [%s:%d] : out of memory.\n",
2326 file, linenum);
2327 err_code |= ERR_ALERT | ERR_FATAL;
2328 goto resolv_out;
2329 }
2330
2331 if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
2332 ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n",
2333 file, linenum);
2334 err_code |= ERR_ALERT | ERR_FATAL;
2335 goto resolv_out;
2336 }
2337
2338 sk = calloc(1, sizeof(*sk));
2339 if (sk == NULL) {
2340 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n",
2341 resolv_linenum);
2342 err_code |= ERR_ALERT | ERR_FATAL;
2343 goto resolv_out;
2344 }
2345
2346 while (fgets(resolv_line, LINESIZE, f) != NULL) {
2347 resolv_linenum++;
2348 if (strncmp(resolv_line, "nameserver", 10) != 0)
2349 continue;
2350
2351 address = strtok(resolv_line + 10, whitespace);
2352 if (address == resolv_line + 10)
2353 continue;
2354
2355 if (address == NULL) {
2356 ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
2357 resolv_linenum);
2358 err_code |= ERR_WARN;
2359 continue;
2360 }
2361
2362 duplicate_name = 0;
2363 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
2364 if (strcmp(newnameserver->id, address) == 0) {
2365 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",
2366 resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line);
2367 err_code |= ERR_WARN;
2368 duplicate_name = 1;
2369 }
2370 }
2371
2372 if (duplicate_name)
2373 continue;
2374
2375 memset(sk, 0, sizeof(*sk));
2376 sk = str2ip2(address, sk, 1);
2377 if (!sk) {
2378 ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, namerserver will be excluded.\n",
2379 resolv_linenum, address);
2380 err_code |= ERR_WARN;
2381 continue;
2382 }
2383
2384 set_host_port(sk, 53);
2385
2386 proto = protocol_by_family(sk->ss_family);
2387 if (!proto || !proto->connect) {
2388 ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
2389 resolv_linenum, address);
2390 err_code |= ERR_WARN;
2391 continue;
2392 }
2393
2394 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == 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->conf.file = strdup("/etc/resolv.conf");
2401 if (newnameserver->conf.file == NULL) {
2402 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2403 err_code |= ERR_ALERT | ERR_FATAL;
2404 goto resolv_out;
2405 }
2406
2407 newnameserver->id = strdup(address);
2408 if (newnameserver->id == NULL) {
2409 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2410 err_code |= ERR_ALERT | ERR_FATAL;
2411 goto resolv_out;
2412 }
2413
2414 newnameserver->resolvers = curr_resolvers;
2415 newnameserver->conf.line = resolv_linenum;
2416 newnameserver->addr = *sk;
2417
2418 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
2419 }
2420
2421resolv_out:
2422 free(sk);
2423 free(resolv_line);
2424 if (f != NULL)
2425 fclose(f);
2426 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002427 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2428 const char *res;
2429 unsigned int time;
2430
2431 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002432 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2433 file, linenum, args[0]);
2434 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002435 err_code |= ERR_ALERT | ERR_FATAL;
2436 goto out;
2437 }
2438 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2439 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002440 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2441 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002442 err_code |= ERR_ALERT | ERR_FATAL;
2443 goto out;
2444 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002445 if (strcmp(args[1], "nx") == 0)
2446 curr_resolvers->hold.nx = time;
2447 else if (strcmp(args[1], "other") == 0)
2448 curr_resolvers->hold.other = time;
2449 else if (strcmp(args[1], "refused") == 0)
2450 curr_resolvers->hold.refused = time;
2451 else if (strcmp(args[1], "timeout") == 0)
2452 curr_resolvers->hold.timeout = time;
2453 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002454 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002455 else if (strcmp(args[1], "obsolete") == 0)
2456 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002457 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002458 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2459 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002460 err_code |= ERR_ALERT | ERR_FATAL;
2461 goto out;
2462 }
2463
2464 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002465 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002466 int i = 0;
2467
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002468 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002469 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2470 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002471 err_code |= ERR_ALERT | ERR_FATAL;
2472 goto out;
2473 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002474
2475 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002476 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002477 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2478 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002479 err_code |= ERR_ALERT | ERR_FATAL;
2480 goto out;
2481 }
2482
2483 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002484 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002485 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002486 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2487 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002488 err_code |= ERR_WARN;
2489 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002490 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002491 else if (strcmp(args[0], "resolve_retries") == 0) {
2492 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002493 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2494 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002495 err_code |= ERR_ALERT | ERR_FATAL;
2496 goto out;
2497 }
2498 curr_resolvers->resolve_retries = atoi(args[1]);
2499 }
2500 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002501 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002502 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2503 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002504 err_code |= ERR_ALERT | ERR_FATAL;
2505 goto out;
2506 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002507 else if (strcmp(args[1], "retry") == 0 ||
2508 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002509 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002510 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002511
2512 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002513 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2514 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002515 err_code |= ERR_ALERT | ERR_FATAL;
2516 goto out;
2517 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002518 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002519 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002520 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2521 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002522 err_code |= ERR_ALERT | ERR_FATAL;
2523 goto out;
2524 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002525 if (args[1][2] == 't')
2526 curr_resolvers->timeout.retry = tout;
2527 else
2528 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002529 }
2530 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002531 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2532 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002533 err_code |= ERR_ALERT | ERR_FATAL;
2534 goto out;
2535 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002536 } /* neither "nameserver" nor "resolvers" */
2537 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002538 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002539 err_code |= ERR_ALERT | ERR_FATAL;
2540 goto out;
2541 }
2542
2543 out:
2544 free(errmsg);
2545 return err_code;
2546}
Simon Horman0d16a402015-01-30 11:22:58 +09002547
2548/*
William Lallemand51097192015-04-14 16:35:22 +02002549 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002550 * Returns the error code, 0 if OK, or any combination of :
2551 * - ERR_ABORT: must abort ASAP
2552 * - ERR_FATAL: we can continue parsing but not start the service
2553 * - ERR_WARN: a warning has been emitted
2554 * - ERR_ALERT: an alert has been emitted
2555 * Only the two first ones can stop processing, the two others are just
2556 * indicators.
2557 */
2558int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2559{
2560 static struct mailers *curmailers = NULL;
2561 struct mailer *newmailer = NULL;
2562 const char *err;
2563 int err_code = 0;
2564 char *errmsg = NULL;
2565
2566 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2567 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002568 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002569 err_code |= ERR_ALERT | ERR_ABORT;
2570 goto out;
2571 }
2572
2573 err = invalid_char(args[1]);
2574 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002575 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2576 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002577 err_code |= ERR_ALERT | ERR_ABORT;
2578 goto out;
2579 }
2580
2581 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2582 /*
2583 * If there are two proxies with the same name only following
2584 * combinations are allowed:
2585 */
2586 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002587 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2588 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002589 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002590 }
2591 }
2592
Vincent Bernat02779b62016-04-03 13:48:43 +02002593 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002594 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002595 err_code |= ERR_ALERT | ERR_ABORT;
2596 goto out;
2597 }
2598
2599 curmailers->next = mailers;
2600 mailers = curmailers;
2601 curmailers->conf.file = strdup(file);
2602 curmailers->conf.line = linenum;
2603 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002604 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2605 * But need enough time so that timeouts don't occur
2606 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002607 }
2608 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2609 struct sockaddr_storage *sk;
2610 int port1, port2;
2611 struct protocol *proto;
2612
2613 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002614 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2615 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002616 err_code |= ERR_ALERT | ERR_FATAL;
2617 goto out;
2618 }
2619
2620 err = invalid_char(args[1]);
2621 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002622 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2623 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002624 err_code |= ERR_ALERT | ERR_FATAL;
2625 goto out;
2626 }
2627
Vincent Bernat02779b62016-04-03 13:48:43 +02002628 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002629 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002630 err_code |= ERR_ALERT | ERR_ABORT;
2631 goto out;
2632 }
2633
2634 /* the mailers are linked backwards first */
2635 curmailers->count++;
2636 newmailer->next = curmailers->mailer_list;
2637 curmailers->mailer_list = newmailer;
2638 newmailer->mailers = curmailers;
2639 newmailer->conf.file = strdup(file);
2640 newmailer->conf.line = linenum;
2641
2642 newmailer->id = strdup(args[1]);
2643
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002644 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002645 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002646 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002647 err_code |= ERR_ALERT | ERR_FATAL;
2648 goto out;
2649 }
2650
2651 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002652 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002653 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2654 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002655 err_code |= ERR_ALERT | ERR_FATAL;
2656 goto out;
2657 }
2658
2659 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002660 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2661 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002662 err_code |= ERR_ALERT | ERR_FATAL;
2663 goto out;
2664 }
2665
2666 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002667 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2668 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002669 err_code |= ERR_ALERT | ERR_FATAL;
2670 goto out;
2671 }
2672
2673 newmailer->addr = *sk;
2674 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002675 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002676 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002677 }
2678 else if (strcmp(args[0], "timeout") == 0) {
2679 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002680 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2681 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002682 err_code |= ERR_ALERT | ERR_FATAL;
2683 goto out;
2684 }
2685 else if (strcmp(args[1], "mail") == 0) {
2686 const char *res;
2687 unsigned int timeout_mail;
2688 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002689 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2690 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002691 err_code |= ERR_ALERT | ERR_FATAL;
2692 goto out;
2693 }
2694 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2695 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002696 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2697 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002698 err_code |= ERR_ALERT | ERR_FATAL;
2699 goto out;
2700 }
2701 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002702 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 +01002703 err_code |= ERR_ALERT | ERR_FATAL;
2704 goto out;
2705 }
2706 curmailers->timeout.mail = timeout_mail;
2707 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002708 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002709 file, linenum, args[0], args[1]);
2710 err_code |= ERR_ALERT | ERR_FATAL;
2711 goto out;
2712 }
2713 }
Simon Horman0d16a402015-01-30 11:22:58 +09002714 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002715 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002716 err_code |= ERR_ALERT | ERR_FATAL;
2717 goto out;
2718 }
2719
2720out:
2721 free(errmsg);
2722 return err_code;
2723}
2724
Simon Horman9dc49962015-01-30 11:22:59 +09002725static void free_email_alert(struct proxy *p)
2726{
2727 free(p->email_alert.mailers.name);
2728 p->email_alert.mailers.name = NULL;
2729 free(p->email_alert.from);
2730 p->email_alert.from = NULL;
2731 free(p->email_alert.to);
2732 p->email_alert.to = NULL;
2733 free(p->email_alert.myhostname);
2734 p->email_alert.myhostname = NULL;
2735}
2736
Willy Tarreau3842f002009-06-14 11:39:52 +02002737int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002738{
2739 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002740 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002741 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002742 int rc;
2743 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002744 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002745 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002746 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002747 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002748 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002749
Willy Tarreau977b8e42006-12-29 14:19:17 +01002750 if (!strcmp(args[0], "listen"))
2751 rc = PR_CAP_LISTEN;
2752 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002753 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002754 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002755 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002756 else
2757 rc = PR_CAP_NONE;
2758
2759 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002760 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002761 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2762 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2763 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002764 err_code |= ERR_ALERT | ERR_ABORT;
2765 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002766 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002767
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002768 err = invalid_char(args[1]);
2769 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002770 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2771 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002772 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002773 }
2774
Willy Tarreau8f50b682015-05-26 11:45:02 +02002775 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2776 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002777 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2778 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2779 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002780 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002781 }
2782
Vincent Bernat02779b62016-04-03 13:48:43 +02002783 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002784 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002785 err_code |= ERR_ALERT | ERR_ABORT;
2786 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002787 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002788
Willy Tarreau97cb7802010-01-03 20:23:58 +01002789 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002790 curproxy->next = proxies_list;
2791 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002792 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2793 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002794 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002795 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002796 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002797 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002798
William Lallemand6e62fb62015-04-28 16:55:23 +02002799 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2800 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002801 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002802 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002803 }
2804
2805 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002806 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002807 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002808
Willy Tarreaubaaee002006-06-26 02:48:02 +02002809 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002810 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002811 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002812 curproxy->no_options = defproxy.no_options;
2813 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002814 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002815 curproxy->except_net = defproxy.except_net;
2816 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002817 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002818 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002819
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002820 if (defproxy.fwdfor_hdr_len) {
2821 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2822 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2823 }
2824
Willy Tarreaub86db342009-11-30 11:50:16 +01002825 if (defproxy.orgto_hdr_len) {
2826 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2827 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2828 }
2829
Mark Lamourinec2247f02012-01-04 13:02:01 -05002830 if (defproxy.server_id_hdr_len) {
2831 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2832 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2833 }
2834
Willy Tarreau977b8e42006-12-29 14:19:17 +01002835 if (curproxy->cap & PR_CAP_FE) {
2836 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002837 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002838 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002839
2840 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002841 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2842 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002843
2844 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2845 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002846
Willy Tarreau977b8e42006-12-29 14:19:17 +01002847 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002848 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002849 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002850 curproxy->fullconn = defproxy.fullconn;
2851 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002852 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002853 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002854
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002855 if (defproxy.check_req) {
2856 curproxy->check_req = calloc(1, defproxy.check_len);
2857 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2858 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002859 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002860
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002861 if (defproxy.expect_str) {
2862 curproxy->expect_str = strdup(defproxy.expect_str);
2863 if (defproxy.expect_regex) {
2864 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002865 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2866 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002867 }
2868 }
2869
Willy Tarreau67402132012-05-31 20:40:20 +02002870 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002871 if (defproxy.cookie_name)
2872 curproxy->cookie_name = strdup(defproxy.cookie_name);
2873 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002874
2875 if (defproxy.dyncookie_key)
2876 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002877 if (defproxy.cookie_domain)
2878 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002879
Willy Tarreau31936852010-10-06 16:59:56 +02002880 if (defproxy.cookie_maxidle)
2881 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2882
2883 if (defproxy.cookie_maxlife)
2884 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2885
Emeric Brun647caf12009-06-30 17:57:00 +02002886 if (defproxy.rdp_cookie_name)
2887 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2888 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2889
Willy Tarreau01732802007-11-01 22:48:15 +01002890 if (defproxy.url_param_name)
2891 curproxy->url_param_name = strdup(defproxy.url_param_name);
2892 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002893
Benoitaffb4812009-03-25 13:02:10 +01002894 if (defproxy.hh_name)
2895 curproxy->hh_name = strdup(defproxy.hh_name);
2896 curproxy->hh_len = defproxy.hh_len;
2897 curproxy->hh_match_domain = defproxy.hh_match_domain;
2898
Willy Tarreauef9a3602012-12-08 22:29:20 +01002899 if (defproxy.conn_src.iface_name)
2900 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2901 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002902 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002903#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002904 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002905#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002906 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002907 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002908
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002909 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002910 if (defproxy.capture_name)
2911 curproxy->capture_name = strdup(defproxy.capture_name);
2912 curproxy->capture_namelen = defproxy.capture_namelen;
2913 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002914 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002915
Willy Tarreau977b8e42006-12-29 14:19:17 +01002916 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002917 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002918 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002919 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002920 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002921 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002922 curproxy->mon_net = defproxy.mon_net;
2923 curproxy->mon_mask = defproxy.mon_mask;
2924 if (defproxy.monitor_uri)
2925 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2926 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002927 if (defproxy.defbe.name)
2928 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002929
2930 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002931 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2932 if (curproxy->conf.logformat_string &&
2933 curproxy->conf.logformat_string != default_http_log_format &&
2934 curproxy->conf.logformat_string != default_tcp_log_format &&
2935 curproxy->conf.logformat_string != clf_http_log_format)
2936 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2937
2938 if (defproxy.conf.lfs_file) {
2939 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2940 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2941 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002942
2943 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2944 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2945 if (curproxy->conf.logformat_sd_string &&
2946 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2947 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2948
2949 if (defproxy.conf.lfsd_file) {
2950 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2951 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2952 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002953 }
2954
2955 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002956 curproxy->timeout.connect = defproxy.timeout.connect;
2957 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002958 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002959 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002960 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002961 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002962 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002963 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002964 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002965 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002966 }
2967
Willy Tarreaubaaee002006-06-26 02:48:02 +02002968 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002969 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002970
2971 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002972 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002973 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002974 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002975 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002976 LIST_INIT(&node->list);
2977 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2978 }
2979
Willy Tarreau62a61232013-04-12 18:13:46 +02002980 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2981 if (curproxy->conf.uniqueid_format_string)
2982 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2983
Dragan Dosen43885c72015-10-01 13:18:13 +02002984 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002985
Willy Tarreau62a61232013-04-12 18:13:46 +02002986 if (defproxy.conf.uif_file) {
2987 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2988 curproxy->conf.uif_line = defproxy.conf.uif_line;
2989 }
William Lallemanda73203e2012-03-12 12:48:57 +01002990
2991 /* copy default header unique id */
2992 if (defproxy.header_unique_id)
2993 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2994
William Lallemand82fe75c2012-10-23 10:25:10 +02002995 /* default compression options */
2996 if (defproxy.comp != NULL) {
2997 curproxy->comp = calloc(1, sizeof(struct comp));
2998 curproxy->comp->algos = defproxy.comp->algos;
2999 curproxy->comp->types = defproxy.comp->types;
3000 }
3001
Willy Tarreaubaaee002006-06-26 02:48:02 +02003002 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003003 curproxy->conf.used_listener_id = EB_ROOT;
3004 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003005
Simon Horman98637e52014-06-20 12:30:16 +09003006 if (defproxy.check_path)
3007 curproxy->check_path = strdup(defproxy.check_path);
3008 if (defproxy.check_command)
3009 curproxy->check_command = strdup(defproxy.check_command);
3010
Simon Horman9dc49962015-01-30 11:22:59 +09003011 if (defproxy.email_alert.mailers.name)
3012 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
3013 if (defproxy.email_alert.from)
3014 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
3015 if (defproxy.email_alert.to)
3016 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
3017 if (defproxy.email_alert.myhostname)
3018 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003019 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003020 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003021
Willy Tarreau93893792009-07-23 13:19:11 +02003022 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003023 }
3024 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3025 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003026 /* FIXME-20070101: we should do this too at the end of the
3027 * config parsing to free all default values.
3028 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003029 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3030 err_code |= ERR_ABORT;
3031 goto out;
3032 }
3033
Willy Tarreaua534fea2008-08-03 12:19:50 +02003034 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003035 free(defproxy.check_command);
3036 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003037 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003038 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003039 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003040 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003041 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003042 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003043 free(defproxy.capture_name);
3044 free(defproxy.monitor_uri);
3045 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003046 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003047 free(defproxy.fwdfor_hdr_name);
3048 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003049 free(defproxy.orgto_hdr_name);
3050 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003051 free(defproxy.server_id_hdr_name);
3052 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003053 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003054 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003055 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003056 free(defproxy.expect_regex);
3057 defproxy.expect_regex = NULL;
3058 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003059
Willy Tarreau62a61232013-04-12 18:13:46 +02003060 if (defproxy.conf.logformat_string != default_http_log_format &&
3061 defproxy.conf.logformat_string != default_tcp_log_format &&
3062 defproxy.conf.logformat_string != clf_http_log_format)
3063 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003064
Willy Tarreau62a61232013-04-12 18:13:46 +02003065 free(defproxy.conf.uniqueid_format_string);
3066 free(defproxy.conf.lfs_file);
3067 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003068 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003069 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003070
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003071 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3072 free(defproxy.conf.logformat_sd_string);
3073 free(defproxy.conf.lfsd_file);
3074
Willy Tarreaua534fea2008-08-03 12:19:50 +02003075 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003076 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003077
Willy Tarreaubaaee002006-06-26 02:48:02 +02003078 /* we cannot free uri_auth because it might already be used */
3079 init_default_instance();
3080 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003081 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3082 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003083 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003084 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003085 }
3086 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003087 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003088 err_code |= ERR_ALERT | ERR_FATAL;
3089 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003090 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003091
3092 /* update the current file and line being parsed */
3093 curproxy->conf.args.file = curproxy->conf.file;
3094 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003095
3096 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003097 if (!strcmp(args[0], "server") ||
3098 !strcmp(args[0], "default-server") ||
3099 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003100 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3101 if (err_code & ERR_FATAL)
3102 goto out;
3103 }
3104 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003105 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003106 int cur_arg;
3107
Willy Tarreaubaaee002006-06-26 02:48:02 +02003108 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003109 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003110 err_code |= ERR_ALERT | ERR_FATAL;
3111 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003112 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003113 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003114 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003115
Willy Tarreau24709282013-03-10 21:32:12 +01003116 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003117 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3118 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003119 err_code |= ERR_ALERT | ERR_FATAL;
3120 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003121 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003122
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003123 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003124
3125 /* use default settings for unix sockets */
3126 bind_conf->ux.uid = global.unix_bind.ux.uid;
3127 bind_conf->ux.gid = global.unix_bind.ux.gid;
3128 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003129
3130 /* NOTE: the following line might create several listeners if there
3131 * are comma-separated IPs or port ranges. So all further processing
3132 * will have to be applied to all listeners created after last_listen.
3133 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003134 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3135 if (errmsg && *errmsg) {
3136 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003137 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003138 }
3139 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003140 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3141 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003142 err_code |= ERR_ALERT | ERR_FATAL;
3143 goto out;
3144 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003145
Willy Tarreau4348fad2012-09-20 16:48:07 +02003146 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3147 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003148 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003149 }
3150
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003151 cur_arg = 2;
3152 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003153 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003154 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003155 char *err;
3156
Willy Tarreau26982662012-09-12 23:17:10 +02003157 kw = bind_find_kw(args[cur_arg]);
3158 if (kw) {
3159 char *err = NULL;
3160 int code;
3161
3162 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003163 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3164 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003165 cur_arg += 1 + kw->skip ;
3166 err_code |= ERR_ALERT | ERR_FATAL;
3167 goto out;
3168 }
3169
Willy Tarreau4348fad2012-09-20 16:48:07 +02003170 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003171 err_code |= code;
3172
3173 if (code) {
3174 if (err && *err) {
3175 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003176 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003177 }
3178 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003179 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3180 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003181 if (code & ERR_FATAL) {
3182 free(err);
3183 cur_arg += 1 + kw->skip;
3184 goto out;
3185 }
3186 }
3187 free(err);
3188 cur_arg += 1 + kw->skip;
3189 continue;
3190 }
3191
Willy Tarreau8638f482012-09-18 18:01:17 +02003192 err = NULL;
3193 if (!bind_dumped) {
3194 bind_dump_kws(&err);
3195 indent_msg(&err, 4);
3196 bind_dumped = 1;
3197 }
3198
Christopher Faulet767a84b2017-11-24 16:50:31 +01003199 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3200 file, linenum, args[0], args[1], args[cur_arg],
3201 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003202 free(err);
3203
Willy Tarreau93893792009-07-23 13:19:11 +02003204 err_code |= ERR_ALERT | ERR_FATAL;
3205 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003206 }
Willy Tarreau93893792009-07-23 13:19:11 +02003207 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003208 }
3209 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003210 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003211 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3212 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003213 err_code |= ERR_ALERT | ERR_FATAL;
3214 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003215 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003216 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003217 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003218
Willy Tarreaubaaee002006-06-26 02:48:02 +02003219 /* flush useless bits */
3220 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003221 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003222 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003223 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003224 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003225 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003226
William Lallemanddf1425a2015-04-28 20:17:49 +02003227 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3228 goto out;
3229
Willy Tarreau1c47f852006-07-09 08:22:27 +02003230 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003231 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3232 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003233 err_code |= ERR_ALERT | ERR_FATAL;
3234 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003235 }
3236
Willy Tarreaua534fea2008-08-03 12:19:50 +02003237 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003238 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003239 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003240 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003241 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3242
Willy Tarreau93893792009-07-23 13:19:11 +02003243 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003244 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003245 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003246 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3247 goto out;
3248
Willy Tarreaubaaee002006-06-26 02:48:02 +02003249 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3250 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3251 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3252 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003253 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003254 err_code |= ERR_ALERT | ERR_FATAL;
3255 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003256 }
3257 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003258 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003259 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003260
3261 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003262 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003263 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003264 err_code |= ERR_ALERT | ERR_FATAL;
3265 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003266 }
3267
William Lallemanddf1425a2015-04-28 20:17:49 +02003268 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3269 goto out;
3270
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003271 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003272 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3273 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003274 err_code |= ERR_ALERT | ERR_FATAL;
3275 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003276 }
3277
3278 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003279 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003280 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003281
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003282 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003283 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3284 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003285 err_code |= ERR_ALERT | ERR_FATAL;
3286 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003287 }
3288
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003289 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3290 if (node) {
3291 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003292 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3293 file, linenum, proxy_type_str(curproxy), curproxy->id,
3294 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003295 err_code |= ERR_ALERT | ERR_FATAL;
3296 goto out;
3297 }
3298 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003299 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003300 else if (!strcmp(args[0], "description")) {
3301 int i, len=0;
3302 char *d;
3303
Cyril Bonté99ed3272010-01-24 23:29:44 +01003304 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003305 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003306 file, linenum, args[0]);
3307 err_code |= ERR_ALERT | ERR_FATAL;
3308 goto out;
3309 }
3310
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003311 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003312 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3313 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003314 return -1;
3315 }
3316
Willy Tarreau348acfe2014-04-14 15:00:39 +02003317 for (i = 1; *args[i]; i++)
3318 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003319
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003320 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003321 curproxy->desc = d;
3322
Willy Tarreau348acfe2014-04-14 15:00:39 +02003323 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3324 for (i = 2; *args[i]; i++)
3325 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003326
3327 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003328 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003329 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3330 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003331 curproxy->state = PR_STSTOPPED;
3332 }
3333 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003334 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3335 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003336 curproxy->state = PR_STNEW;
3337 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003338 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3339 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003340 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003341
3342 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003343 if (strcmp(args[cur_arg], "all") == 0) {
3344 set = 0;
3345 break;
3346 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003347 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003348 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003349 err_code |= ERR_ALERT | ERR_FATAL;
3350 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003351 }
3352 cur_arg++;
3353 }
3354 curproxy->bind_proc = set;
3355 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003356 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003357 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003358 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003359 err_code |= ERR_ALERT | ERR_FATAL;
3360 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003361 }
3362
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003363 err = invalid_char(args[1]);
3364 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003365 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3366 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003367 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003368 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003369 }
3370
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003371 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003372 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3373 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003374 err_code |= ERR_ALERT | ERR_FATAL;
3375 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003376 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003377 }
3378 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3379
3380 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3381 err_code |= ERR_WARN;
3382
3383 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003384 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3385 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003386 err_code |= ERR_ALERT | ERR_FATAL;
3387 goto out;
3388 }
3389 free(curproxy->dyncookie_key);
3390 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003391 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003392 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3393 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003394
Willy Tarreau977b8e42006-12-29 14:19:17 +01003395 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003396 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003397
Willy Tarreaubaaee002006-06-26 02:48:02 +02003398 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003399 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3400 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003401 err_code |= ERR_ALERT | ERR_FATAL;
3402 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003403 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003404
Willy Tarreau67402132012-05-31 20:40:20 +02003405 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003406 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003407 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003408 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003409 curproxy->cookie_name = strdup(args[1]);
3410 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003411
Willy Tarreaubaaee002006-06-26 02:48:02 +02003412 cur_arg = 2;
3413 while (*(args[cur_arg])) {
3414 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003415 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003416 }
3417 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003418 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003419 }
3420 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003421 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003422 }
3423 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003424 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003425 }
3426 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003427 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003428 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003429 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003430 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003431 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003432 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003433 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003434 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003435 else if (!strcmp(args[cur_arg], "httponly")) {
3436 curproxy->ck_opts |= PR_CK_HTTPONLY;
3437 }
3438 else if (!strcmp(args[cur_arg], "secure")) {
3439 curproxy->ck_opts |= PR_CK_SECURE;
3440 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003441 else if (!strcmp(args[cur_arg], "domain")) {
3442 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003443 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3444 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003445 err_code |= ERR_ALERT | ERR_FATAL;
3446 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003447 }
3448
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003449 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003450 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003451 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3452 " dots nor does not start with a dot."
3453 " RFC forbids it, this configuration may not work properly.\n",
3454 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003455 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003456 }
3457
3458 err = invalid_domainchar(args[cur_arg + 1]);
3459 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003460 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3461 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003462 err_code |= ERR_ALERT | ERR_FATAL;
3463 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003464 }
3465
Willy Tarreau68a897b2009-12-03 23:28:34 +01003466 if (!curproxy->cookie_domain) {
3467 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3468 } else {
3469 /* one domain was already specified, add another one by
3470 * building the string which will be returned along with
3471 * the cookie.
3472 */
3473 char *new_ptr;
3474 int new_len = strlen(curproxy->cookie_domain) +
3475 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3476 new_ptr = malloc(new_len);
3477 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3478 free(curproxy->cookie_domain);
3479 curproxy->cookie_domain = new_ptr;
3480 }
Willy Tarreau31936852010-10-06 16:59:56 +02003481 cur_arg++;
3482 }
3483 else if (!strcmp(args[cur_arg], "maxidle")) {
3484 unsigned int maxidle;
3485 const char *res;
3486
3487 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003488 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3489 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003490 err_code |= ERR_ALERT | ERR_FATAL;
3491 goto out;
3492 }
3493
3494 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3495 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003496 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3497 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003498 err_code |= ERR_ALERT | ERR_FATAL;
3499 goto out;
3500 }
3501 curproxy->cookie_maxidle = maxidle;
3502 cur_arg++;
3503 }
3504 else if (!strcmp(args[cur_arg], "maxlife")) {
3505 unsigned int maxlife;
3506 const char *res;
3507
3508 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003509 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3510 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003511 err_code |= ERR_ALERT | ERR_FATAL;
3512 goto out;
3513 }
3514
3515 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3516 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003517 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3518 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003519 err_code |= ERR_ALERT | ERR_FATAL;
3520 goto out;
3521 }
3522 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003523 cur_arg++;
3524 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003525 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003526
3527 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3528 err_code |= ERR_WARN;
3529 curproxy->ck_opts |= PR_CK_DYNAMIC;
3530 }
3531
Willy Tarreaubaaee002006-06-26 02:48:02 +02003532 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003533 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3534 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003535 err_code |= ERR_ALERT | ERR_FATAL;
3536 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003537 }
3538 cur_arg++;
3539 }
Willy Tarreau67402132012-05-31 20:40:20 +02003540 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003541 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3542 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003543 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003544 }
3545
Willy Tarreau67402132012-05-31 20:40:20 +02003546 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003547 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3548 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003549 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003550 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003551
Willy Tarreau67402132012-05-31 20:40:20 +02003552 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003553 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3554 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003555 err_code |= ERR_ALERT | ERR_FATAL;
3556 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003557 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003558 else if (!strcmp(args[0], "email-alert")) {
3559 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003560 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3561 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003562 err_code |= ERR_ALERT | ERR_FATAL;
3563 goto out;
3564 }
3565
3566 if (!strcmp(args[1], "from")) {
3567 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003568 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3569 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003570 err_code |= ERR_ALERT | ERR_FATAL;
3571 goto out;
3572 }
3573 free(curproxy->email_alert.from);
3574 curproxy->email_alert.from = strdup(args[2]);
3575 }
3576 else if (!strcmp(args[1], "mailers")) {
3577 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003578 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3579 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003580 err_code |= ERR_ALERT | ERR_FATAL;
3581 goto out;
3582 }
3583 free(curproxy->email_alert.mailers.name);
3584 curproxy->email_alert.mailers.name = strdup(args[2]);
3585 }
3586 else if (!strcmp(args[1], "myhostname")) {
3587 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003588 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3589 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003590 err_code |= ERR_ALERT | ERR_FATAL;
3591 goto out;
3592 }
3593 free(curproxy->email_alert.myhostname);
3594 curproxy->email_alert.myhostname = strdup(args[2]);
3595 }
Simon Horman64e34162015-02-06 11:11:57 +09003596 else if (!strcmp(args[1], "level")) {
3597 curproxy->email_alert.level = get_log_level(args[2]);
3598 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003599 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3600 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003601 err_code |= ERR_ALERT | ERR_FATAL;
3602 goto out;
3603 }
3604 }
Simon Horman9dc49962015-01-30 11:22:59 +09003605 else if (!strcmp(args[1], "to")) {
3606 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003607 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3608 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003609 err_code |= ERR_ALERT | ERR_FATAL;
3610 goto out;
3611 }
3612 free(curproxy->email_alert.to);
3613 curproxy->email_alert.to = strdup(args[2]);
3614 }
3615 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003616 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3617 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003618 err_code |= ERR_ALERT | ERR_FATAL;
3619 goto out;
3620 }
Simon Horman64e34162015-02-06 11:11:57 +09003621 /* Indicate that the email_alert is at least partially configured */
3622 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003623 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003624 else if (!strcmp(args[0], "external-check")) {
3625 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003626 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3627 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003628 err_code |= ERR_ALERT | ERR_FATAL;
3629 goto out;
3630 }
3631
3632 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003633 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003634 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003635 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003636 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3637 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003638 err_code |= ERR_ALERT | ERR_FATAL;
3639 goto out;
3640 }
3641 free(curproxy->check_command);
3642 curproxy->check_command = strdup(args[2]);
3643 }
3644 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003645 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003646 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003647 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003648 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3649 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003650 err_code |= ERR_ALERT | ERR_FATAL;
3651 goto out;
3652 }
3653 free(curproxy->check_path);
3654 curproxy->check_path = strdup(args[2]);
3655 }
3656 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003657 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3658 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003659 err_code |= ERR_ALERT | ERR_FATAL;
3660 goto out;
3661 }
3662 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003663 else if (!strcmp(args[0], "persist")) { /* persist */
3664 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003665 ha_alert("parsing [%s:%d] : missing persist method.\n",
3666 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003667 err_code |= ERR_ALERT | ERR_FATAL;
3668 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003669 }
3670
3671 if (!strncmp(args[1], "rdp-cookie", 10)) {
3672 curproxy->options2 |= PR_O2_RDPC_PRST;
3673
Emeric Brunb982a3d2010-01-04 15:45:53 +01003674 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003675 const char *beg, *end;
3676
3677 beg = args[1] + 11;
3678 end = strchr(beg, ')');
3679
William Lallemanddf1425a2015-04-28 20:17:49 +02003680 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3681 goto out;
3682
Emeric Brun647caf12009-06-30 17:57:00 +02003683 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003684 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3685 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003686 err_code |= ERR_ALERT | ERR_FATAL;
3687 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003688 }
3689
3690 free(curproxy->rdp_cookie_name);
3691 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3692 curproxy->rdp_cookie_len = end-beg;
3693 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003694 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003695 free(curproxy->rdp_cookie_name);
3696 curproxy->rdp_cookie_name = strdup("msts");
3697 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3698 }
3699 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003700 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3701 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003702 err_code |= ERR_ALERT | ERR_FATAL;
3703 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003704 }
3705 }
3706 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003707 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3708 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003709 err_code |= ERR_ALERT | ERR_FATAL;
3710 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003711 }
3712 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003713 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003714 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 +02003715 err_code |= ERR_ALERT | ERR_FATAL;
3716 goto out;
3717 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003718 else if (!strcmp(args[0], "load-server-state-from-file")) {
3719 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3720 err_code |= ERR_WARN;
3721 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3722 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3723 }
3724 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3725 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3726 }
3727 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3728 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3729 }
3730 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003731 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3732 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003733 err_code |= ERR_ALERT | ERR_FATAL;
3734 goto out;
3735 }
3736 }
3737 else if (!strcmp(args[0], "server-state-file-name")) {
3738 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3739 err_code |= ERR_WARN;
3740 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003741 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3742 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003743 err_code |= ERR_ALERT | ERR_FATAL;
3744 goto out;
3745 }
3746 else if (!strcmp(args[1], "use-backend-name"))
3747 curproxy->server_state_file_name = strdup(curproxy->id);
3748 else
3749 curproxy->server_state_file_name = strdup(args[1]);
3750 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003751 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003752 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003753 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003754
Willy Tarreaubaaee002006-06-26 02:48:02 +02003755 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003756 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003757 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 +01003758 err_code |= ERR_ALERT | ERR_FATAL;
3759 goto out;
3760 }
3761
William Lallemand1a748ae2015-05-19 16:37:23 +02003762 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3763 goto out;
3764
Willy Tarreaubaaee002006-06-26 02:48:02 +02003765 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003766 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3767 file, linenum, args[0]);
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 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003771 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003772 curproxy->capture_name = strdup(args[2]);
3773 curproxy->capture_namelen = strlen(curproxy->capture_name);
3774 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003775 curproxy->to_log |= LW_COOKIE;
3776 }
3777 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3778 struct cap_hdr *hdr;
3779
3780 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003781 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 +02003782 err_code |= ERR_ALERT | ERR_FATAL;
3783 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003784 }
3785
William Lallemand1a748ae2015-05-19 16:37:23 +02003786 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3787 goto out;
3788
Willy Tarreaubaaee002006-06-26 02:48:02 +02003789 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003790 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3791 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003792 err_code |= ERR_ALERT | ERR_FATAL;
3793 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003794 }
3795
Vincent Bernat02779b62016-04-03 13:48:43 +02003796 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003797 hdr->next = curproxy->req_cap;
3798 hdr->name = strdup(args[3]);
3799 hdr->namelen = strlen(args[3]);
3800 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003801 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003802 hdr->index = curproxy->nb_req_cap++;
3803 curproxy->req_cap = hdr;
3804 curproxy->to_log |= LW_REQHDR;
3805 }
3806 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3807 struct cap_hdr *hdr;
3808
3809 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003810 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 +02003811 err_code |= ERR_ALERT | ERR_FATAL;
3812 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003813 }
3814
William Lallemand1a748ae2015-05-19 16:37:23 +02003815 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3816 goto out;
3817
Willy Tarreaubaaee002006-06-26 02:48:02 +02003818 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003819 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3820 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003821 err_code |= ERR_ALERT | ERR_FATAL;
3822 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003823 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003824 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003825 hdr->next = curproxy->rsp_cap;
3826 hdr->name = strdup(args[3]);
3827 hdr->namelen = strlen(args[3]);
3828 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003829 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003830 hdr->index = curproxy->nb_rsp_cap++;
3831 curproxy->rsp_cap = hdr;
3832 curproxy->to_log |= LW_RSPHDR;
3833 }
3834 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003835 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\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 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003841 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003842 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003843 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003844
William Lallemanddf1425a2015-04-28 20:17:49 +02003845 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3846 goto out;
3847
Willy Tarreaubaaee002006-06-26 02:48:02 +02003848 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003849 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3850 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003851 err_code |= ERR_ALERT | ERR_FATAL;
3852 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003853 }
3854 curproxy->conn_retries = atol(args[1]);
3855 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003856 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003857 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003858
3859 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003860 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003861 err_code |= ERR_ALERT | ERR_FATAL;
3862 goto out;
3863 }
3864
Willy Tarreau20b0de52012-12-24 15:45:22 +01003865 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003866 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003867 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3868 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3869 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3870 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003871 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3872 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003873 err_code |= ERR_WARN;
3874 }
3875
Willy Tarreauff011f22011-01-06 17:51:27 +01003876 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003877
Willy Tarreauff011f22011-01-06 17:51:27 +01003878 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003879 err_code |= ERR_ALERT | ERR_ABORT;
3880 goto out;
3881 }
3882
Willy Tarreau5002f572014-04-23 01:32:02 +02003883 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003884 err_code |= warnif_cond_conflicts(rule->cond,
3885 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3886 file, linenum);
3887
Willy Tarreauff011f22011-01-06 17:51:27 +01003888 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003889 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003890 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003891 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003892
3893 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003894 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003895 err_code |= ERR_ALERT | ERR_FATAL;
3896 goto out;
3897 }
3898
3899 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003900 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003901 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3902 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003903 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3904 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003905 err_code |= ERR_WARN;
3906 }
3907
3908 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3909
3910 if (!rule) {
3911 err_code |= ERR_ALERT | ERR_ABORT;
3912 goto out;
3913 }
3914
3915 err_code |= warnif_cond_conflicts(rule->cond,
3916 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3917 file, linenum);
3918
3919 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3920 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003921 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3922 /* set the header name and length into the proxy structure */
3923 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3924 err_code |= ERR_WARN;
3925
3926 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003927 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3928 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003929 err_code |= ERR_ALERT | ERR_FATAL;
3930 goto out;
3931 }
3932
3933 /* set the desired header name */
3934 free(curproxy->server_id_hdr_name);
3935 curproxy->server_id_hdr_name = strdup(args[1]);
3936 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3937 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003938 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003939 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003940
Willy Tarreaub099aca2008-10-12 17:26:37 +02003941 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003942 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003943 err_code |= ERR_ALERT | ERR_FATAL;
3944 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003945 }
3946
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003947 /* emulate "block" using "http-request block". Since these rules are supposed to
3948 * be processed before all http-request rules, we put them into their own list
3949 * and will insert them at the end.
3950 */
3951 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3952 if (!rule) {
3953 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003954 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003955 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003956 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3957 err_code |= warnif_cond_conflicts(rule->cond,
3958 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3959 file, linenum);
3960 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003961
3962 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003963 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 +02003964
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003965 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003966 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003967 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003968
Cyril Bonté99ed3272010-01-24 23:29:44 +01003969 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003970 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003971 err_code |= ERR_ALERT | ERR_FATAL;
3972 goto out;
3973 }
3974
Willy Tarreaube4653b2015-05-28 15:26:58 +02003975 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003976 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3977 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003978 err_code |= ERR_ALERT | ERR_FATAL;
3979 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003980 }
3981
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003982 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003983 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003984 err_code |= warnif_cond_conflicts(rule->cond,
3985 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3986 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003987 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003988 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003989 struct switching_rule *rule;
3990
Willy Tarreaub099aca2008-10-12 17:26:37 +02003991 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003992 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003993 err_code |= ERR_ALERT | ERR_FATAL;
3994 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003995 }
3996
Willy Tarreau55ea7572007-06-17 19:56:27 +02003997 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003998 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003999
4000 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004001 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004002 err_code |= ERR_ALERT | ERR_FATAL;
4003 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02004004 }
4005
Willy Tarreauf51658d2014-04-23 01:21:56 +02004006 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004007 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004008 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4009 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02004010 err_code |= ERR_ALERT | ERR_FATAL;
4011 goto out;
4012 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004013
Willy Tarreauf51658d2014-04-23 01:21:56 +02004014 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004015 }
Willy Tarreau4f862642017-02-28 09:34:39 +01004016 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004017 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
4018 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004019 err_code |= ERR_ALERT | ERR_FATAL;
4020 goto out;
4021 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004022
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004023 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004024 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004025 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004026 goto out;
4027 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004028 rule->cond = cond;
4029 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004030 rule->line = linenum;
4031 rule->file = strdup(file);
4032 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004033 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004034 goto out;
4035 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004036 LIST_INIT(&rule->list);
4037 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4038 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004039 else if (strcmp(args[0], "use-server") == 0) {
4040 struct server_rule *rule;
4041
4042 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004043 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004044 err_code |= ERR_ALERT | ERR_FATAL;
4045 goto out;
4046 }
4047
4048 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4049 err_code |= ERR_WARN;
4050
4051 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004052 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004053 err_code |= ERR_ALERT | ERR_FATAL;
4054 goto out;
4055 }
4056
4057 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004058 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4059 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004060 err_code |= ERR_ALERT | ERR_FATAL;
4061 goto out;
4062 }
4063
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004064 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004065 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4066 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004067 err_code |= ERR_ALERT | ERR_FATAL;
4068 goto out;
4069 }
4070
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004071 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004072
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004073 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004074 rule->cond = cond;
4075 rule->srv.name = strdup(args[1]);
4076 LIST_INIT(&rule->list);
4077 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4078 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4079 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004080 else if ((!strcmp(args[0], "force-persist")) ||
4081 (!strcmp(args[0], "ignore-persist"))) {
4082 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004083
4084 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004085 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004086 err_code |= ERR_ALERT | ERR_FATAL;
4087 goto out;
4088 }
4089
Cyril Bonté4288c5a2018-03-12 22:02:59 +01004090 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01004091 err_code |= ERR_WARN;
4092
Willy Tarreauef6494c2010-01-28 17:12:36 +01004093 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004094 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4095 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004096 err_code |= ERR_ALERT | ERR_FATAL;
4097 goto out;
4098 }
4099
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004100 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004101 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4102 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004103 err_code |= ERR_ALERT | ERR_FATAL;
4104 goto out;
4105 }
4106
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004107 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4108 * where force-persist is applied.
4109 */
4110 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004111
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004112 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004113 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004114 if (!strcmp(args[0], "force-persist")) {
4115 rule->type = PERSIST_TYPE_FORCE;
4116 } else {
4117 rule->type = PERSIST_TYPE_IGNORE;
4118 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004119 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004120 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004121 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004122 else if (!strcmp(args[0], "stick-table")) {
4123 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004124 struct proxy *other;
4125
Willy Tarreauc7867682018-07-27 10:26:22 +02004126 if (curproxy == &defproxy) {
4127 ha_alert("parsing [%s:%d] : 'stick-table' is not supported in 'defaults' section.\n",
4128 file, linenum);
4129 err_code |= ERR_ALERT | ERR_FATAL;
4130 goto out;
4131 }
4132
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004133 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004134 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004135 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4136 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004137 err_code |= ERR_ALERT | ERR_FATAL;
4138 goto out;
4139 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004140
Emeric Brun32da3c42010-09-23 18:39:19 +02004141 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004142 curproxy->table.type = (unsigned int)-1;
4143 while (*args[myidx]) {
4144 const char *err;
4145
4146 if (strcmp(args[myidx], "size") == 0) {
4147 myidx++;
4148 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004149 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4150 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004151 err_code |= ERR_ALERT | ERR_FATAL;
4152 goto out;
4153 }
4154 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004155 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4156 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004157 err_code |= ERR_ALERT | ERR_FATAL;
4158 goto out;
4159 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004160 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004161 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004162 else if (strcmp(args[myidx], "peers") == 0) {
4163 myidx++;
Godbach50523162013-12-11 19:48:57 +08004164 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004165 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4166 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004167 err_code |= ERR_ALERT | ERR_FATAL;
4168 goto out;
Godbach50523162013-12-11 19:48:57 +08004169 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004170 curproxy->table.peers.name = strdup(args[myidx++]);
4171 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004172 else if (strcmp(args[myidx], "expire") == 0) {
4173 myidx++;
4174 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004175 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4176 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004177 err_code |= ERR_ALERT | ERR_FATAL;
4178 goto out;
4179 }
4180 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4181 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004182 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4183 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004184 err_code |= ERR_ALERT | ERR_FATAL;
4185 goto out;
4186 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004187 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004188 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4189 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004190 err_code |= ERR_ALERT | ERR_FATAL;
4191 goto out;
4192 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004193 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004194 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004195 }
4196 else if (strcmp(args[myidx], "nopurge") == 0) {
4197 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004198 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004199 }
4200 else if (strcmp(args[myidx], "type") == 0) {
4201 myidx++;
4202 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004203 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4204 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004205 err_code |= ERR_ALERT | ERR_FATAL;
4206 goto out;
4207 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004208 /* myidx already points to next arg */
4209 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004210 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004211 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004212 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004213
4214 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004215 nw = args[myidx];
4216 while (*nw) {
4217 /* the "store" keyword supports a comma-separated list */
4218 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004219 sa = NULL; /* store arg */
4220 while (*nw && *nw != ',') {
4221 if (*nw == '(') {
4222 *nw = 0;
4223 sa = ++nw;
4224 while (*nw != ')') {
4225 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004226 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4227 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004228 err_code |= ERR_ALERT | ERR_FATAL;
4229 goto out;
4230 }
4231 nw++;
4232 }
4233 *nw = '\0';
4234 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004235 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004236 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004237 if (*nw)
4238 *nw++ = '\0';
4239 type = stktable_get_data_type(cw);
4240 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004241 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4242 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004243 err_code |= ERR_ALERT | ERR_FATAL;
4244 goto out;
4245 }
Willy Tarreauac782882010-06-20 10:41:54 +02004246
4247 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4248 switch (err) {
4249 case PE_NONE: break;
4250 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004251 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4252 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004253 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004254 break;
4255
4256 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004257 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4258 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004259 err_code |= ERR_ALERT | ERR_FATAL;
4260 goto out;
4261
4262 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004263 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4264 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004265 err_code |= ERR_ALERT | ERR_FATAL;
4266 goto out;
4267
4268 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004269 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4270 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004271 err_code |= ERR_ALERT | ERR_FATAL;
4272 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004273 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004274 }
4275 myidx++;
4276 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004277 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004278 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4279 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004280 err_code |= ERR_ALERT | ERR_FATAL;
4281 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004282 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004283 }
4284
4285 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004286 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4287 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004288 err_code |= ERR_ALERT | ERR_FATAL;
4289 goto out;
4290 }
4291
4292 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004293 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4294 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004295 err_code |= ERR_ALERT | ERR_FATAL;
4296 goto out;
4297 }
4298 }
4299 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004300 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004301 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004302 int myidx = 0;
4303 const char *name = NULL;
4304 int flags;
4305
4306 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004307 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004308 err_code |= ERR_ALERT | ERR_FATAL;
4309 goto out;
4310 }
4311
4312 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4313 err_code |= ERR_WARN;
4314 goto out;
4315 }
4316
4317 myidx++;
4318 if ((strcmp(args[myidx], "store") == 0) ||
4319 (strcmp(args[myidx], "store-request") == 0)) {
4320 myidx++;
4321 flags = STK_IS_STORE;
4322 }
4323 else if (strcmp(args[myidx], "store-response") == 0) {
4324 myidx++;
4325 flags = STK_IS_STORE | STK_ON_RSP;
4326 }
4327 else if (strcmp(args[myidx], "match") == 0) {
4328 myidx++;
4329 flags = STK_IS_MATCH;
4330 }
4331 else if (strcmp(args[myidx], "on") == 0) {
4332 myidx++;
4333 flags = STK_IS_MATCH | STK_IS_STORE;
4334 }
4335 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004336 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004337 err_code |= ERR_ALERT | ERR_FATAL;
4338 goto out;
4339 }
4340
4341 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004342 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004343 err_code |= ERR_ALERT | ERR_FATAL;
4344 goto out;
4345 }
4346
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004347 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004348 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004349 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004350 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004351 err_code |= ERR_ALERT | ERR_FATAL;
4352 goto out;
4353 }
4354
4355 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004356 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004357 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4358 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004359 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004360 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004361 goto out;
4362 }
4363 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004364 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004365 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4366 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004367 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004368 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004369 goto out;
4370 }
4371 }
4372
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004373 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004374 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004375
Emeric Brunb982a3d2010-01-04 15:45:53 +01004376 if (strcmp(args[myidx], "table") == 0) {
4377 myidx++;
4378 name = args[myidx++];
4379 }
4380
Willy Tarreauef6494c2010-01-28 17:12:36 +01004381 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004382 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004383 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4384 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004385 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004386 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004387 goto out;
4388 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004389 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004390 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004391 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4392 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004393 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004394 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004395 goto out;
4396 }
Emeric Brun97679e72010-09-23 17:56:44 +02004397 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004398 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004399 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004400 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004401
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004402 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004403 rule->cond = cond;
4404 rule->expr = expr;
4405 rule->flags = flags;
4406 rule->table.name = name ? strdup(name) : NULL;
4407 LIST_INIT(&rule->list);
4408 if (flags & STK_ON_RSP)
4409 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4410 else
4411 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4412 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004413 else if (!strcmp(args[0], "stats")) {
4414 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4415 curproxy->uri_auth = NULL; /* we must detach from the default config */
4416
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004417 if (!*args[1]) {
4418 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004419 } else if (!strcmp(args[1], "admin")) {
4420 struct stats_admin_rule *rule;
4421
4422 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004423 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 +02004424 err_code |= ERR_ALERT | ERR_FATAL;
4425 goto out;
4426 }
4427
4428 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004429 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004430 err_code |= ERR_ALERT | ERR_ABORT;
4431 goto out;
4432 }
4433
4434 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004435 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4436 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004437 err_code |= ERR_ALERT | ERR_FATAL;
4438 goto out;
4439 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004440 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004441 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4442 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004443 err_code |= ERR_ALERT | ERR_FATAL;
4444 goto out;
4445 }
4446
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004447 err_code |= warnif_cond_conflicts(cond,
4448 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4449 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004450
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004451 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004452 rule->cond = cond;
4453 LIST_INIT(&rule->list);
4454 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004455 } else if (!strcmp(args[1], "uri")) {
4456 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004457 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004458 err_code |= ERR_ALERT | ERR_FATAL;
4459 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004460 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004461 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004462 err_code |= ERR_ALERT | ERR_ABORT;
4463 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004464 }
4465 } else if (!strcmp(args[1], "realm")) {
4466 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004467 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004468 err_code |= ERR_ALERT | ERR_FATAL;
4469 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004470 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
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 Tarreaubaaee002006-06-26 02:48:02 +02004474 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004475 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004476 unsigned interval;
4477
4478 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4479 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004480 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4481 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004482 err_code |= ERR_ALERT | ERR_FATAL;
4483 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004484 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004485 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004486 err_code |= ERR_ALERT | ERR_ABORT;
4487 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004488 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004489 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004490 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004491
4492 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004493 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004494 err_code |= ERR_ALERT | ERR_FATAL;
4495 goto out;
4496 }
4497
4498 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004499 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004500 err_code |= ERR_ALERT | ERR_ABORT;
4501 goto out;
4502 }
4503
Willy Tarreauff011f22011-01-06 17:51:27 +01004504 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004505 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004506 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4507 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004508 err_code |= ERR_WARN;
4509 }
4510
Willy Tarreauff011f22011-01-06 17:51:27 +01004511 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004512
Willy Tarreauff011f22011-01-06 17:51:27 +01004513 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004514 err_code |= ERR_ALERT | ERR_ABORT;
4515 goto out;
4516 }
4517
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004518 err_code |= warnif_cond_conflicts(rule->cond,
4519 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4520 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004521 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004522
Willy Tarreaubaaee002006-06-26 02:48:02 +02004523 } else if (!strcmp(args[1], "auth")) {
4524 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004525 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004526 err_code |= ERR_ALERT | ERR_FATAL;
4527 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004528 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004529 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004530 err_code |= ERR_ALERT | ERR_ABORT;
4531 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004532 }
4533 } else if (!strcmp(args[1], "scope")) {
4534 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004535 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004536 err_code |= ERR_ALERT | ERR_FATAL;
4537 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004538 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004539 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004540 err_code |= ERR_ALERT | ERR_ABORT;
4541 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004542 }
4543 } else if (!strcmp(args[1], "enable")) {
4544 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004545 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004546 err_code |= ERR_ALERT | ERR_ABORT;
4547 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004548 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004549 } else if (!strcmp(args[1], "hide-version")) {
4550 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004551 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004552 err_code |= ERR_ALERT | ERR_ABORT;
4553 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004554 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004555 } else if (!strcmp(args[1], "show-legends")) {
4556 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004557 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004558 err_code |= ERR_ALERT | ERR_ABORT;
4559 goto out;
4560 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004561 } else if (!strcmp(args[1], "show-node")) {
4562
4563 if (*args[2]) {
4564 int i;
4565 char c;
4566
4567 for (i=0; args[2][i]; i++) {
4568 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004569 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4570 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004571 break;
4572 }
4573
4574 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004575 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4576 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4577 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004578 err_code |= ERR_ALERT | ERR_FATAL;
4579 goto out;
4580 }
4581 }
4582
4583 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004584 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004585 err_code |= ERR_ALERT | ERR_ABORT;
4586 goto out;
4587 }
4588 } else if (!strcmp(args[1], "show-desc")) {
4589 char *desc = NULL;
4590
4591 if (*args[2]) {
4592 int i, len=0;
4593 char *d;
4594
Willy Tarreau348acfe2014-04-14 15:00:39 +02004595 for (i = 2; *args[i]; i++)
4596 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004597
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004598 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004599
Willy Tarreau348acfe2014-04-14 15:00:39 +02004600 d += snprintf(d, desc + len - d, "%s", args[2]);
4601 for (i = 3; *args[i]; i++)
4602 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004603 }
4604
4605 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004606 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4607 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004608 else {
4609 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4610 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004611 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004612 err_code |= ERR_ALERT | ERR_ABORT;
4613 goto out;
4614 }
4615 free(desc);
4616 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004617 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004618stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004619 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4620 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004621 err_code |= ERR_ALERT | ERR_FATAL;
4622 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004623 }
4624 }
4625 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004626 int optnum;
4627
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004628 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004629 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4630 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004631 err_code |= ERR_ALERT | ERR_FATAL;
4632 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004633 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004634
4635 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4636 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004637 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004638 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4639 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004640 err_code |= ERR_ALERT | ERR_FATAL;
4641 goto out;
4642 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004643 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4644 goto out;
4645
Willy Tarreau93893792009-07-23 13:19:11 +02004646 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4647 err_code |= ERR_WARN;
4648 goto out;
4649 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004650
Willy Tarreau3842f002009-06-14 11:39:52 +02004651 curproxy->no_options &= ~cfg_opts[optnum].val;
4652 curproxy->options &= ~cfg_opts[optnum].val;
4653
4654 switch (kwm) {
4655 case KWM_STD:
4656 curproxy->options |= cfg_opts[optnum].val;
4657 break;
4658 case KWM_NO:
4659 curproxy->no_options |= cfg_opts[optnum].val;
4660 break;
4661 case KWM_DEF: /* already cleared */
4662 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004663 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004664
Willy Tarreau93893792009-07-23 13:19:11 +02004665 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004666 }
4667 }
4668
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004669 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4670 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004671 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004672 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4673 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004674 err_code |= ERR_ALERT | ERR_FATAL;
4675 goto out;
4676 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004677 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4678 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004679 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4680 err_code |= ERR_WARN;
4681 goto out;
4682 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004683
Willy Tarreau3842f002009-06-14 11:39:52 +02004684 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4685 curproxy->options2 &= ~cfg_opts2[optnum].val;
4686
4687 switch (kwm) {
4688 case KWM_STD:
4689 curproxy->options2 |= cfg_opts2[optnum].val;
4690 break;
4691 case KWM_NO:
4692 curproxy->no_options2 |= cfg_opts2[optnum].val;
4693 break;
4694 case KWM_DEF: /* already cleared */
4695 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004696 }
Willy Tarreau93893792009-07-23 13:19:11 +02004697 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004698 }
4699 }
4700
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004701 /* HTTP options override each other. They can be cancelled using
4702 * "no option xxx" which only switches to default mode if the mode
4703 * was this one (useful for cancelling options set in defaults
4704 * sections).
4705 */
4706 if (strcmp(args[1], "httpclose") == 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_PCL;
4712 goto out;
4713 }
4714 else if (kwm == KWM_NO) {
4715 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4716 curproxy->options &= ~PR_O_HTTP_MODE;
4717 goto out;
4718 }
4719 }
4720 else if (strcmp(args[1], "forceclose") == 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_FCL;
4726 goto out;
4727 }
4728 else if (kwm == KWM_NO) {
4729 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4730 curproxy->options &= ~PR_O_HTTP_MODE;
4731 goto out;
4732 }
4733 }
4734 else if (strcmp(args[1], "http-server-close") == 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_SCL;
4740 goto out;
4741 }
4742 else if (kwm == KWM_NO) {
4743 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4744 curproxy->options &= ~PR_O_HTTP_MODE;
4745 goto out;
4746 }
4747 }
4748 else if (strcmp(args[1], "http-keep-alive") == 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_KAL;
4754 goto out;
4755 }
4756 else if (kwm == KWM_NO) {
4757 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4758 curproxy->options &= ~PR_O_HTTP_MODE;
4759 goto out;
4760 }
4761 }
4762 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004763 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4764 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004765 if (kwm == KWM_STD) {
4766 curproxy->options &= ~PR_O_HTTP_MODE;
4767 curproxy->options |= PR_O_HTTP_TUN;
4768 goto out;
4769 }
4770 else if (kwm == KWM_NO) {
4771 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4772 curproxy->options &= ~PR_O_HTTP_MODE;
4773 goto out;
4774 }
4775 }
4776
Joseph Lynch726ab712015-05-11 23:25:34 -07004777 /* Redispatch can take an integer argument that control when the
4778 * resispatch occurs. All values are relative to the retries option.
4779 * This can be cancelled using "no option xxx".
4780 */
4781 if (strcmp(args[1], "redispatch") == 0) {
4782 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4783 err_code |= ERR_WARN;
4784 goto out;
4785 }
4786
4787 curproxy->no_options &= ~PR_O_REDISP;
4788 curproxy->options &= ~PR_O_REDISP;
4789
4790 switch (kwm) {
4791 case KWM_STD:
4792 curproxy->options |= PR_O_REDISP;
4793 curproxy->redispatch_after = -1;
4794 if(*args[2]) {
4795 curproxy->redispatch_after = atol(args[2]);
4796 }
4797 break;
4798 case KWM_NO:
4799 curproxy->no_options |= PR_O_REDISP;
4800 curproxy->redispatch_after = 0;
4801 break;
4802 case KWM_DEF: /* already cleared */
4803 break;
4804 }
4805 goto out;
4806 }
4807
Willy Tarreau3842f002009-06-14 11:39:52 +02004808 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004809 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4810 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004811 err_code |= ERR_ALERT | ERR_FATAL;
4812 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004813 }
4814
Emeric Brun3a058f32009-06-30 18:26:00 +02004815 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004816 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004817 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004818 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004819 if (*(args[2]) != '\0') {
4820 if (!strcmp(args[2], "clf")) {
4821 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004822 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004823 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004824 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004825 err_code |= ERR_ALERT | ERR_FATAL;
4826 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004827 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004828 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4829 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004830 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004831 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4832 char *oldlogformat = "log-format";
4833 char *clflogformat = "";
4834
4835 if (curproxy->conf.logformat_string == default_http_log_format)
4836 oldlogformat = "option httplog";
4837 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4838 oldlogformat = "option tcplog";
4839 else if (curproxy->conf.logformat_string == clf_http_log_format)
4840 oldlogformat = "option httplog clf";
4841 if (logformat == clf_http_log_format)
4842 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004843 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4844 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004845 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004846 if (curproxy->conf.logformat_string != default_http_log_format &&
4847 curproxy->conf.logformat_string != default_tcp_log_format &&
4848 curproxy->conf.logformat_string != clf_http_log_format)
4849 free(curproxy->conf.logformat_string);
4850 curproxy->conf.logformat_string = logformat;
4851
4852 free(curproxy->conf.lfs_file);
4853 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4854 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004855
4856 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4857 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4858 file, linenum, curproxy->id);
4859 err_code |= ERR_WARN;
4860 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004861 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004862 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004863 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4864 char *oldlogformat = "log-format";
4865
4866 if (curproxy->conf.logformat_string == default_http_log_format)
4867 oldlogformat = "option httplog";
4868 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4869 oldlogformat = "option tcplog";
4870 else if (curproxy->conf.logformat_string == clf_http_log_format)
4871 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004872 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4873 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004874 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004875 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004876 if (curproxy->conf.logformat_string != default_http_log_format &&
4877 curproxy->conf.logformat_string != default_tcp_log_format &&
4878 curproxy->conf.logformat_string != clf_http_log_format)
4879 free(curproxy->conf.logformat_string);
4880 curproxy->conf.logformat_string = default_tcp_log_format;
4881
4882 free(curproxy->conf.lfs_file);
4883 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4884 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004885
4886 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4887 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004888
4889 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4890 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4891 file, linenum, curproxy->id);
4892 err_code |= ERR_WARN;
4893 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004894 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004895 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004896 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004897 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004898 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004899
William Lallemanddf1425a2015-04-28 20:17:49 +02004900 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4901 goto out;
4902
Willy Tarreau13943ab2006-12-31 00:24:10 +01004903 if (curproxy->cap & PR_CAP_FE)
4904 curproxy->options |= PR_O_TCP_CLI_KA;
4905 if (curproxy->cap & PR_CAP_BE)
4906 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004907 }
4908 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004909 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004910 err_code |= ERR_WARN;
4911
Willy Tarreaubaaee002006-06-26 02:48:02 +02004912 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004913 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004914 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004915 curproxy->options2 &= ~PR_O2_CHK_ANY;
4916 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004917 if (!*args[2]) { /* no argument */
4918 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4919 curproxy->check_len = strlen(DEF_CHECK_REQ);
4920 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004921 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004922 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004923 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004924 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004925 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004926 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004927 if (*args[4])
4928 reqlen += strlen(args[4]);
4929 else
4930 reqlen += strlen("HTTP/1.0");
4931
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004932 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004933 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004934 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004935 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004936 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4937 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004938 }
4939 else if (!strcmp(args[1], "ssl-hello-chk")) {
4940 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004941 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004942 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004943
Willy Tarreaua534fea2008-08-03 12:19:50 +02004944 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004945 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004946 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004947 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004948
4949 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4950 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004951 }
Willy Tarreau23677902007-05-08 23:50:35 +02004952 else if (!strcmp(args[1], "smtpchk")) {
4953 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004954 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004955 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004956 curproxy->options2 &= ~PR_O2_CHK_ANY;
4957 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004958
4959 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4960 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4961 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4962 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4963 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4964 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004965 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004966 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4967 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4968 } else {
4969 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4970 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4971 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4972 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4973 }
4974 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004975 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4976 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004977 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004978 else if (!strcmp(args[1], "pgsql-check")) {
4979 /* use PostgreSQL request to check servers' health */
4980 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4981 err_code |= ERR_WARN;
4982
4983 free(curproxy->check_req);
4984 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004985 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004986 curproxy->options2 |= PR_O2_PGSQL_CHK;
4987
4988 if (*(args[2])) {
4989 int cur_arg = 2;
4990
4991 while (*(args[cur_arg])) {
4992 if (strcmp(args[cur_arg], "user") == 0) {
4993 char * packet;
4994 uint32_t packet_len;
4995 uint32_t pv;
4996
4997 /* suboption header - needs additional argument for it */
4998 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004999 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5000 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005001 err_code |= ERR_ALERT | ERR_FATAL;
5002 goto out;
5003 }
5004
5005 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
5006 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
5007 pv = htonl(0x30000); /* protocol version 3.0 */
5008
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005009 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005010
5011 memcpy(packet + 4, &pv, 4);
5012
5013 /* copy "user" */
5014 memcpy(packet + 8, "user", 4);
5015
5016 /* copy username */
5017 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
5018
5019 free(curproxy->check_req);
5020 curproxy->check_req = packet;
5021 curproxy->check_len = packet_len;
5022
5023 packet_len = htonl(packet_len);
5024 memcpy(packet, &packet_len, 4);
5025 cur_arg += 2;
5026 } else {
5027 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005028 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5029 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005030 err_code |= ERR_ALERT | ERR_FATAL;
5031 goto out;
5032 }
5033 } /* end while loop */
5034 }
William Lallemanddf1425a2015-04-28 20:17:49 +02005035 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
5036 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005037 }
5038
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005039 else if (!strcmp(args[1], "redis-check")) {
5040 /* use REDIS PING request to check servers' health */
5041 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5042 err_code |= ERR_WARN;
5043
5044 free(curproxy->check_req);
5045 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005046 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005047 curproxy->options2 |= PR_O2_REDIS_CHK;
5048
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005049 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005050 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5051 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005052
5053 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5054 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005055 }
5056
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005057 else if (!strcmp(args[1], "mysql-check")) {
5058 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005059 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5060 err_code |= ERR_WARN;
5061
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005062 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005063 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005064 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005065 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005066
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005067 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005068 * const char mysql40_client_auth_pkt[] = {
5069 * "\x0e\x00\x00" // packet length
5070 * "\x01" // packet number
5071 * "\x00\x00" // client capabilities
5072 * "\x00\x00\x01" // max packet
5073 * "haproxy\x00" // username (null terminated string)
5074 * "\x00" // filler (always 0x00)
5075 * "\x01\x00\x00" // packet length
5076 * "\x00" // packet number
5077 * "\x01" // COM_QUIT command
5078 * };
5079 */
5080
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005081 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5082 * const char mysql41_client_auth_pkt[] = {
5083 * "\x0e\x00\x00\" // packet length
5084 * "\x01" // packet number
5085 * "\x00\x00\x00\x00" // client capabilities
5086 * "\x00\x00\x00\x01" // max packet
5087 * "\x21" // character set (UTF-8)
5088 * char[23] // All zeroes
5089 * "haproxy\x00" // username (null terminated string)
5090 * "\x00" // filler (always 0x00)
5091 * "\x01\x00\x00" // packet length
5092 * "\x00" // packet number
5093 * "\x01" // COM_QUIT command
5094 * };
5095 */
5096
5097
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005098 if (*(args[2])) {
5099 int cur_arg = 2;
5100
5101 while (*(args[cur_arg])) {
5102 if (strcmp(args[cur_arg], "user") == 0) {
5103 char *mysqluser;
5104 int packetlen, reqlen, userlen;
5105
5106 /* suboption header - needs additional argument for it */
5107 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005108 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5109 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005110 err_code |= ERR_ALERT | ERR_FATAL;
5111 goto out;
5112 }
5113 mysqluser = args[cur_arg + 1];
5114 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005115
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005116 if (*(args[cur_arg+2])) {
5117 if (!strcmp(args[cur_arg+2], "post-41")) {
5118 packetlen = userlen + 7 + 27;
5119 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005120
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005121 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005122 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005123 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005124
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005125 snprintf(curproxy->check_req, 4, "%c%c%c",
5126 ((unsigned char) packetlen & 0xff),
5127 ((unsigned char) (packetlen >> 8) & 0xff),
5128 ((unsigned char) (packetlen >> 16) & 0xff));
5129
5130 curproxy->check_req[3] = 1;
5131 curproxy->check_req[5] = 130;
5132 curproxy->check_req[11] = 1;
5133 curproxy->check_req[12] = 33;
5134 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5135 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5136 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5137 cur_arg += 3;
5138 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005139 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 +02005140 err_code |= ERR_ALERT | ERR_FATAL;
5141 goto out;
5142 }
5143 } else {
5144 packetlen = userlen + 7;
5145 reqlen = packetlen + 9;
5146
5147 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005148 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005149 curproxy->check_len = reqlen;
5150
5151 snprintf(curproxy->check_req, 4, "%c%c%c",
5152 ((unsigned char) packetlen & 0xff),
5153 ((unsigned char) (packetlen >> 8) & 0xff),
5154 ((unsigned char) (packetlen >> 16) & 0xff));
5155
5156 curproxy->check_req[3] = 1;
5157 curproxy->check_req[5] = 128;
5158 curproxy->check_req[8] = 1;
5159 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5160 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5161 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5162 cur_arg += 2;
5163 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005164 } else {
5165 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005166 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5167 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005168 err_code |= ERR_ALERT | ERR_FATAL;
5169 goto out;
5170 }
5171 } /* end while loop */
5172 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005173 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005174 else if (!strcmp(args[1], "ldap-check")) {
5175 /* use LDAP request to check servers' health */
5176 free(curproxy->check_req);
5177 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005178 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005179 curproxy->options2 |= PR_O2_LDAP_CHK;
5180
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005181 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005182 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5183 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005184 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5185 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005186 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005187 else if (!strcmp(args[1], "spop-check")) {
5188 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005189 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5190 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005191 err_code |= ERR_ALERT | ERR_FATAL;
5192 goto out;
5193 }
5194 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005195 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5196 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005197 err_code |= ERR_ALERT | ERR_FATAL;
5198 goto out;
5199 }
5200
5201 /* use SPOE request to check servers' health */
5202 free(curproxy->check_req);
5203 curproxy->check_req = NULL;
5204 curproxy->options2 &= ~PR_O2_CHK_ANY;
5205 curproxy->options2 |= PR_O2_SPOP_CHK;
5206
Christopher Faulet8ef75252017-02-20 22:56:03 +01005207 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005208 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005209 err_code |= ERR_ALERT | ERR_FATAL;
5210 goto out;
5211 }
5212 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5213 goto out;
5214 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005215 else if (!strcmp(args[1], "tcp-check")) {
5216 /* use raw TCPCHK send/expect to check servers' health */
5217 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5218 err_code |= ERR_WARN;
5219
5220 free(curproxy->check_req);
5221 curproxy->check_req = NULL;
5222 curproxy->options2 &= ~PR_O2_CHK_ANY;
5223 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005224 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5225 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005226 }
Simon Horman98637e52014-06-20 12:30:16 +09005227 else if (!strcmp(args[1], "external-check")) {
5228 /* excute an external command to check servers' health */
5229 free(curproxy->check_req);
5230 curproxy->check_req = NULL;
5231 curproxy->options2 &= ~PR_O2_CHK_ANY;
5232 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005233 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5234 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005235 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005236 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005237 int cur_arg;
5238
5239 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5240 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005241 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005242
Willy Tarreau87cf5142011-08-19 22:57:24 +02005243 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005244
5245 free(curproxy->fwdfor_hdr_name);
5246 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5247 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5248
5249 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5250 cur_arg = 2;
5251 while (*(args[cur_arg])) {
5252 if (!strcmp(args[cur_arg], "except")) {
5253 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005254 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005255 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5256 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005257 err_code |= ERR_ALERT | ERR_FATAL;
5258 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005259 }
5260 /* flush useless bits */
5261 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005262 cur_arg += 2;
5263 } else if (!strcmp(args[cur_arg], "header")) {
5264 /* suboption header - needs additional argument for it */
5265 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005266 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5267 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005268 err_code |= ERR_ALERT | ERR_FATAL;
5269 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005270 }
5271 free(curproxy->fwdfor_hdr_name);
5272 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5273 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5274 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005275 } else if (!strcmp(args[cur_arg], "if-none")) {
5276 curproxy->options &= ~PR_O_FF_ALWAYS;
5277 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005278 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005279 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005280 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5281 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005282 err_code |= ERR_ALERT | ERR_FATAL;
5283 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005284 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005285 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005286 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005287 else if (!strcmp(args[1], "originalto")) {
5288 int cur_arg;
5289
5290 /* insert x-original-to field, but not for the IP address listed as an except.
5291 * set default options (ie: bitfield, header name, etc)
5292 */
5293
5294 curproxy->options |= PR_O_ORGTO;
5295
5296 free(curproxy->orgto_hdr_name);
5297 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5298 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5299
Willy Tarreau87cf5142011-08-19 22:57:24 +02005300 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005301 cur_arg = 2;
5302 while (*(args[cur_arg])) {
5303 if (!strcmp(args[cur_arg], "except")) {
5304 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005305 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 +01005306 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5307 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005308 err_code |= ERR_ALERT | ERR_FATAL;
5309 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005310 }
5311 /* flush useless bits */
5312 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5313 cur_arg += 2;
5314 } else if (!strcmp(args[cur_arg], "header")) {
5315 /* suboption header - needs additional argument for it */
5316 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005317 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5318 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005319 err_code |= ERR_ALERT | ERR_FATAL;
5320 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005321 }
5322 free(curproxy->orgto_hdr_name);
5323 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5324 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5325 cur_arg += 2;
5326 } else {
5327 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005328 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5329 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005330 err_code |= ERR_ALERT | ERR_FATAL;
5331 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005332 }
5333 } /* end while loop */
5334 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005335 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005336 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005337 err_code |= ERR_ALERT | ERR_FATAL;
5338 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005339 }
Willy Tarreau93893792009-07-23 13:19:11 +02005340 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005341 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005342 else if (!strcmp(args[0], "default_backend")) {
5343 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005344 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005345
5346 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005347 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005348 err_code |= ERR_ALERT | ERR_FATAL;
5349 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005350 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005351 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005352 curproxy->defbe.name = strdup(args[1]);
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 Tarreau5fdfb912007-01-01 23:11:07 +01005356 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005357 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005358 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005359 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005360
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005361 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005362 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5363 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005364 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005365 /* enable reconnections to dispatch */
5366 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005367
5368 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5369 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005370 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005371 else if (!strcmp(args[0], "http-reuse")) {
5372 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5373 err_code |= ERR_WARN;
5374
5375 if (strcmp(args[1], "never") == 0) {
5376 /* enable a graceful server shutdown on an HTTP 404 response */
5377 curproxy->options &= ~PR_O_REUSE_MASK;
5378 curproxy->options |= PR_O_REUSE_NEVR;
5379 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5380 goto out;
5381 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005382 else if (strcmp(args[1], "safe") == 0) {
5383 /* enable a graceful server shutdown on an HTTP 404 response */
5384 curproxy->options &= ~PR_O_REUSE_MASK;
5385 curproxy->options |= PR_O_REUSE_SAFE;
5386 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5387 goto out;
5388 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005389 else if (strcmp(args[1], "aggressive") == 0) {
5390 curproxy->options &= ~PR_O_REUSE_MASK;
5391 curproxy->options |= PR_O_REUSE_AGGR;
5392 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5393 goto out;
5394 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005395 else if (strcmp(args[1], "always") == 0) {
5396 /* enable a graceful server shutdown on an HTTP 404 response */
5397 curproxy->options &= ~PR_O_REUSE_MASK;
5398 curproxy->options |= PR_O_REUSE_ALWS;
5399 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5400 goto out;
5401 }
5402 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005403 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005404 err_code |= ERR_ALERT | ERR_FATAL;
5405 goto out;
5406 }
5407 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005408 else if (!strcmp(args[0], "http-check")) {
5409 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005410 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005411
5412 if (strcmp(args[1], "disable-on-404") == 0) {
5413 /* enable a graceful server shutdown on an HTTP 404 response */
5414 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005415 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5416 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005417 }
Willy Tarreauef781042010-01-27 11:53:01 +01005418 else if (strcmp(args[1], "send-state") == 0) {
5419 /* enable emission of the apparent state of a server in HTTP checks */
5420 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005421 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5422 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005423 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005424 else if (strcmp(args[1], "expect") == 0) {
5425 const char *ptr_arg;
5426 int cur_arg;
5427
5428 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005429 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005430 err_code |= ERR_ALERT | ERR_FATAL;
5431 goto out;
5432 }
5433
5434 cur_arg = 2;
5435 /* consider exclamation marks, sole or at the beginning of a word */
5436 while (*(ptr_arg = args[cur_arg])) {
5437 while (*ptr_arg == '!') {
5438 curproxy->options2 ^= PR_O2_EXP_INV;
5439 ptr_arg++;
5440 }
5441 if (*ptr_arg)
5442 break;
5443 cur_arg++;
5444 }
5445 /* now ptr_arg points to the beginning of a word past any possible
5446 * exclamation mark, and cur_arg is the argument which holds this word.
5447 */
5448 if (strcmp(ptr_arg, "status") == 0) {
5449 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005450 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5451 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005452 err_code |= ERR_ALERT | ERR_FATAL;
5453 goto out;
5454 }
5455 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005456 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005457 curproxy->expect_str = strdup(args[cur_arg + 1]);
5458 }
5459 else if (strcmp(ptr_arg, "string") == 0) {
5460 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005461 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5462 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005463 err_code |= ERR_ALERT | ERR_FATAL;
5464 goto out;
5465 }
5466 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005467 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005468 curproxy->expect_str = strdup(args[cur_arg + 1]);
5469 }
5470 else if (strcmp(ptr_arg, "rstatus") == 0) {
5471 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005472 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5473 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005474 err_code |= ERR_ALERT | ERR_FATAL;
5475 goto out;
5476 }
5477 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005478 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005479 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005480 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005481 free(curproxy->expect_regex);
5482 curproxy->expect_regex = NULL;
5483 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005484 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005485 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5486 error = NULL;
5487 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005488 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5489 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005490 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005491 err_code |= ERR_ALERT | ERR_FATAL;
5492 goto out;
5493 }
5494 }
5495 else if (strcmp(ptr_arg, "rstring") == 0) {
5496 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005497 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5498 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005499 err_code |= ERR_ALERT | ERR_FATAL;
5500 goto out;
5501 }
5502 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005503 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005504 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005505 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005506 free(curproxy->expect_regex);
5507 curproxy->expect_regex = NULL;
5508 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005509 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005510 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5511 error = NULL;
5512 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005513 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5514 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005515 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005516 err_code |= ERR_ALERT | ERR_FATAL;
5517 goto out;
5518 }
5519 }
5520 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005521 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5522 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005523 err_code |= ERR_ALERT | ERR_FATAL;
5524 goto out;
5525 }
5526 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005527 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005528 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 +02005529 err_code |= ERR_ALERT | ERR_FATAL;
5530 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005531 }
5532 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005533 else if (!strcmp(args[0], "tcp-check")) {
5534 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5535 err_code |= ERR_WARN;
5536
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005537 if (strcmp(args[1], "comment") == 0) {
5538 int cur_arg;
5539 struct tcpcheck_rule *tcpcheck;
5540
5541 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005542 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005543 tcpcheck->action = TCPCHK_ACT_COMMENT;
5544
5545 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005546 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5547 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005548 err_code |= ERR_ALERT | ERR_FATAL;
5549 goto out;
5550 }
5551
5552 tcpcheck->comment = strdup(args[cur_arg + 1]);
5553
5554 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005555 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5556 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005557 }
5558 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005559 const char *ptr_arg;
5560 int cur_arg;
5561 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005562
5563 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005564 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5565 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5566 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5567 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5568 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005569
Willy Tarreau5581c272015-05-13 12:24:53 +02005570 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5571 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005572 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5573 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005574 err_code |= ERR_ALERT | ERR_FATAL;
5575 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005576 }
5577
5578 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005579 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005580 tcpcheck->action = TCPCHK_ACT_CONNECT;
5581
5582 /* parsing each parameters to fill up the rule */
5583 while (*(ptr_arg = args[cur_arg])) {
5584 /* tcp port */
5585 if (strcmp(args[cur_arg], "port") == 0) {
5586 if ( (atol(args[cur_arg + 1]) > 65535) ||
5587 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005588 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5589 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005590 err_code |= ERR_ALERT | ERR_FATAL;
5591 goto out;
5592 }
5593 tcpcheck->port = atol(args[cur_arg + 1]);
5594 cur_arg += 2;
5595 }
5596 /* send proxy protocol */
5597 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5598 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5599 cur_arg++;
5600 }
5601#ifdef USE_OPENSSL
5602 else if (strcmp(args[cur_arg], "ssl") == 0) {
5603 curproxy->options |= PR_O_TCPCHK_SSL;
5604 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5605 cur_arg++;
5606 }
5607#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005608 /* comment for this tcpcheck line */
5609 else if (strcmp(args[cur_arg], "comment") == 0) {
5610 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005611 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5612 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005613 err_code |= ERR_ALERT | ERR_FATAL;
5614 goto out;
5615 }
5616 tcpcheck->comment = strdup(args[cur_arg + 1]);
5617 cur_arg += 2;
5618 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005619 else {
5620#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005621 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 +01005622#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005623 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 +01005624#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005625 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005626 err_code |= ERR_ALERT | ERR_FATAL;
5627 goto out;
5628 }
5629
5630 }
5631
5632 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5633 }
5634 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005635 if (! *(args[2]) ) {
5636 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005637 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5638 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005639 err_code |= ERR_ALERT | ERR_FATAL;
5640 goto out;
5641 } else {
5642 struct tcpcheck_rule *tcpcheck;
5643
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005644 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005645
5646 tcpcheck->action = TCPCHK_ACT_SEND;
5647 tcpcheck->string_len = strlen(args[2]);
5648 tcpcheck->string = strdup(args[2]);
5649 tcpcheck->expect_regex = NULL;
5650
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005651 /* comment for this tcpcheck line */
5652 if (strcmp(args[3], "comment") == 0) {
5653 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005654 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5655 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005656 err_code |= ERR_ALERT | ERR_FATAL;
5657 goto out;
5658 }
5659 tcpcheck->comment = strdup(args[4]);
5660 }
5661
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005662 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5663 }
5664 }
5665 else if (strcmp(args[1], "send-binary") == 0) {
5666 if (! *(args[2]) ) {
5667 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005668 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5669 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005670 err_code |= ERR_ALERT | ERR_FATAL;
5671 goto out;
5672 } else {
5673 struct tcpcheck_rule *tcpcheck;
5674 char *err = NULL;
5675
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005676 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005677
5678 tcpcheck->action = TCPCHK_ACT_SEND;
5679 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005680 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5681 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005682 err_code |= ERR_ALERT | ERR_FATAL;
5683 goto out;
5684 }
5685 tcpcheck->expect_regex = NULL;
5686
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005687 /* comment for this tcpcheck line */
5688 if (strcmp(args[3], "comment") == 0) {
5689 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005690 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5691 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005692 err_code |= ERR_ALERT | ERR_FATAL;
5693 goto out;
5694 }
5695 tcpcheck->comment = strdup(args[4]);
5696 }
5697
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005698 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5699 }
5700 }
5701 else if (strcmp(args[1], "expect") == 0) {
5702 const char *ptr_arg;
5703 int cur_arg;
5704 int inverse = 0;
5705
5706 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005707 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005708 err_code |= ERR_ALERT | ERR_FATAL;
5709 goto out;
5710 }
5711
5712 cur_arg = 2;
5713 /* consider exclamation marks, sole or at the beginning of a word */
5714 while (*(ptr_arg = args[cur_arg])) {
5715 while (*ptr_arg == '!') {
5716 inverse = !inverse;
5717 ptr_arg++;
5718 }
5719 if (*ptr_arg)
5720 break;
5721 cur_arg++;
5722 }
5723 /* now ptr_arg points to the beginning of a word past any possible
5724 * exclamation mark, and cur_arg is the argument which holds this word.
5725 */
5726 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005727 struct tcpcheck_rule *tcpcheck;
5728 char *err = NULL;
5729
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005730 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005731 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5732 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005733 err_code |= ERR_ALERT | ERR_FATAL;
5734 goto out;
5735 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005736
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005737 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005738
5739 tcpcheck->action = TCPCHK_ACT_EXPECT;
5740 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005741 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5742 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005743 err_code |= ERR_ALERT | ERR_FATAL;
5744 goto out;
5745 }
5746 tcpcheck->expect_regex = NULL;
5747 tcpcheck->inverse = inverse;
5748
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005749 /* tcpcheck comment */
5750 cur_arg += 2;
5751 if (strcmp(args[cur_arg], "comment") == 0) {
5752 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005753 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5754 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005755 err_code |= ERR_ALERT | ERR_FATAL;
5756 goto out;
5757 }
5758 tcpcheck->comment = strdup(args[cur_arg + 1]);
5759 }
5760
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005761 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5762 }
5763 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005764 struct tcpcheck_rule *tcpcheck;
5765
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005766 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005767 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5768 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005769 err_code |= ERR_ALERT | ERR_FATAL;
5770 goto out;
5771 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005772
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005773 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005774
5775 tcpcheck->action = TCPCHK_ACT_EXPECT;
5776 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5777 tcpcheck->string = strdup(args[cur_arg + 1]);
5778 tcpcheck->expect_regex = NULL;
5779 tcpcheck->inverse = inverse;
5780
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005781 /* tcpcheck comment */
5782 cur_arg += 2;
5783 if (strcmp(args[cur_arg], "comment") == 0) {
5784 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005785 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5786 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005787 err_code |= ERR_ALERT | ERR_FATAL;
5788 goto out;
5789 }
5790 tcpcheck->comment = strdup(args[cur_arg + 1]);
5791 }
5792
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005793 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5794 }
5795 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005796 struct tcpcheck_rule *tcpcheck;
5797
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005798 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005799 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5800 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005801 err_code |= ERR_ALERT | ERR_FATAL;
5802 goto out;
5803 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005804
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005805 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005806
5807 tcpcheck->action = TCPCHK_ACT_EXPECT;
5808 tcpcheck->string_len = 0;
5809 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005810 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5811 error = NULL;
5812 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005813 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5814 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005815 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005816 err_code |= ERR_ALERT | ERR_FATAL;
5817 goto out;
5818 }
5819 tcpcheck->inverse = inverse;
5820
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005821 /* tcpcheck comment */
5822 cur_arg += 2;
5823 if (strcmp(args[cur_arg], "comment") == 0) {
5824 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005825 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5826 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005827 err_code |= ERR_ALERT | ERR_FATAL;
5828 goto out;
5829 }
5830 tcpcheck->comment = strdup(args[cur_arg + 1]);
5831 }
5832
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005833 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5834 }
5835 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005836 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5837 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005838 err_code |= ERR_ALERT | ERR_FATAL;
5839 goto out;
5840 }
5841 }
5842 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005843 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 +02005844 err_code |= ERR_ALERT | ERR_FATAL;
5845 goto out;
5846 }
5847 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005848 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005849 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005850 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005851 err_code |= ERR_ALERT | ERR_FATAL;
5852 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005853 }
5854
Willy Tarreaub80c2302007-11-30 20:51:32 +01005855 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005856 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005857
5858 if (strcmp(args[1], "fail") == 0) {
5859 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005860 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005861 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5862 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005863 err_code |= ERR_ALERT | ERR_FATAL;
5864 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005865 }
5866
Willy Tarreau721d8e02017-12-01 18:25:08 +01005867 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005868 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005869 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5870 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005871 err_code |= ERR_ALERT | ERR_FATAL;
5872 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005873 }
5874 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5875 }
5876 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005877 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005878 err_code |= ERR_ALERT | ERR_FATAL;
5879 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005880 }
5881 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005882#ifdef TPROXY
5883 else if (!strcmp(args[0], "transparent")) {
5884 /* enable transparent proxy connections */
5885 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005886 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5887 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005888 }
5889#endif
5890 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005891 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005892 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005893
Willy Tarreaubaaee002006-06-26 02:48:02 +02005894 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005895 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005896 err_code |= ERR_ALERT | ERR_FATAL;
5897 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005898 }
5899 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005900 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5901 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005902 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005903 else if (!strcmp(args[0], "backlog")) { /* backlog */
5904 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005905 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005906
5907 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005908 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005909 err_code |= ERR_ALERT | ERR_FATAL;
5910 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005911 }
5912 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005913 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5914 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005915 }
Willy Tarreau86034312006-12-29 00:10:33 +01005916 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005917 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005918 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005919
Willy Tarreau86034312006-12-29 00:10:33 +01005920 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005921 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005922 err_code |= ERR_ALERT | ERR_FATAL;
5923 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005924 }
5925 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005926 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5927 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005928 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005929 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5930 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005931 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005932 err_code |= ERR_ALERT | ERR_FATAL;
5933 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005934 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005935 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5936 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005937 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5938 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005939 err_code |= ERR_ALERT | ERR_FATAL;
5940 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005941 }
5942 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005943 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5944 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005945 }
5946 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005947 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005948 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005949 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005950
Willy Tarreaubaaee002006-06-26 02:48:02 +02005951 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005952 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005953 err_code |= ERR_ALERT | ERR_FATAL;
5954 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005955 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005956 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005957 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005958
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005959 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005960 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005961 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005962 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005963 goto out;
5964 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005965
5966 proto = protocol_by_family(sk->ss_family);
5967 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005968 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5969 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005970 err_code |= ERR_ALERT | ERR_FATAL;
5971 goto out;
5972 }
5973
5974 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005975 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5976 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005977 err_code |= ERR_ALERT | ERR_FATAL;
5978 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005979 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005980
5981 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005982 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5983 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005984 err_code |= ERR_ALERT | ERR_FATAL;
5985 goto out;
5986 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005987
William Lallemanddf1425a2015-04-28 20:17:49 +02005988 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5989 goto out;
5990
Willy Tarreaud5191e72010-02-09 20:50:45 +01005991 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005992 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005993 }
5994 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005995 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005996 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005997
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005998 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005999 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006000 err_code |= ERR_ALERT | ERR_FATAL;
6001 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02006002 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006003 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006004 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006005 /**
6006 * The syntax for hash-type config element is
6007 * hash-type {map-based|consistent} [[<algo>] avalanche]
6008 *
6009 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
6010 */
6011 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04006012
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006013 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
6014 err_code |= ERR_WARN;
6015
6016 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006017 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
6018 }
6019 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006020 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
6021 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006022 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006023 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 -05006024 err_code |= ERR_ALERT | ERR_FATAL;
6025 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01006026 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006027 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006028 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006029 err_code |= ERR_ALERT | ERR_FATAL;
6030 goto out;
6031 }
Bhaskar98634f02013-10-29 23:30:51 -04006032
6033 /* set the hash function to use */
6034 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006035 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04006036 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006037
6038 /* if consistent with no argument, then avalanche modifier is also applied */
6039 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6040 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006041 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006042 /* set the hash function */
6043 if (!strcmp(args[2], "sdbm")) {
6044 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6045 }
6046 else if (!strcmp(args[2], "djb2")) {
6047 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006048 }
6049 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006050 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006051 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006052 else if (!strcmp(args[2], "crc32")) {
6053 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6054 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006055 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006056 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 -05006057 err_code |= ERR_ALERT | ERR_FATAL;
6058 goto out;
6059 }
6060
6061 /* set the hash modifier */
6062 if (!strcmp(args[3], "avalanche")) {
6063 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6064 }
6065 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006066 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 -05006067 err_code |= ERR_ALERT | ERR_FATAL;
6068 goto out;
6069 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006070 }
William Lallemanda73203e2012-03-12 12:48:57 +01006071 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006072 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6073 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006074 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006075 err_code |= ERR_ALERT | ERR_FATAL;
6076 goto out;
6077 }
6078 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6079 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006080 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 -04006081 err_code |= ERR_ALERT | ERR_FATAL;
6082 goto out;
6083 }
6084 }
William Lallemanda73203e2012-03-12 12:48:57 +01006085 else if (strcmp(args[0], "unique-id-format") == 0) {
6086 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006087 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006088 err_code |= ERR_ALERT | ERR_FATAL;
6089 goto out;
6090 }
William Lallemand3203ff42012-11-11 17:30:56 +01006091 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006092 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 +01006093 err_code |= ERR_ALERT | ERR_FATAL;
6094 goto out;
6095 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006096 free(curproxy->conf.uniqueid_format_string);
6097 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006098
Willy Tarreau62a61232013-04-12 18:13:46 +02006099 free(curproxy->conf.uif_file);
6100 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6101 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006102 }
William Lallemanda73203e2012-03-12 12:48:57 +01006103
6104 else if (strcmp(args[0], "unique-id-header") == 0) {
6105 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006106 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006107 err_code |= ERR_ALERT | ERR_FATAL;
6108 goto out;
6109 }
6110 free(curproxy->header_unique_id);
6111 curproxy->header_unique_id = strdup(args[1]);
6112 }
6113
William Lallemand723b73a2012-02-08 16:37:49 +01006114 else if (strcmp(args[0], "log-format") == 0) {
6115 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006116 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006117 err_code |= ERR_ALERT | ERR_FATAL;
6118 goto out;
6119 }
William Lallemand3203ff42012-11-11 17:30:56 +01006120 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006121 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 +01006122 err_code |= ERR_ALERT | ERR_FATAL;
6123 goto out;
6124 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006125 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6126 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006127
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006128 if (curproxy->conf.logformat_string == default_http_log_format)
6129 oldlogformat = "option httplog";
6130 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6131 oldlogformat = "option tcplog";
6132 else if (curproxy->conf.logformat_string == clf_http_log_format)
6133 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006134 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6135 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006136 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006137 if (curproxy->conf.logformat_string != default_http_log_format &&
6138 curproxy->conf.logformat_string != default_tcp_log_format &&
6139 curproxy->conf.logformat_string != clf_http_log_format)
6140 free(curproxy->conf.logformat_string);
6141 curproxy->conf.logformat_string = strdup(args[1]);
6142
6143 free(curproxy->conf.lfs_file);
6144 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6145 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006146
6147 /* get a chance to improve log-format error reporting by
6148 * reporting the correct line-number when possible.
6149 */
6150 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006151 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6152 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006153 err_code |= ERR_WARN;
6154 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006155 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006156 else if (!strcmp(args[0], "log-format-sd")) {
6157 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006158 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006159 err_code |= ERR_ALERT | ERR_FATAL;
6160 goto out;
6161 }
6162 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006163 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 +02006164 err_code |= ERR_ALERT | ERR_FATAL;
6165 goto out;
6166 }
6167
6168 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6169 free(curproxy->conf.logformat_sd_string);
6170 curproxy->conf.logformat_sd_string = strdup(args[1]);
6171
6172 free(curproxy->conf.lfsd_file);
6173 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6174 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6175
6176 /* get a chance to improve log-format-sd error reporting by
6177 * reporting the correct line-number when possible.
6178 */
6179 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006180 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6181 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006182 err_code |= ERR_WARN;
6183 }
6184 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006185 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6186 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006187 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 +01006188 err_code |= ERR_ALERT | ERR_FATAL;
6189 goto out;
6190 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006191 chunk_destroy(&curproxy->log_tag);
6192 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006193 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006194 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6195 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6196 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006197 err_code |= ERR_ALERT | ERR_FATAL;
6198 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006199 }
6200 }
6201 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006202 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006203 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006204 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006205 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006206
Willy Tarreau977b8e42006-12-29 14:19:17 +01006207 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006208 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006209
Willy Tarreaubaaee002006-06-26 02:48:02 +02006210 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006211 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6212 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006213 err_code |= ERR_ALERT | ERR_FATAL;
6214 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006215 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006216
6217 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006218 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6219 free(curproxy->conn_src.iface_name);
6220 curproxy->conn_src.iface_name = NULL;
6221 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006222
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006223 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006224 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006225 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6226 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006227 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006228 goto out;
6229 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006230
6231 proto = protocol_by_family(sk->ss_family);
6232 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006233 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6234 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006235 err_code |= ERR_ALERT | ERR_FATAL;
6236 goto out;
6237 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006238
6239 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006240 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6241 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006242 err_code |= ERR_ALERT | ERR_FATAL;
6243 goto out;
6244 }
6245
Willy Tarreauef9a3602012-12-08 22:29:20 +01006246 curproxy->conn_src.source_addr = *sk;
6247 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006248
6249 cur_arg = 2;
6250 while (*(args[cur_arg])) {
6251 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006252#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006253 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006254 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6255 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006256 err_code |= ERR_ALERT | ERR_FATAL;
6257 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006258 }
6259
6260 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006261 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6262 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006263 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006264 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6265 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006266 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6267 char *name, *end;
6268
6269 name = args[cur_arg+1] + 7;
6270 while (isspace(*name))
6271 name++;
6272
6273 end = name;
6274 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6275 end++;
6276
Willy Tarreauef9a3602012-12-08 22:29:20 +01006277 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6278 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6279 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6280 curproxy->conn_src.bind_hdr_len = end - name;
6281 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6282 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6283 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006284
6285 /* now look for an occurrence number */
6286 while (isspace(*end))
6287 end++;
6288 if (*end == ',') {
6289 end++;
6290 name = end;
6291 if (*end == '-')
6292 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006293 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006294 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006295 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006296 }
6297
Willy Tarreauef9a3602012-12-08 22:29:20 +01006298 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006299 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6300 " occurrences values smaller than %d.\n",
6301 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006302 err_code |= ERR_ALERT | ERR_FATAL;
6303 goto out;
6304 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006305 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006306 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006307
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006308 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006309 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006310 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6311 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006312 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006313 goto out;
6314 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006315
6316 proto = protocol_by_family(sk->ss_family);
6317 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006318 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6319 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006320 err_code |= ERR_ALERT | ERR_FATAL;
6321 goto out;
6322 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006323
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006324 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006325 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6326 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006327 err_code |= ERR_ALERT | ERR_FATAL;
6328 goto out;
6329 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006330 curproxy->conn_src.tproxy_addr = *sk;
6331 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006332 }
6333 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006334#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006335 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6336 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006337 err_code |= ERR_ALERT | ERR_FATAL;
6338 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006339#endif
6340 cur_arg += 2;
6341 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006342 }
6343
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006344 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6345#ifdef SO_BINDTODEVICE
6346 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006347 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6348 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006349 err_code |= ERR_ALERT | ERR_FATAL;
6350 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006351 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006352 free(curproxy->conn_src.iface_name);
6353 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6354 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006355 global.last_checks |= LSTCHK_NETADM;
6356#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006357 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6358 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006359 err_code |= ERR_ALERT | ERR_FATAL;
6360 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006361#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006362 cur_arg += 2;
6363 continue;
6364 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006365 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6366 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006367 err_code |= ERR_ALERT | ERR_FATAL;
6368 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006369 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006370 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006371 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006372 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6373 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006374 err_code |= ERR_ALERT | ERR_FATAL;
6375 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006376 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006377 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006378 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006379 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6380 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006381 err_code |= ERR_ALERT | ERR_FATAL;
6382 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006383 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006384
6385 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006386 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006387 args[0], args[1], args[2], (const char **)args+3);
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], "reqdel")) { /* delete request header from a regex */
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_REMOVE, 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], "reqdeny")) { /* deny 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_DENY, 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 }
6405 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
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_PASS, 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 Tarreaubaaee002006-06-26 02:48:02 +02006411 }
6412 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006413 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006414 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006415 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006416 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006417 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006418 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006419 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006420 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006421 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006422 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006423 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006424 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006425 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006426 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006427 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006428 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6429 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006430 err_code |= ERR_ALERT | ERR_FATAL;
6431 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006432 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006433
6434 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006435 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006436 args[0], args[1], args[2], (const char **)args+3);
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], "reqidel")) { /* delete request header from a regex ignoring case */
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_REMOVE, 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], "reqideny")) { /* deny 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_DENY, 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 }
6454 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
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_PASS, 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 Tarreaubaaee002006-06-26 02:48:02 +02006460 }
6461 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006462 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006463 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006464 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006465 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006466 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006467 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006468 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006469 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006470 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006471 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006472 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006473 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006474 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006475 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006476 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006477
Willy Tarreaubaaee002006-06-26 02:48:02 +02006478 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006479 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006480 err_code |= ERR_ALERT | ERR_FATAL;
6481 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006482 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006483 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006484 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006485
Willy Tarreaubaaee002006-06-26 02:48:02 +02006486 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006487 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006488 err_code |= ERR_ALERT | ERR_FATAL;
6489 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006490 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006491
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006492 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006493 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006494 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6495 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006496 err_code |= ERR_ALERT | ERR_FATAL;
6497 goto out;
6498 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006499 err_code |= warnif_cond_conflicts(cond,
6500 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6501 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006502 }
6503 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006504 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6505 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006506 err_code |= ERR_ALERT | ERR_FATAL;
6507 goto out;
6508 }
6509
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006510 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006511 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006512 wl->s = strdup(args[1]);
6513 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006514 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006515 }
6516 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006517 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006518 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6519 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006520 err_code |= ERR_ALERT | ERR_FATAL;
6521 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006522 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006523
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_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006526 args[0], args[1], args[2], (const char **)args+3);
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], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006531 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006532 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006533 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006534 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006535 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006536 }
6537 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
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_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006540 args[0], args[1], NULL, (const char **)args+2);
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], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006545 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006546 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6547 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006548 err_code |= ERR_ALERT | ERR_FATAL;
6549 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006550 }
6551
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_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006554 args[0], args[1], args[2], (const char **)args+3);
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], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006559 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006560 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006561 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006562 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006563 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006564 }
6565 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006566 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006567 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006568 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006569 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006570 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006571 }
6572 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006573 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006574
Willy Tarreaubaaee002006-06-26 02:48:02 +02006575 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006576 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006577 err_code |= ERR_ALERT | ERR_FATAL;
6578 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006579 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006580 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006581 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006582
Willy Tarreaubaaee002006-06-26 02:48:02 +02006583 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006584 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006585 err_code |= ERR_ALERT | ERR_FATAL;
6586 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006587 }
6588
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006589 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006590 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006591 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6592 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006593 err_code |= ERR_ALERT | ERR_FATAL;
6594 goto out;
6595 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006596 err_code |= warnif_cond_conflicts(cond,
6597 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6598 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006599 }
6600 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006601 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6602 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006603 err_code |= ERR_ALERT | ERR_FATAL;
6604 goto out;
6605 }
6606
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006607 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006608 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006609 wl->s = strdup(args[1]);
6610 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006611 }
6612 else if (!strcmp(args[0], "errorloc") ||
6613 !strcmp(args[0], "errorloc302") ||
6614 !strcmp(args[0], "errorloc303")) { /* error location */
6615 int errnum, errlen;
6616 char *err;
6617
Willy Tarreau977b8e42006-12-29 14:19:17 +01006618 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006619 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006620
Willy Tarreaubaaee002006-06-26 02:48:02 +02006621 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006622 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 +02006623 err_code |= ERR_ALERT | ERR_FATAL;
6624 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006625 }
6626
6627 errnum = atol(args[1]);
6628 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006629 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6630 err = malloc(errlen);
6631 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006632 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006633 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6634 err = malloc(errlen);
6635 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006636 }
6637
Willy Tarreau0f772532006-12-23 20:51:41 +01006638 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6639 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006640 chunk_destroy(&curproxy->errmsg[rc]);
6641 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006642 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006643 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006644 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006645
6646 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006647 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6648 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006649 free(err);
6650 }
6651 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006652 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6653 int errnum, errlen, fd;
6654 char *err;
6655 struct stat stat;
6656
6657 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006658 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006659
6660 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006661 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 +02006662 err_code |= ERR_ALERT | ERR_FATAL;
6663 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006664 }
6665
6666 fd = open(args[2], O_RDONLY);
6667 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006668 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6669 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006670 if (fd >= 0)
6671 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006672 err_code |= ERR_ALERT | ERR_FATAL;
6673 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006674 }
6675
Willy Tarreau27a674e2009-08-17 07:23:33 +02006676 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006677 errlen = stat.st_size;
6678 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006679 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6680 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006681 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006682 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006683 }
6684
6685 err = malloc(errlen); /* malloc() must succeed during parsing */
6686 errnum = read(fd, err, errlen);
6687 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006688 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6689 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006690 close(fd);
6691 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006692 err_code |= ERR_ALERT | ERR_FATAL;
6693 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006694 }
6695 close(fd);
6696
6697 errnum = atol(args[1]);
6698 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6699 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006700 chunk_destroy(&curproxy->errmsg[rc]);
6701 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006702 break;
6703 }
6704 }
6705
6706 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006707 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6708 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006709 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006710 free(err);
6711 }
6712 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006713 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006714 struct cfg_kw_list *kwl;
6715 int index;
6716
6717 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6718 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6719 if (kwl->kw[index].section != CFG_LISTEN)
6720 continue;
6721 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6722 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006723 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006724 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006725 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006726 err_code |= ERR_ALERT | ERR_FATAL;
6727 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006728 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006729 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006730 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006731 err_code |= ERR_WARN;
6732 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006733 }
Willy Tarreau93893792009-07-23 13:19:11 +02006734 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006735 }
6736 }
6737 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006738
Christopher Faulet767a84b2017-11-24 16:50:31 +01006739 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006740 err_code |= ERR_ALERT | ERR_FATAL;
6741 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006742 }
Willy Tarreau93893792009-07-23 13:19:11 +02006743 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006744 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006745 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006746}
6747
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006748int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006749cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6750{
6751#ifdef CONFIG_HAP_NS
6752 const char *err;
6753 const char *item = args[0];
6754
6755 if (!strcmp(item, "namespace_list")) {
6756 return 0;
6757 }
6758 else if (!strcmp(item, "namespace")) {
6759 size_t idx = 1;
6760 const char *current;
6761 while (*(current = args[idx++])) {
6762 err = invalid_char(current);
6763 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006764 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6765 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006766 return ERR_ALERT | ERR_FATAL;
6767 }
6768
6769 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006770 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6771 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006772 return ERR_ALERT | ERR_FATAL;
6773 }
6774 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006775 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6776 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006777 return ERR_ALERT | ERR_FATAL;
6778 }
6779 }
6780 }
6781
6782 return 0;
6783#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006784 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6785 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006786 return ERR_ALERT | ERR_FATAL;
6787#endif
6788}
6789
6790int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006791cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6792{
6793
6794 int err_code = 0;
6795 const char *err;
6796
6797 if (!strcmp(args[0], "userlist")) { /* new userlist */
6798 struct userlist *newul;
6799
6800 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006801 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6802 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006803 err_code |= ERR_ALERT | ERR_FATAL;
6804 goto out;
6805 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006806 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6807 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006808
6809 err = invalid_char(args[1]);
6810 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006811 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6812 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006813 err_code |= ERR_ALERT | ERR_FATAL;
6814 goto out;
6815 }
6816
6817 for (newul = userlist; newul; newul = newul->next)
6818 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006819 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6820 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006821 err_code |= ERR_WARN;
6822 goto out;
6823 }
6824
Vincent Bernat02779b62016-04-03 13:48:43 +02006825 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006826 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006827 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006828 err_code |= ERR_ALERT | ERR_ABORT;
6829 goto out;
6830 }
6831
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006832 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006833 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006834 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006835 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006836 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006837 goto out;
6838 }
6839
6840 newul->next = userlist;
6841 userlist = newul;
6842
6843 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006844 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006845 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006846 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006847
6848 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006849 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6850 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006851 err_code |= ERR_ALERT | ERR_FATAL;
6852 goto out;
6853 }
6854
6855 err = invalid_char(args[1]);
6856 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006857 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6858 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006859 err_code |= ERR_ALERT | ERR_FATAL;
6860 goto out;
6861 }
6862
William Lallemand4ac9f542015-05-28 18:03:51 +02006863 if (!userlist)
6864 goto out;
6865
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006866 for (ag = userlist->groups; ag; ag = ag->next)
6867 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006868 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6869 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006870 err_code |= ERR_ALERT;
6871 goto out;
6872 }
6873
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006874 ag = calloc(1, sizeof(*ag));
6875 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006876 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006877 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006878 goto out;
6879 }
6880
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006881 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006882 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006883 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006884 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006885 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006886 goto out;
6887 }
6888
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006889 cur_arg = 2;
6890
6891 while (*args[cur_arg]) {
6892 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006893 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006894 cur_arg += 2;
6895 continue;
6896 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006897 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6898 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006899 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006900 free(ag->groupusers);
6901 free(ag->name);
6902 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006903 goto out;
6904 }
6905 }
6906
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006907 ag->next = userlist->groups;
6908 userlist->groups = ag;
6909
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006910 } else if (!strcmp(args[0], "user")) { /* new user */
6911 struct auth_users *newuser;
6912 int cur_arg;
6913
6914 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006915 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6916 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006917 err_code |= ERR_ALERT | ERR_FATAL;
6918 goto out;
6919 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006920 if (!userlist)
6921 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006922
6923 for (newuser = userlist->users; newuser; newuser = newuser->next)
6924 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006925 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6926 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006927 err_code |= ERR_ALERT;
6928 goto out;
6929 }
6930
Vincent Bernat02779b62016-04-03 13:48:43 +02006931 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006932 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006933 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006934 err_code |= ERR_ALERT | ERR_ABORT;
6935 goto out;
6936 }
6937
6938 newuser->user = strdup(args[1]);
6939
6940 newuser->next = userlist->users;
6941 userlist->users = newuser;
6942
6943 cur_arg = 2;
6944
6945 while (*args[cur_arg]) {
6946 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006947#ifdef CONFIG_HAP_CRYPT
6948 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006949 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6950 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006951 err_code |= ERR_ALERT | ERR_FATAL;
6952 goto out;
6953 }
6954#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006955 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6956 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006957 err_code |= ERR_ALERT;
6958#endif
6959 newuser->pass = strdup(args[cur_arg + 1]);
6960 cur_arg += 2;
6961 continue;
6962 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6963 newuser->pass = strdup(args[cur_arg + 1]);
6964 newuser->flags |= AU_O_INSECURE;
6965 cur_arg += 2;
6966 continue;
6967 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006968 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006969 cur_arg += 2;
6970 continue;
6971 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006972 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6973 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006974 err_code |= ERR_ALERT | ERR_FATAL;
6975 goto out;
6976 }
6977 }
6978 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006979 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 +01006980 err_code |= ERR_ALERT | ERR_FATAL;
6981 }
6982
6983out:
6984 return err_code;
6985}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006986
Christopher Faulet79bdef32016-11-04 22:36:15 +01006987int
6988cfg_parse_scope(const char *file, int linenum, char *line)
6989{
6990 char *beg, *end, *scope = NULL;
6991 int err_code = 0;
6992 const char *err;
6993
6994 beg = line + 1;
6995 end = strchr(beg, ']');
6996
6997 /* Detect end of scope declaration */
6998 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006999 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
7000 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007001 err_code |= ERR_ALERT | ERR_FATAL;
7002 goto out;
7003 }
7004
7005 /* Get scope name and check its validity */
7006 scope = my_strndup(beg, end-beg);
7007 err = invalid_char(scope);
7008 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007009 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
7010 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007011 err_code |= ERR_ALERT | ERR_ABORT;
7012 goto out;
7013 }
7014
7015 /* Be sure to have a scope declaration alone on its line */
7016 line = end+1;
7017 while (isspace((unsigned char)*line))
7018 line++;
7019 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007020 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7021 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007022 err_code |= ERR_ALERT | ERR_ABORT;
7023 goto out;
7024 }
7025
7026 /* We have a valid scope declaration, save it */
7027 free(cfg_scope);
7028 cfg_scope = scope;
7029 scope = NULL;
7030
7031 out:
7032 free(scope);
7033 return err_code;
7034}
7035
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01007036int
7037cfg_parse_track_sc_num(unsigned int *track_sc_num,
7038 const char *arg, const char *end, char **errmsg)
7039{
7040 const char *p;
7041 unsigned int num;
7042
7043 p = arg;
7044 num = read_uint64(&arg, end);
7045
7046 if (arg != end) {
7047 memprintf(errmsg, "Wrong track-sc number '%s'", p);
7048 return -1;
7049 }
7050
7051 if (num >= MAX_SESS_STKCTR) {
7052 memprintf(errmsg, "%u track-sc number exceeding "
7053 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
7054 return -1;
7055 }
7056
7057 *track_sc_num = num;
7058 return 0;
7059}
7060
Willy Tarreaubaaee002006-06-26 02:48:02 +02007061/*
7062 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007063 * Returns the error code, 0 if OK, or any combination of :
7064 * - ERR_ABORT: must abort ASAP
7065 * - ERR_FATAL: we can continue parsing but not start the service
7066 * - ERR_WARN: a warning has been emitted
7067 * - ERR_ALERT: an alert has been emitted
7068 * Only the two first ones can stop processing, the two others are just
7069 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007070 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007071int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007072{
William Lallemand64e84512015-05-12 14:25:37 +02007073 char *thisline;
7074 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007075 FILE *f;
7076 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007077 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007078 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007079 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007080 int readbytes = 0;
7081
7082 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007083 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007084 return -1;
7085 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007086
David Carlier97880bb2016-04-08 10:35:26 +01007087 if ((f=fopen(file,"r")) == NULL) {
7088 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007089 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007090 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007091
William Lallemandb2f07452015-05-12 14:27:13 +02007092next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007093 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007094 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007095 char *end;
7096 char *args[MAX_LINE_ARGS + 1];
7097 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007098 int dquote = 0; /* double quote */
7099 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007100
Willy Tarreaubaaee002006-06-26 02:48:02 +02007101 linenum++;
7102
7103 end = line + strlen(line);
7104
William Lallemand64e84512015-05-12 14:25:37 +02007105 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007106 /* Check if we reached the limit and the last char is not \n.
7107 * Watch out for the last line without the terminating '\n'!
7108 */
William Lallemand64e84512015-05-12 14:25:37 +02007109 char *newline;
7110 int newlinesize = linesize * 2;
7111
7112 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7113 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007114 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7115 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007116 err_code |= ERR_ALERT | ERR_FATAL;
7117 continue;
7118 }
7119
7120 readbytes = linesize - 1;
7121 linesize = newlinesize;
7122 thisline = newline;
7123 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007124 }
7125
William Lallemand64e84512015-05-12 14:25:37 +02007126 readbytes = 0;
7127
Willy Tarreaubaaee002006-06-26 02:48:02 +02007128 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007129 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007130 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007131
Christopher Faulet79bdef32016-11-04 22:36:15 +01007132
7133 if (*line == '[') {/* This is the begining if a scope */
7134 err_code |= cfg_parse_scope(file, linenum, line);
7135 goto next_line;
7136 }
7137
Willy Tarreaubaaee002006-06-26 02:48:02 +02007138 arg = 0;
7139 args[arg] = line;
7140
7141 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007142 if (*line == '"' && !squote) { /* double quote outside single quotes */
7143 if (dquote)
7144 dquote = 0;
7145 else
7146 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007147 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007148 end--;
7149 }
7150 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7151 if (squote)
7152 squote = 0;
7153 else
7154 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007155 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007156 end--;
7157 }
7158 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007159 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7160 * C equivalent value. Other combinations left unchanged (eg: \1).
7161 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007162 int skip = 0;
7163 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7164 *line = line[1];
7165 skip = 1;
7166 }
7167 else if (line[1] == 'r') {
7168 *line = '\r';
7169 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007170 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007171 else if (line[1] == 'n') {
7172 *line = '\n';
7173 skip = 1;
7174 }
7175 else if (line[1] == 't') {
7176 *line = '\t';
7177 skip = 1;
7178 }
7179 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007180 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007181 unsigned char hex1, hex2;
7182 hex1 = toupper(line[2]) - '0';
7183 hex2 = toupper(line[3]) - '0';
7184 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7185 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7186 *line = (hex1<<4) + hex2;
7187 skip = 3;
7188 }
7189 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007190 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007191 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007192 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007193 } else if (line[1] == '"') {
7194 *line = '"';
7195 skip = 1;
7196 } else if (line[1] == '\'') {
7197 *line = '\'';
7198 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007199 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7200 *line = '$';
7201 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007202 }
7203 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007204 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007205 end -= skip;
7206 }
7207 line++;
7208 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007209 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007210 /* end of string, end of loop */
7211 *line = 0;
7212 break;
7213 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007214 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007215 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007216 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007217 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007218 line++;
7219 args[++arg] = line;
7220 }
William Lallemandb2f07452015-05-12 14:27:13 +02007221 else if (dquote && *line == '$') {
7222 /* environment variables are evaluated inside double quotes */
7223 char *var_beg;
7224 char *var_end;
7225 char save_char;
7226 char *value;
7227 int val_len;
7228 int newlinesize;
7229 int braces = 0;
7230
7231 var_beg = line + 1;
7232 var_end = var_beg;
7233
7234 if (*var_beg == '{') {
7235 var_beg++;
7236 var_end++;
7237 braces = 1;
7238 }
7239
7240 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007241 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 +02007242 err_code |= ERR_ALERT | ERR_FATAL;
7243 goto next_line; /* skip current line */
7244 }
7245
7246 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7247 var_end++;
7248
7249 save_char = *var_end;
7250 *var_end = '\0';
7251 value = getenv(var_beg);
7252 *var_end = save_char;
7253 val_len = value ? strlen(value) : 0;
7254
7255 if (braces) {
7256 if (*var_end == '}') {
7257 var_end++;
7258 braces = 0;
7259 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007260 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007261 err_code |= ERR_ALERT | ERR_FATAL;
7262 goto next_line; /* skip current line */
7263 }
7264 }
7265
7266 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7267
7268 /* if not enough space in thisline */
7269 if (newlinesize > linesize) {
7270 char *newline;
7271
7272 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7273 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007274 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007275 err_code |= ERR_ALERT | ERR_FATAL;
7276 goto next_line; /* slip current line */
7277 }
7278 /* recompute pointers if realloc returns a new pointer */
7279 if (newline != thisline) {
7280 int i;
7281 int diff;
7282
7283 for (i = 0; i <= arg; i++) {
7284 diff = args[i] - thisline;
7285 args[i] = newline + diff;
7286 }
7287
7288 diff = var_end - thisline;
7289 var_end = newline + diff;
7290 diff = end - thisline;
7291 end = newline + diff;
7292 diff = line - thisline;
7293 line = newline + diff;
7294 thisline = newline;
7295 }
7296 linesize = newlinesize;
7297 }
7298
7299 /* insert value inside the line */
7300 memmove(line + val_len, var_end, end - var_end + 1);
7301 memcpy(line, value, val_len);
7302 end += val_len - (var_end - line);
7303 line += val_len;
7304 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007305 else {
7306 line++;
7307 }
7308 }
William Lallemandb2f07452015-05-12 14:27:13 +02007309
William Lallemandf9873ba2015-05-05 17:37:14 +02007310 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007311 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007312 err_code |= ERR_ALERT | ERR_FATAL;
7313 }
7314
7315 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007316 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007317 err_code |= ERR_ALERT | ERR_FATAL;
7318 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007319
7320 /* empty line */
7321 if (!**args)
7322 continue;
7323
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007324 if (*line) {
7325 /* we had to stop due to too many args.
7326 * Let's terminate the string, print the offending part then cut the
7327 * last arg.
7328 */
7329 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7330 line++;
7331 *line = '\0';
7332
Christopher Faulet767a84b2017-11-24 16:50:31 +01007333 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7334 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007335 err_code |= ERR_ALERT | ERR_FATAL;
7336 args[arg] = line;
7337 }
7338
Willy Tarreau540abe42007-05-02 20:50:16 +02007339 /* zero out remaining args and ensure that at least one entry
7340 * is zeroed out.
7341 */
7342 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007343 args[arg] = line;
7344 }
7345
Willy Tarreau3842f002009-06-14 11:39:52 +02007346 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007347 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007348 char *tmp;
7349
Willy Tarreau3842f002009-06-14 11:39:52 +02007350 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007351 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007352 for (arg=0; *args[arg+1]; arg++)
7353 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007354 *tmp = '\0'; // fix the next arg to \0
7355 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007356 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007357 else if (!strcmp(args[0], "default")) {
7358 kwm = KWM_DEF;
7359 for (arg=0; *args[arg+1]; arg++)
7360 args[arg] = args[arg+1]; // shift args after inversion
7361 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007362
William Lallemand0f99e342011-10-12 17:50:54 +02007363 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7364 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007365 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007366 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007367 }
7368
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007369 /* detect section start */
7370 list_for_each_entry(ics, &sections, list) {
7371 if (strcmp(args[0], ics->section_name) == 0) {
7372 cursection = ics->section_name;
7373 cs = ics;
7374 break;
7375 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007376 }
7377
William Lallemandd2ff56d2017-10-16 11:06:50 +02007378 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007379 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007380 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007381 } else {
7382 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007383
William Lallemandd2ff56d2017-10-16 11:06:50 +02007384 if (pcs != cs && pcs && pcs->post_section_parser) {
7385 err_code |= pcs->post_section_parser();
7386 if (err_code & ERR_ABORT)
7387 goto err;
7388 }
7389
7390 err_code |= cs->section_parser(file, linenum, args, kwm);
7391 if (err_code & ERR_ABORT)
7392 goto err;
7393 }
7394 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007395 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007396
7397 if (pcs == cs && pcs && pcs->post_section_parser)
7398 err_code |= pcs->post_section_parser();
7399
7400err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007401 free(cfg_scope);
7402 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007403 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007404 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007405 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007406 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007407}
7408
Willy Tarreau64ab6072014-09-16 12:17:36 +02007409/* This function propagates processes from frontend <from> to backend <to> so
7410 * that it is always guaranteed that a backend pointed to by a frontend is
7411 * bound to all of its processes. After that, if the target is a "listen"
7412 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007413 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007414 * checked first to ensure that <to> is already bound to all processes of
7415 * <from>, there is no risk of looping and we ensure to follow the shortest
7416 * path to the destination.
7417 *
7418 * It is possible to set <to> to NULL for the first call so that the function
7419 * takes care of visiting the initial frontend in <from>.
7420 *
7421 * It is important to note that the function relies on the fact that all names
7422 * have already been resolved.
7423 */
7424void propagate_processes(struct proxy *from, struct proxy *to)
7425{
7426 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007427
7428 if (to) {
7429 /* check whether we need to go down */
7430 if (from->bind_proc &&
7431 (from->bind_proc & to->bind_proc) == from->bind_proc)
7432 return;
7433
7434 if (!from->bind_proc && !to->bind_proc)
7435 return;
7436
7437 to->bind_proc = from->bind_proc ?
7438 (to->bind_proc | from->bind_proc) : 0;
7439
7440 /* now propagate down */
7441 from = to;
7442 }
7443
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007444 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007445 return;
7446
Willy Tarreauf6b70012014-12-18 14:00:43 +01007447 if (from->state == PR_STSTOPPED)
7448 return;
7449
Willy Tarreau64ab6072014-09-16 12:17:36 +02007450 /* default_backend */
7451 if (from->defbe.be)
7452 propagate_processes(from, from->defbe.be);
7453
7454 /* use_backend */
7455 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007456 if (rule->dynamic)
7457 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007458 to = rule->be.backend;
7459 propagate_processes(from, to);
7460 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007461}
7462
Willy Tarreaubb925012009-07-23 13:36:36 +02007463/*
7464 * Returns the error code, 0 if OK, or any combination of :
7465 * - ERR_ABORT: must abort ASAP
7466 * - ERR_FATAL: we can continue parsing but not start the service
7467 * - ERR_WARN: a warning has been emitted
7468 * - ERR_ALERT: an alert has been emitted
7469 * Only the two first ones can stop processing, the two others are just
7470 * indicators.
7471 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007472int check_config_validity()
7473{
7474 int cfgerr = 0;
7475 struct proxy *curproxy = NULL;
7476 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007477 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007478 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007479 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007480 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007481 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06007482 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007483
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007484 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007485 /*
7486 * Now, check for the integrity of all that we have collected.
7487 */
7488
7489 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007490 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007491
Willy Tarreau193b8c62012-11-22 00:17:38 +01007492 if (!global.tune.max_http_hdr)
7493 global.tune.max_http_hdr = MAX_HTTP_HDR;
7494
7495 if (!global.tune.cookie_len)
7496 global.tune.cookie_len = CAPTURE_LEN;
7497
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007498 if (!global.tune.requri_len)
7499 global.tune.requri_len = REQURI_LEN;
7500
Willy Tarreaubafbe012017-11-24 17:34:44 +01007501 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007502
Willy Tarreaubafbe012017-11-24 17:34:44 +01007503 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007504
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007505 /* Post initialisation of the users and groups lists. */
7506 err_code = userlist_postinit();
7507 if (err_code != ERR_NONE)
7508 goto out;
7509
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007510 /* first, we will invert the proxy list order */
7511 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007512 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007513 struct proxy *next;
7514
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007515 next = proxies_list->next;
7516 proxies_list->next = curproxy;
7517 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007518 if (!next)
7519 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007520 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007521 }
7522
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007523 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007524 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007525 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007526 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007527 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007528 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007529 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007530 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007531
Willy Tarreau050536d2012-10-04 08:47:34 +02007532 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007533 /* proxy ID not set, use automatic numbering with first
7534 * spare entry starting with next_pxid.
7535 */
7536 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7537 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7538 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007539 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007540 next_pxid++;
7541
Willy Tarreau55ea7572007-06-17 19:56:27 +02007542
Willy Tarreaubaaee002006-06-26 02:48:02 +02007543 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007544 /* ensure we don't keep listeners uselessly bound */
7545 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007546 free((void *)curproxy->table.peers.name);
7547 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007548 continue;
7549 }
7550
Willy Tarreau102df612014-05-07 23:56:38 +02007551 /* Check multi-process mode compatibility for the current proxy */
7552
7553 if (curproxy->bind_proc) {
7554 /* an explicit bind-process was specified, let's check how many
7555 * processes remain.
7556 */
David Carliere6c39412015-07-02 07:00:17 +00007557 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007558
7559 curproxy->bind_proc &= nbits(global.nbproc);
7560 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007561 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 +02007562 curproxy->bind_proc = 1;
7563 }
7564 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007565 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 +02007566 curproxy->bind_proc = 0;
7567 }
7568 }
7569
Willy Tarreau3d209582014-05-09 17:06:11 +02007570 /* check and reduce the bind-proc of each listener */
7571 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7572 unsigned long mask;
7573
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007574 /* HTTP frontends with "h2" as ALPN/NPN will work in
7575 * HTTP/2 and absolutely require buffers 16kB or larger.
7576 */
7577#ifdef USE_OPENSSL
7578 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7579#ifdef OPENSSL_NPN_NEGOTIATED
7580 /* check NPN */
7581 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007582 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",
7583 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007584 cfgerr++;
7585 }
7586#endif
7587#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7588 /* check ALPN */
7589 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007590 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",
7591 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007592 cfgerr++;
7593 }
7594#endif
7595 } /* HTTP && bufsize < 16384 */
7596#endif
7597
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007598 /* detect and address thread affinity inconsistencies */
7599 nbproc = 0;
7600 if (bind_conf->bind_proc)
7601 nbproc = my_ffsl(bind_conf->bind_proc);
7602
7603 mask = bind_conf->bind_thread[nbproc - 1];
Willy Tarreau0c026f42018-08-01 19:12:20 +02007604 if (mask && !(mask & all_threads_mask)) {
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007605 unsigned long new_mask = 0;
7606
7607 while (mask) {
Willy Tarreau0c026f42018-08-01 19:12:20 +02007608 new_mask |= mask & all_threads_mask;
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007609 mask >>= global.nbthread;
7610 }
7611
7612 for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
7613 if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
7614 bind_conf->bind_thread[nbproc] = new_mask;
7615 }
7616 ha_warning("Proxy '%s': the thread range specified on the 'process' directive of 'bind %s' at [%s:%d] only refers to thread numbers out of the range defined by the global 'nbthread' directive. The thread numbers were remapped to existing threads instead (mask 0x%lx).\n",
7617 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
7618 }
7619
7620 /* detect process and nbproc affinity inconsistencies */
Willy Tarreau3d209582014-05-09 17:06:11 +02007621 if (!bind_conf->bind_proc)
7622 continue;
7623
7624 mask = nbits(global.nbproc);
7625 if (curproxy->bind_proc)
7626 mask &= curproxy->bind_proc;
7627 /* mask cannot be null here thanks to the previous checks */
7628
David Carliere6c39412015-07-02 07:00:17 +00007629 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007630 bind_conf->bind_proc &= mask;
7631
7632 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007633 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",
7634 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007635 bind_conf->bind_proc = mask & ~(mask - 1);
7636 }
7637 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007638 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",
7639 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007640 bind_conf->bind_proc = 0;
7641 }
7642 }
7643
Willy Tarreauff01a212009-03-15 13:46:16 +01007644 switch (curproxy->mode) {
7645 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007646 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007647 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007648 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7649 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007650 cfgerr++;
7651 }
7652
7653 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007654 ha_warning("config : servers will be ignored for %s '%s'.\n",
7655 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007656 break;
7657
7658 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007659 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007660 break;
7661
7662 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007663 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007664 break;
7665 }
7666
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007667 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007668 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7669 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007670 err_code |= ERR_WARN;
7671 }
7672
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007673 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007674 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007675 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007676 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7677 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007678 cfgerr++;
7679 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007680#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007681 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007682 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7683 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007684 cfgerr++;
7685 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007686#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007687 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007688 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7689 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007690 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007691 }
7692 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007693 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007694 /* If no LB algo is set in a backend, and we're not in
7695 * transparent mode, dispatch mode nor proxy mode, we
7696 * want to use balance roundrobin by default.
7697 */
7698 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7699 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007700 }
7701 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007702
Willy Tarreau1620ec32011-08-06 17:05:02 +02007703 if (curproxy->options & PR_O_DISPATCH)
7704 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7705 else if (curproxy->options & PR_O_HTTP_PROXY)
7706 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7707 else if (curproxy->options & PR_O_TRANSP)
7708 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007709
Willy Tarreau1620ec32011-08-06 17:05:02 +02007710 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7711 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007712 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7713 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007714 err_code |= ERR_WARN;
7715 curproxy->options &= ~PR_O_DISABLE404;
7716 }
7717 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007718 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7719 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007720 err_code |= ERR_WARN;
7721 curproxy->options &= ~PR_O2_CHK_SNDST;
7722 }
Willy Tarreauef781042010-01-27 11:53:01 +01007723 }
7724
Simon Horman98637e52014-06-20 12:30:16 +09007725 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7726 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007727 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7728 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007729 cfgerr++;
7730 }
7731 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007732 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7733 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007734 cfgerr++;
7735 }
7736 }
7737
Simon Horman64e34162015-02-06 11:11:57 +09007738 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007739 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007740 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7741 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7742 "'email-alert myhostname', or 'email-alert to' "
7743 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7744 "to be present).\n",
7745 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007746 err_code |= ERR_WARN;
7747 free_email_alert(curproxy);
7748 }
7749 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007750 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007751 }
7752
Simon Horman98637e52014-06-20 12:30:16 +09007753 if (curproxy->check_command) {
7754 int clear = 0;
7755 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007756 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7757 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007758 err_code |= ERR_WARN;
7759 clear = 1;
7760 }
7761 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007762 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7763 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007764 cfgerr++;
7765 }
7766 if (clear) {
7767 free(curproxy->check_command);
7768 curproxy->check_command = NULL;
7769 }
7770 }
7771
7772 if (curproxy->check_path) {
7773 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007774 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7775 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007776 err_code |= ERR_WARN;
7777 free(curproxy->check_path);
7778 curproxy->check_path = NULL;
7779 }
7780 }
7781
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007782 /* if a default backend was specified, let's find it */
7783 if (curproxy->defbe.name) {
7784 struct proxy *target;
7785
Willy Tarreauafb39922015-05-26 12:04:09 +02007786 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007787 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007788 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7789 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007790 cfgerr++;
7791 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007792 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7793 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007794 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007795 } else if (target->mode != curproxy->mode &&
7796 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7797
Christopher Faulet767a84b2017-11-24 16:50:31 +01007798 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7799 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7800 curproxy->conf.file, curproxy->conf.line,
7801 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7802 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007803 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007804 } else {
7805 free(curproxy->defbe.name);
7806 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007807 /* Update tot_fe_maxconn for a further fullconn's computation */
7808 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007809 /* Emit a warning if this proxy also has some servers */
7810 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007811 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7812 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007813 err_code |= ERR_WARN;
7814 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007815 }
7816 }
7817
Emeric Brun3f783572017-01-12 11:21:28 +01007818 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7819 /* Case of listen without default backend
7820 * The curproxy will be its own default backend
7821 * so we update tot_fe_maxconn for a further
7822 * fullconn's computation */
7823 curproxy->tot_fe_maxconn += curproxy->maxconn;
7824 }
7825
Willy Tarreau55ea7572007-06-17 19:56:27 +02007826 /* find the target proxy for 'use_backend' rules */
7827 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007828 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007829 struct logformat_node *node;
7830 char *pxname;
7831
7832 /* Try to parse the string as a log format expression. If the result
7833 * of the parsing is only one entry containing a simple string, then
7834 * it's a standard string corresponding to a static rule, thus the
7835 * parsing is cancelled and be.name is restored to be resolved.
7836 */
7837 pxname = rule->be.name;
7838 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007839 curproxy->conf.args.ctx = ARGC_UBK;
7840 curproxy->conf.args.file = rule->file;
7841 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007842 err = NULL;
7843 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007844 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7845 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007846 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007847 cfgerr++;
7848 continue;
7849 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007850 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7851
7852 if (!LIST_ISEMPTY(&rule->be.expr)) {
7853 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7854 rule->dynamic = 1;
7855 free(pxname);
7856 continue;
7857 }
7858 /* simple string: free the expression and fall back to static rule */
7859 free(node->arg);
7860 free(node);
7861 }
7862
7863 rule->dynamic = 0;
7864 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007865
Willy Tarreauafb39922015-05-26 12:04:09 +02007866 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007867 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007868 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7869 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007870 cfgerr++;
7871 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007872 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7873 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007874 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007875 } else if (target->mode != curproxy->mode &&
7876 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7877
Christopher Faulet767a84b2017-11-24 16:50:31 +01007878 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7879 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7880 curproxy->conf.file, curproxy->conf.line,
7881 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7882 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007883 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007884 } else {
7885 free((void *)rule->be.name);
7886 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007887 /* For each target of switching rules, we update
7888 * their tot_fe_maxconn, except if a previous rule point
7889 * on the same backend or on the default backend */
7890 if (rule->be.backend != curproxy->defbe.be) {
7891 struct switching_rule *swrule;
7892
7893 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7894 if (rule == swrule) {
7895 target->tot_fe_maxconn += curproxy->maxconn;
7896 break;
7897 }
7898 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7899 /* there is multiple ref of this backend */
7900 break;
7901 }
7902 }
7903 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007904 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007905 }
7906
Willy Tarreau64ab6072014-09-16 12:17:36 +02007907 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007908 list_for_each_entry(srule, &curproxy->server_rules, list) {
7909 struct server *target = findserver(curproxy, srule->srv.name);
7910
7911 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007912 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7913 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007914 cfgerr++;
7915 continue;
7916 }
7917 free((void *)srule->srv.name);
7918 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007919 }
7920
Emeric Brunb982a3d2010-01-04 15:45:53 +01007921 /* find the target table for 'stick' rules */
7922 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7923 struct proxy *target;
7924
Emeric Brun1d33b292010-01-04 15:47:17 +01007925 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7926 if (mrule->flags & STK_IS_STORE)
7927 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7928
Emeric Brunb982a3d2010-01-04 15:45:53 +01007929 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007930 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007931 else
7932 target = curproxy;
7933
7934 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007935 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7936 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007937 cfgerr++;
7938 }
7939 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007940 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7941 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007942 cfgerr++;
7943 }
Willy Tarreau12785782012-04-27 21:37:17 +02007944 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007945 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7946 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007947 cfgerr++;
7948 }
7949 else {
7950 free((void *)mrule->table.name);
7951 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007952 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007953 }
7954 }
7955
7956 /* find the target table for 'store response' rules */
7957 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7958 struct proxy *target;
7959
Emeric Brun1d33b292010-01-04 15:47:17 +01007960 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7961
Emeric Brunb982a3d2010-01-04 15:45:53 +01007962 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007963 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007964 else
7965 target = curproxy;
7966
7967 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007968 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7969 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007970 cfgerr++;
7971 }
7972 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007973 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7974 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007975 cfgerr++;
7976 }
Willy Tarreau12785782012-04-27 21:37:17 +02007977 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007978 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7979 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007980 cfgerr++;
7981 }
7982 else {
7983 free((void *)mrule->table.name);
7984 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007985 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007986 }
7987 }
7988
Christopher Faulete4e830d2017-09-18 14:51:41 +02007989 /* check validity for 'tcp-request' layer 4 rules */
7990 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
7991 err = NULL;
7992 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007993 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007994 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01007995 cfgerr++;
7996 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02007997 }
7998
Christopher Faulete4e830d2017-09-18 14:51:41 +02007999 /* check validity for 'tcp-request' layer 5 rules */
8000 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
8001 err = NULL;
8002 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008003 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008004 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008005 cfgerr++;
8006 }
8007 }
8008
Christopher Faulete4e830d2017-09-18 14:51:41 +02008009 /* check validity for 'tcp-request' layer 6 rules */
8010 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8011 err = NULL;
8012 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008013 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008014 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008015 cfgerr++;
8016 }
8017 }
8018
Christopher Faulete4e830d2017-09-18 14:51:41 +02008019 /* check validity for 'http-request' layer 7 rules */
8020 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
8021 err = NULL;
8022 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008023 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008024 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008025 cfgerr++;
8026 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008027 }
8028
Christopher Faulete4e830d2017-09-18 14:51:41 +02008029 /* check validity for 'http-response' layer 7 rules */
8030 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
8031 err = NULL;
8032 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008033 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008034 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02008035 cfgerr++;
8036 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008037 }
8038
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008039 /* move any "block" rules at the beginning of the http-request rules */
8040 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8041 /* insert block_rules into http_req_rules at the beginning */
8042 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8043 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8044 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8045 curproxy->http_req_rules.n = curproxy->block_rules.n;
8046 LIST_INIT(&curproxy->block_rules);
8047 }
8048
Emeric Brun32da3c42010-09-23 18:39:19 +02008049 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008050 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008051
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008052 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008053 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8054 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008055 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008056 break;
8057 }
8058 }
8059
8060 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008061 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8062 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008063 free((void *)curproxy->table.peers.name);
8064 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008065 cfgerr++;
8066 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008067 else if (curpeers->state == PR_STSTOPPED) {
8068 /* silently disable this peers section */
8069 curproxy->table.peers.p = NULL;
8070 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008071 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008072 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8073 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008074 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008075 cfgerr++;
8076 }
8077 }
8078
Simon Horman9dc49962015-01-30 11:22:59 +09008079
8080 if (curproxy->email_alert.mailers.name) {
8081 struct mailers *curmailers = mailers;
8082
8083 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008084 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008085 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008086 }
Simon Horman9dc49962015-01-30 11:22:59 +09008087 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008088 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8089 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008090 free_email_alert(curproxy);
8091 cfgerr++;
8092 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008093 else {
8094 err = NULL;
8095 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008096 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008097 free(err);
8098 cfgerr++;
8099 }
8100 }
Simon Horman9dc49962015-01-30 11:22:59 +09008101 }
8102
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008103 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008104 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008105 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008106 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8107 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008108 cfgerr++;
8109 goto out_uri_auth_compat;
8110 }
8111
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008112 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008113 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008114 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008115 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008116
Willy Tarreau95fa4692010-02-01 13:05:50 +01008117 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8118 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008119
8120 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008121 uri_auth_compat_req[i++] = "realm";
8122 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8123 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008124
Willy Tarreau95fa4692010-02-01 13:05:50 +01008125 uri_auth_compat_req[i++] = "unless";
8126 uri_auth_compat_req[i++] = "{";
8127 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8128 uri_auth_compat_req[i++] = "}";
8129 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008130
Willy Tarreauff011f22011-01-06 17:51:27 +01008131 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8132 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008133 cfgerr++;
8134 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008135 }
8136
Willy Tarreauff011f22011-01-06 17:51:27 +01008137 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008138
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008139 if (curproxy->uri_auth->auth_realm) {
8140 free(curproxy->uri_auth->auth_realm);
8141 curproxy->uri_auth->auth_realm = NULL;
8142 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008143
8144 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008145 }
8146out_uri_auth_compat:
8147
Dragan Dosen43885c72015-10-01 13:18:13 +02008148 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008149 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008150 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8151 if (!curproxy->conf.logformat_sd_string) {
8152 /* set the default logformat_sd_string */
8153 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8154 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008155 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008156 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008157 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008158
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008159 /* compile the log format */
8160 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008161 if (curproxy->conf.logformat_string != default_http_log_format &&
8162 curproxy->conf.logformat_string != default_tcp_log_format &&
8163 curproxy->conf.logformat_string != clf_http_log_format)
8164 free(curproxy->conf.logformat_string);
8165 curproxy->conf.logformat_string = NULL;
8166 free(curproxy->conf.lfs_file);
8167 curproxy->conf.lfs_file = NULL;
8168 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008169
8170 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8171 free(curproxy->conf.logformat_sd_string);
8172 curproxy->conf.logformat_sd_string = NULL;
8173 free(curproxy->conf.lfsd_file);
8174 curproxy->conf.lfsd_file = NULL;
8175 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008176 }
8177
Willy Tarreau62a61232013-04-12 18:13:46 +02008178 if (curproxy->conf.logformat_string) {
8179 curproxy->conf.args.ctx = ARGC_LOG;
8180 curproxy->conf.args.file = curproxy->conf.lfs_file;
8181 curproxy->conf.args.line = curproxy->conf.lfs_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.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008184 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008185 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8186 curproxy->conf.lfs_file, curproxy->conf.lfs_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
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008194 if (curproxy->conf.logformat_sd_string) {
8195 curproxy->conf.args.ctx = ARGC_LOGSD;
8196 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8197 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008198 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008199 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 +01008200 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008201 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8202 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008203 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008204 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008205 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008206 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8207 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008208 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008209 cfgerr++;
8210 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008211 curproxy->conf.args.file = NULL;
8212 curproxy->conf.args.line = 0;
8213 }
8214
Willy Tarreau62a61232013-04-12 18:13:46 +02008215 if (curproxy->conf.uniqueid_format_string) {
8216 curproxy->conf.args.ctx = ARGC_UIF;
8217 curproxy->conf.args.file = curproxy->conf.uif_file;
8218 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008219 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008220 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 +01008221 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008222 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8223 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008224 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008225 cfgerr++;
8226 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008227 curproxy->conf.args.file = NULL;
8228 curproxy->conf.args.line = 0;
8229 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008230
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008231 /* only now we can check if some args remain unresolved.
8232 * This must be done after the users and groups resolution.
8233 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008234 cfgerr += smp_resolve_args(curproxy);
8235 if (!cfgerr)
8236 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008237
Willy Tarreau2738a142006-07-08 17:28:09 +02008238 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008239 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008240 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008241 (!curproxy->timeout.connect ||
8242 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008243 ha_warning("config : missing timeouts for %s '%s'.\n"
8244 " | While not properly invalid, you will certainly encounter various problems\n"
8245 " | with such a configuration. To fix this, please ensure that all following\n"
8246 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8247 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008248 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008249 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008250
Willy Tarreau1fa31262007-12-03 00:36:16 +01008251 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8252 * We must still support older configurations, so let's find out whether those
8253 * parameters have been set or must be copied from contimeouts.
8254 */
8255 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008256 if (!curproxy->timeout.tarpit ||
8257 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008258 /* tarpit timeout not set. We search in the following order:
8259 * default.tarpit, curr.connect, default.connect.
8260 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008261 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008262 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008263 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008264 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008265 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008266 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008267 }
8268 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008269 (!curproxy->timeout.queue ||
8270 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008271 /* queue timeout not set. We search in the following order:
8272 * default.queue, curr.connect, default.connect.
8273 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008274 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008275 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008276 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008277 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008278 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008279 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008280 }
8281 }
8282
Willy Tarreau1620ec32011-08-06 17:05:02 +02008283 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008284 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008285 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008286 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008287 }
8288
Willy Tarreau215663d2014-06-13 18:30:23 +02008289 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8290 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008291 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8292 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008293 err_code |= ERR_WARN;
8294 }
8295
Willy Tarreau193b8c62012-11-22 00:17:38 +01008296 /* ensure that cookie capture length is not too large */
8297 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008298 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8299 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008300 err_code |= ERR_WARN;
8301 curproxy->capture_len = global.tune.cookie_len - 1;
8302 }
8303
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008304 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008305 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008306 curproxy->req_cap_pool = create_pool("ptrcap",
8307 curproxy->nb_req_cap * sizeof(char *),
8308 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008309 }
8310
8311 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008312 curproxy->rsp_cap_pool = create_pool("ptrcap",
8313 curproxy->nb_rsp_cap * sizeof(char *),
8314 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008315 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008316
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008317 switch (curproxy->load_server_state_from_file) {
8318 case PR_SRV_STATE_FILE_UNSPEC:
8319 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8320 break;
8321 case PR_SRV_STATE_FILE_GLOBAL:
8322 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008323 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",
8324 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008325 err_code |= ERR_WARN;
8326 }
8327 break;
8328 }
8329
Willy Tarreaubaaee002006-06-26 02:48:02 +02008330 /* first, we will invert the servers list order */
8331 newsrv = NULL;
8332 while (curproxy->srv) {
8333 struct server *next;
8334
8335 next = curproxy->srv->next;
8336 curproxy->srv->next = newsrv;
8337 newsrv = curproxy->srv;
8338 if (!next)
8339 break;
8340 curproxy->srv = next;
8341 }
8342
Willy Tarreau17edc812014-01-03 12:14:34 +01008343 /* Check that no server name conflicts. This causes trouble in the stats.
8344 * We only emit a warning for the first conflict affecting each server,
8345 * in order to avoid combinatory explosion if all servers have the same
8346 * name. We do that only for servers which do not have an explicit ID,
8347 * because these IDs were made also for distinguishing them and we don't
8348 * want to annoy people who correctly manage them.
8349 */
8350 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8351 struct server *other_srv;
8352
8353 if (newsrv->puid)
8354 continue;
8355
8356 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8357 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008358 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",
8359 newsrv->conf.file, newsrv->conf.line,
8360 proxy_type_str(curproxy), curproxy->id,
8361 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008362 break;
8363 }
8364 }
8365 }
8366
Willy Tarreaudd701652010-05-25 23:03:02 +02008367 /* assign automatic UIDs to servers which don't have one yet */
8368 next_id = 1;
8369 newsrv = curproxy->srv;
8370 while (newsrv != NULL) {
8371 if (!newsrv->puid) {
8372 /* server ID not set, use automatic numbering with first
8373 * spare entry starting with next_svid.
8374 */
8375 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8376 newsrv->conf.id.key = newsrv->puid = next_id;
8377 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8378 }
8379 next_id++;
8380 newsrv = newsrv->next;
8381 }
8382
Willy Tarreau20697042007-11-15 23:26:18 +01008383 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008384 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008385
Willy Tarreau62c3be22012-01-20 13:12:32 +01008386 /*
8387 * If this server supports a maxconn parameter, it needs a dedicated
8388 * tasks to fill the emptied slots when a connection leaves.
8389 * Also, resolve deferred tracking dependency if needed.
8390 */
8391 newsrv = curproxy->srv;
8392 while (newsrv != NULL) {
8393 if (newsrv->minconn > newsrv->maxconn) {
8394 /* Only 'minconn' was specified, or it was higher than or equal
8395 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8396 * this will avoid further useless expensive computations.
8397 */
8398 newsrv->maxconn = newsrv->minconn;
8399 } else if (newsrv->maxconn && !newsrv->minconn) {
8400 /* minconn was not specified, so we set it to maxconn */
8401 newsrv->minconn = newsrv->maxconn;
8402 }
8403
Willy Tarreau17d45382016-12-22 21:16:08 +01008404 /* this will also properly set the transport layer for prod and checks */
8405 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8406 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8407 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8408 }
Emeric Brun94324a42012-10-11 14:00:19 +02008409
Willy Tarreau2f075e92013-12-03 11:11:34 +01008410 /* set the check type on the server */
8411 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8412
Willy Tarreau62c3be22012-01-20 13:12:32 +01008413 if (newsrv->trackit) {
8414 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008415 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008416 char *pname, *sname;
8417
8418 pname = newsrv->trackit;
8419 sname = strrchr(pname, '/');
8420
8421 if (sname)
8422 *sname++ = '\0';
8423 else {
8424 sname = pname;
8425 pname = NULL;
8426 }
8427
8428 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008429 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008430 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008431 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8432 proxy_type_str(curproxy), curproxy->id,
8433 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008434 cfgerr++;
8435 goto next_srv;
8436 }
8437 } else
8438 px = curproxy;
8439
8440 srv = findserver(px, sname);
8441 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008442 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8443 proxy_type_str(curproxy), curproxy->id,
8444 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008445 cfgerr++;
8446 goto next_srv;
8447 }
8448
Willy Tarreau32091232014-05-16 13:52:00 +02008449 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8450 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8451 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008452 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8453 "tracking as it does not have any check nor agent enabled.\n",
8454 proxy_type_str(curproxy), curproxy->id,
8455 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008456 cfgerr++;
8457 goto next_srv;
8458 }
8459
8460 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8461
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008462 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008463 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8464 "belongs to a tracking chain looping back to %s/%s.\n",
8465 proxy_type_str(curproxy), curproxy->id,
8466 newsrv->id, px->id, srv->id, px->id,
8467 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008468 cfgerr++;
8469 goto next_srv;
8470 }
8471
8472 if (curproxy != px &&
8473 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008474 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8475 "tracking: disable-on-404 option inconsistency.\n",
8476 proxy_type_str(curproxy), curproxy->id,
8477 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008478 cfgerr++;
8479 goto next_srv;
8480 }
8481
Willy Tarreau62c3be22012-01-20 13:12:32 +01008482 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008483 newsrv->tracknext = srv->trackers;
8484 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008485
8486 free(newsrv->trackit);
8487 newsrv->trackit = NULL;
8488 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008489
Willy Tarreau62c3be22012-01-20 13:12:32 +01008490 next_srv:
8491 newsrv = newsrv->next;
8492 }
8493
Olivier Houchard4e694042017-03-14 20:01:29 +01008494 /*
8495 * Try to generate dynamic cookies for servers now.
8496 * It couldn't be done earlier, since at the time we parsed
8497 * the server line, we may not have known yet that we
8498 * should use dynamic cookies, or the secret key may not
8499 * have been provided yet.
8500 */
8501 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8502 newsrv = curproxy->srv;
8503 while (newsrv != NULL) {
8504 srv_set_dyncookie(newsrv);
8505 newsrv = newsrv->next;
8506 }
8507
8508 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008509 /* We have to initialize the server lookup mechanism depending
8510 * on what LB algorithm was choosen.
8511 */
8512
8513 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8514 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8515 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008516 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8517 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8518 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02008519 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
8520 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8521 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02008522 } else {
8523 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8524 fwrr_init_server_groups(curproxy);
8525 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008526 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008527
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008528 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008529 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8530 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8531 fwlc_init_server_tree(curproxy);
8532 } else {
8533 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8534 fas_init_server_tree(curproxy);
8535 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008536 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008537
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008538 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008539 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8540 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8541 chash_init_server_tree(curproxy);
8542 } else {
8543 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8544 init_server_map(curproxy);
8545 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008546 break;
8547 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008548 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008549
8550 if (curproxy->options & PR_O_LOGASAP)
8551 curproxy->to_log &= ~LW_BYTES;
8552
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008553 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008554 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8555 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008556 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8557 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008558 err_code |= ERR_WARN;
8559 }
8560
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008561 if (curproxy->mode != PR_MODE_HTTP) {
8562 int optnum;
8563
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008564 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008565 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8566 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008567 err_code |= ERR_WARN;
8568 curproxy->uri_auth = NULL;
8569 }
8570
Willy Tarreaude7dc882017-03-10 11:49:21 +01008571 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008572 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8573 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008574 err_code |= ERR_WARN;
8575 }
8576
8577 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008578 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8579 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008580 err_code |= ERR_WARN;
8581 }
8582
8583 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008584 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8585 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008586 err_code |= ERR_WARN;
8587 }
8588
8589 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008590 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8591 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008592 err_code |= ERR_WARN;
8593 }
8594
8595 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008596 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8597 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008598 err_code |= ERR_WARN;
8599 }
8600
Willy Tarreau87cf5142011-08-19 22:57:24 +02008601 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008602 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8603 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008604 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008605 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008606 }
8607
8608 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008609 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8610 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008611 err_code |= ERR_WARN;
8612 curproxy->options &= ~PR_O_ORGTO;
8613 }
8614
8615 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8616 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8617 (curproxy->cap & cfg_opts[optnum].cap) &&
8618 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008619 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8620 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008621 err_code |= ERR_WARN;
8622 curproxy->options &= ~cfg_opts[optnum].val;
8623 }
8624 }
8625
8626 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8627 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8628 (curproxy->cap & cfg_opts2[optnum].cap) &&
8629 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008630 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8631 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008632 err_code |= ERR_WARN;
8633 curproxy->options2 &= ~cfg_opts2[optnum].val;
8634 }
8635 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008636
Willy Tarreau29fbe512015-08-20 19:35:14 +02008637#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008638 if (curproxy->conn_src.bind_hdr_occ) {
8639 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008640 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8641 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008642 err_code |= ERR_WARN;
8643 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008644#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008645 }
8646
Willy Tarreaubaaee002006-06-26 02:48:02 +02008647 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008648 * ensure that we're not cross-dressing a TCP server into HTTP.
8649 */
8650 newsrv = curproxy->srv;
8651 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008652 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008653 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8654 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008655 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008656 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008657
Willy Tarreau0cec3312011-10-31 13:49:26 +01008658 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008659 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8660 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008661 err_code |= ERR_WARN;
8662 }
8663
Willy Tarreauc93cd162014-05-13 15:54:22 +02008664 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008665 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8666 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008667 err_code |= ERR_WARN;
8668 }
8669
Willy Tarreau29fbe512015-08-20 19:35:14 +02008670#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008671 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8672 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008673 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8674 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008675 err_code |= ERR_WARN;
8676 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008677#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008678
Willy Tarreau46deab62018-04-28 07:18:15 +02008679 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
8680 curproxy->options &= ~PR_O_REUSE_MASK;
8681
Willy Tarreau4c183462017-01-06 12:21:38 +01008682 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8683 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8684 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8685 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8686 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008687 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",
8688 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008689 err_code |= ERR_WARN;
8690 }
8691
8692
8693 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008694 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",
8695 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008696 err_code |= ERR_WARN;
8697 }
8698 }
8699
Willy Tarreau21d2af32008-02-14 20:25:24 +01008700 newsrv = newsrv->next;
8701 }
8702
Willy Tarreaue42bd962014-09-16 16:21:19 +02008703 /* check if we have a frontend with "tcp-request content" looking at L7
8704 * with no inspect-delay
8705 */
8706 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008707 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8708 if (arule->action == ACT_TCP_CAPTURE &&
8709 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008710 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008711 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8712 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008713 break;
8714 }
8715
Christopher Faulete4e830d2017-09-18 14:51:41 +02008716 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008717 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8718 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8719 " This means that these rules will randomly find their contents. This can be fixed by"
8720 " setting the tcp-request inspect-delay.\n",
8721 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008722 err_code |= ERR_WARN;
8723 }
8724 }
8725
Christopher Fauletd7c91962015-04-30 11:48:27 +02008726 /* Check filter configuration, if any */
8727 cfgerr += flt_check(curproxy);
8728
Willy Tarreauc1a21672009-08-16 22:37:44 +02008729 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008730 if (!curproxy->accept)
8731 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008732
Willy Tarreauc1a21672009-08-16 22:37:44 +02008733 if (curproxy->tcp_req.inspect_delay ||
8734 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008735 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008736
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008737 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008738 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008739 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008740 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008741
8742 /* both TCP and HTTP must check switching rules */
8743 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008744
8745 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008746 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008747 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8748 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 +01008749 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008750 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8751 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008752 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008753 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008754 }
8755
8756 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008757 if (curproxy->tcp_req.inspect_delay ||
8758 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8759 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8760
Emeric Brun97679e72010-09-23 17:56:44 +02008761 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8762 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8763
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008764 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008765 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008766 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008767 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008768
8769 /* If the backend does requires RDP cookie persistence, we have to
8770 * enable the corresponding analyser.
8771 */
8772 if (curproxy->options2 & PR_O2_RDPC_PRST)
8773 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008774
8775 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008776 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008777 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8778 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 +01008779 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008780 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8781 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008782 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008783 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008784 }
Christopher Fauleta717b992018-04-10 14:43:00 +02008785
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008786 /* Check the mux protocols, if any, for each listener and server
Christopher Fauleta717b992018-04-10 14:43:00 +02008787 * attached to the current proxy */
8788 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8789 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8790
8791 if (!bind_conf->mux_proto)
8792 continue;
8793 if (!(bind_conf->mux_proto->mode & mode)) {
8794 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n",
8795 proxy_type_str(curproxy), curproxy->id,
8796 (int)bind_conf->mux_proto->token.len,
8797 bind_conf->mux_proto->token.ptr,
8798 bind_conf->arg, bind_conf->file, bind_conf->line);
8799 cfgerr++;
8800 }
8801 }
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008802 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8803 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8804
8805 if (!newsrv->mux_proto)
8806 continue;
8807 if (!(newsrv->mux_proto->mode & mode)) {
8808 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n",
8809 proxy_type_str(curproxy), curproxy->id,
8810 (int)newsrv->mux_proto->token.len,
8811 newsrv->mux_proto->token.ptr,
8812 newsrv->id, newsrv->conf.file, newsrv->conf.line);
8813 cfgerr++;
8814 }
8815 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008816 }
8817
8818 /***********************************************************/
8819 /* At this point, target names have already been resolved. */
8820 /***********************************************************/
8821
8822 /* Check multi-process mode compatibility */
8823
8824 if (global.nbproc > 1 && global.stats_fe) {
8825 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8826 unsigned long mask;
8827
8828 mask = nbits(global.nbproc);
8829 if (global.stats_fe->bind_proc)
8830 mask &= global.stats_fe->bind_proc;
8831
8832 if (bind_conf->bind_proc)
8833 mask &= bind_conf->bind_proc;
8834
8835 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008836 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008837 break;
8838 }
8839 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008840 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 +02008841 }
8842 }
8843
8844 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008845 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008846 if (curproxy->bind_proc)
8847 continue;
8848
8849 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8850 unsigned long mask;
8851
Willy Tarreaue428b082015-05-04 21:57:58 +02008852 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008853 curproxy->bind_proc |= mask;
8854 }
8855
8856 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008857 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008858 }
8859
8860 if (global.stats_fe) {
8861 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8862 unsigned long mask;
8863
Cyril Bonté06181952016-02-24 00:14:54 +01008864 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008865 global.stats_fe->bind_proc |= mask;
8866 }
8867 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008868 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008869 }
8870
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008871 /* propagate bindings from frontends to backends. Don't do it if there
8872 * are any fatal errors as we must not call it with unresolved proxies.
8873 */
8874 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008875 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008876 if (curproxy->cap & PR_CAP_FE)
8877 propagate_processes(curproxy, NULL);
8878 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008879 }
8880
8881 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008882 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008883 if (curproxy->bind_proc)
8884 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008885 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008886 }
8887
8888 /*******************************************************/
8889 /* At this step, all proxies have a non-null bind_proc */
8890 /*******************************************************/
8891
8892 /* perform the final checks before creating tasks */
8893
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008894 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008895 struct listener *listener;
8896 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008897
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008898 /* Configure SSL for each bind line.
8899 * Note: if configuration fails at some point, the ->ctx member
8900 * remains NULL so that listeners can later detach.
8901 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008902 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008903 if (bind_conf->xprt->prepare_bind_conf &&
8904 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008905 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008906 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008907
Willy Tarreaue6b98942007-10-29 01:09:36 +01008908 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008909 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008910 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008911 int nbproc;
8912
8913 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008914 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008915 nbits(global.nbproc));
8916
8917 if (!nbproc) /* no intersection between listener and frontend */
8918 nbproc = 1;
8919
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008920 if (!listener->luid) {
8921 /* listener ID not set, use automatic numbering with first
8922 * spare entry starting with next_luid.
8923 */
8924 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8925 listener->conf.id.key = listener->luid = next_id;
8926 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008927 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008928 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008929
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008930 /* enable separate counters */
8931 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008932 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008933 if (!listener->name)
8934 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008935 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008936
Willy Tarreaue6b98942007-10-29 01:09:36 +01008937 if (curproxy->options & PR_O_TCP_NOLING)
8938 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008939 if (!listener->maxconn)
8940 listener->maxconn = curproxy->maxconn;
8941 if (!listener->backlog)
8942 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008943 if (!listener->maxaccept)
8944 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8945
8946 /* we want to have an optimal behaviour on single process mode to
8947 * maximize the work at once, but in multi-process we want to keep
8948 * some fairness between processes, so we target half of the max
8949 * number of events to be balanced over all the processes the proxy
8950 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8951 * used to disable the limit.
8952 */
8953 if (listener->maxaccept > 0) {
8954 if (nbproc > 1)
8955 listener->maxaccept = (listener->maxaccept + 1) / 2;
8956 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8957 }
8958
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008959 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008960 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008961 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008962
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008963 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008964 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008965
Willy Tarreau620408f2016-10-21 16:37:51 +02008966 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8967 listener->options |= LI_O_TCP_L5_RULES;
8968
Willy Tarreaude3041d2010-05-31 10:56:17 +02008969 if (curproxy->mon_mask.s_addr)
8970 listener->options |= LI_O_CHK_MONNET;
8971
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008972 /* smart accept mode is automatic in HTTP mode */
8973 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008974 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008975 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8976 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008977 }
8978
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008979 /* Release unused SSL configs */
8980 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008981 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8982 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008983 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008984
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008985 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008986 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008987 int count, maxproc = 0;
8988
8989 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008990 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008991 if (count > maxproc)
8992 maxproc = count;
8993 }
8994 /* backends have 0, frontends have 1 or more */
8995 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008996 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8997 " limited to process assigned to the current request.\n",
8998 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008999
Willy Tarreau102df612014-05-07 23:56:38 +02009000 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009001 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
9002 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009003 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009004 }
Willy Tarreau102df612014-05-07 23:56:38 +02009005 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009006 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
9007 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009008 }
9009 }
Willy Tarreau918ff602011-07-25 16:33:49 +02009010
9011 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02009012 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02009013 if (curproxy->task) {
9014 curproxy->task->context = curproxy;
9015 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02009016 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009017 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
9018 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02009019 cfgerr++;
9020 }
Willy Tarreaub369a042014-09-16 13:21:03 +02009021 }
9022
Willy Tarreaufbb78422011-06-05 15:38:35 +02009023 /* automatically compute fullconn if not set. We must not do it in the
9024 * loop above because cross-references are not yet fully resolved.
9025 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009026 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009027 /* If <fullconn> is not set, let's set it to 10% of the sum of
9028 * the possible incoming frontend's maxconns.
9029 */
9030 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009031 /* we have the sum of the maxconns in <total>. We only
9032 * keep 10% of that sum to set the default fullconn, with
9033 * a hard minimum of 1 (to avoid a divide by zero).
9034 */
Emeric Brun3f783572017-01-12 11:21:28 +01009035 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02009036 if (!curproxy->fullconn)
9037 curproxy->fullconn = 1;
9038 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01009039 }
9040
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009041 /*
9042 * Recount currently required checks.
9043 */
9044
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009045 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009046 int optnum;
9047
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009048 for (optnum = 0; cfg_opts[optnum].name; optnum++)
9049 if (curproxy->options & cfg_opts[optnum].val)
9050 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009051
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009052 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
9053 if (curproxy->options2 & cfg_opts2[optnum].val)
9054 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009055 }
9056
Willy Tarreau0fca4832015-05-01 19:12:05 +02009057 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009058 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02009059 if (curproxy->table.peers.p)
9060 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
9061
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009062 if (cfg_peers) {
9063 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02009064 struct peer *p, *pb;
9065
Willy Tarreau1e273012015-05-01 19:15:17 +02009066 /* Remove all peers sections which don't have a valid listener,
9067 * which are not used by any table, or which are bound to more
9068 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009069 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009070 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009071 while (*last) {
9072 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009073
9074 if (curpeers->state == PR_STSTOPPED) {
9075 /* the "disabled" keyword was present */
9076 if (curpeers->peers_fe)
9077 stop_proxy(curpeers->peers_fe);
9078 curpeers->peers_fe = NULL;
9079 }
9080 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009081 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9082 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009083 }
David Carliere6c39412015-07-02 07:00:17 +00009084 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009085 /* either it's totally stopped or too much used */
9086 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009087 ha_alert("Peers section '%s': peers referenced by sections "
9088 "running in different processes (%d different ones). "
9089 "Check global.nbproc and all tables' bind-process "
9090 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009091 cfgerr++;
9092 }
9093 stop_proxy(curpeers->peers_fe);
9094 curpeers->peers_fe = NULL;
9095 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009096 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009097 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009098 last = &curpeers->next;
9099 continue;
9100 }
9101
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009102 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009103 p = curpeers->remote;
9104 while (p) {
9105 pb = p->next;
9106 free(p->id);
9107 free(p);
9108 p = pb;
9109 }
9110
9111 /* Destroy and unlink this curpeers section.
9112 * Note: curpeers is backed up into *last.
9113 */
9114 free(curpeers->id);
9115 curpeers = curpeers->next;
9116 free(*last);
9117 *last = curpeers;
9118 }
9119 }
9120
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009121 /* initialize stick-tables on backend capable proxies. This must not
9122 * be done earlier because the data size may be discovered while parsing
9123 * other proxies.
9124 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009125 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009126 if (curproxy->state == PR_STSTOPPED)
9127 continue;
9128
9129 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009130 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009131 cfgerr++;
9132 }
9133 }
9134
Simon Horman0d16a402015-01-30 11:22:58 +09009135 if (mailers) {
9136 struct mailers *curmailers = mailers, **last;
9137 struct mailer *m, *mb;
9138
9139 /* Remove all mailers sections which don't have a valid listener.
9140 * This can happen when a mailers section is never referenced.
9141 */
9142 last = &mailers;
9143 while (*last) {
9144 curmailers = *last;
9145 if (curmailers->users) {
9146 last = &curmailers->next;
9147 continue;
9148 }
9149
Christopher Faulet767a84b2017-11-24 16:50:31 +01009150 ha_warning("Removing incomplete section 'mailers %s'.\n",
9151 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009152
9153 m = curmailers->mailer_list;
9154 while (m) {
9155 mb = m->next;
9156 free(m->id);
9157 free(m);
9158 m = mb;
9159 }
9160
9161 /* Destroy and unlink this curmailers section.
9162 * Note: curmailers is backed up into *last.
9163 */
9164 free(curmailers->id);
9165 curmailers = curmailers->next;
9166 free(*last);
9167 *last = curmailers;
9168 }
9169 }
9170
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009171 /* Update server_state_file_name to backend name if backend is supposed to use
9172 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009173 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009174 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9175 curproxy->server_state_file_name == NULL)
9176 curproxy->server_state_file_name = strdup(curproxy->id);
9177 }
9178
Willy Tarreaubafbe012017-11-24 17:34:44 +01009179 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009180 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009181 MEM_F_SHARED);
9182
Ben Draut054fbee2018-04-13 15:43:04 -06009183 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
9184 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
9185 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
9186 curr_resolvers->id, curr_resolvers->conf.file,
9187 curr_resolvers->conf.line);
9188 err_code |= ERR_WARN;
9189 }
9190 }
9191
William Lallemand48b4bb42017-10-23 14:36:34 +02009192 list_for_each_entry(postparser, &postparsers, list) {
9193 if (postparser->func)
9194 cfgerr += postparser->func();
9195 }
9196
Willy Tarreaubb925012009-07-23 13:36:36 +02009197 if (cfgerr > 0)
9198 err_code |= ERR_ALERT | ERR_FATAL;
9199 out:
9200 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009201}
9202
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009203/*
9204 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9205 * parsing sessions.
9206 */
9207void cfg_register_keywords(struct cfg_kw_list *kwl)
9208{
9209 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9210}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009211
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009212/*
9213 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9214 */
9215void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9216{
9217 LIST_DEL(&kwl->list);
9218 LIST_INIT(&kwl->list);
9219}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009220
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009221/* this function register new section in the haproxy configuration file.
9222 * <section_name> is the name of this new section and <section_parser>
9223 * is the called parser. If two section declaration have the same name,
9224 * only the first declared is used.
9225 */
9226int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009227 int (*section_parser)(const char *, int, char **, int),
9228 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009229{
9230 struct cfg_section *cs;
9231
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009232 list_for_each_entry(cs, &sections, list) {
9233 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009234 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009235 return 0;
9236 }
9237 }
9238
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009239 cs = calloc(1, sizeof(*cs));
9240 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009241 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009242 return 0;
9243 }
9244
9245 cs->section_name = section_name;
9246 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009247 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009248
9249 LIST_ADDQ(&sections, &cs->list);
9250
9251 return 1;
9252}
9253
William Lallemand48b4bb42017-10-23 14:36:34 +02009254/* this function register a new function which will be called once the haproxy
9255 * configuration file has been parsed. It's useful to check dependencies
9256 * between sections or to resolve items once everything is parsed.
9257 */
9258int cfg_register_postparser(char *name, int (*func)())
9259{
9260 struct cfg_postparser *cp;
9261
9262 cp = calloc(1, sizeof(*cp));
9263 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009264 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009265 return 0;
9266 }
9267 cp->name = name;
9268 cp->func = func;
9269
9270 LIST_ADDQ(&postparsers, &cp->list);
9271
9272 return 1;
9273}
9274
Willy Tarreaubaaee002006-06-26 02:48:02 +02009275/*
David Carlier845efb52015-09-25 11:49:18 +01009276 * free all config section entries
9277 */
9278void cfg_unregister_sections(void)
9279{
9280 struct cfg_section *cs, *ics;
9281
9282 list_for_each_entry_safe(cs, ics, &sections, list) {
9283 LIST_DEL(&cs->list);
9284 free(cs);
9285 }
9286}
9287
Christopher Faulet7110b402016-10-26 11:09:44 +02009288void cfg_backup_sections(struct list *backup_sections)
9289{
9290 struct cfg_section *cs, *ics;
9291
9292 list_for_each_entry_safe(cs, ics, &sections, list) {
9293 LIST_DEL(&cs->list);
9294 LIST_ADDQ(backup_sections, &cs->list);
9295 }
9296}
9297
9298void cfg_restore_sections(struct list *backup_sections)
9299{
9300 struct cfg_section *cs, *ics;
9301
9302 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9303 LIST_DEL(&cs->list);
9304 LIST_ADDQ(&sections, &cs->list);
9305 }
9306}
9307
Willy Tarreau659fbf02016-05-26 17:55:28 +02009308__attribute__((constructor))
9309static void cfgparse_init(void)
9310{
9311 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009312 cfg_register_section("listen", cfg_parse_listen, NULL);
9313 cfg_register_section("frontend", cfg_parse_listen, NULL);
9314 cfg_register_section("backend", cfg_parse_listen, NULL);
9315 cfg_register_section("defaults", cfg_parse_listen, NULL);
9316 cfg_register_section("global", cfg_parse_global, NULL);
9317 cfg_register_section("userlist", cfg_parse_users, NULL);
9318 cfg_register_section("peers", cfg_parse_peers, NULL);
9319 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9320 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9321 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009322}
9323
David Carlier845efb52015-09-25 11:49:18 +01009324/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009325 * Local variables:
9326 * c-indent-level: 8
9327 * c-basic-offset: 8
9328 * End:
9329 */