blob: 3d224b9bee0d3fe93c81b6d04fd982d79e395bb4 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Configuration parser
3 *
Willy Tarreauff011f22011-01-06 17:51:27 +01004 * Copyright 2000-2011 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Cyril Bonté1a0191d2014-08-29 20:20:02 +020013#ifdef CONFIG_HAP_CRYPT
14/* This is to have crypt() defined on Linux */
15#define _GNU_SOURCE
16
17#ifdef NEED_CRYPT_H
18/* some platforms such as Solaris need this */
19#include <crypt.h>
20#endif
21#endif /* CONFIG_HAP_CRYPT */
22
Willy Tarreaubaaee002006-06-26 02:48:02 +020023#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <netdb.h>
27#include <ctype.h>
Willy Tarreau95c20ac2007-03-25 15:39:23 +020028#include <pwd.h>
29#include <grp.h>
Willy Tarreau0b4ed902007-03-26 00:18:40 +020030#include <errno.h>
Willy Tarreau3f49b302007-06-11 00:29:26 +020031#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <unistd.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035
Willy Tarreau2dd0d472006-06-29 17:53:05 +020036#include <common/cfgparse.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020037#include <common/chunk.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020038#include <common/config.h>
Willy Tarreau058e9072009-07-20 09:30:05 +020039#include <common/errors.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020040#include <common/memory.h>
41#include <common/standard.h>
42#include <common/time.h>
43#include <common/uri_auth.h>
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +010044#include <common/namespace.h>
Emeric Brunc60def82017-09-27 14:59:38 +020045#include <common/hathreads.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020046
47#include <types/capture.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020048#include <types/compression.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020049#include <types/filters.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020050#include <types/global.h>
Willy Tarreau3fdb3662012-11-12 00:42:33 +010051#include <types/obj_type.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020052#include <types/peers.h>
Simon Horman0d16a402015-01-30 11:22:58 +090053#include <types/mailers.h>
Baptiste Assmann325137d2015-04-13 23:40:55 +020054#include <types/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010055#include <types/stats.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020056
Willy Tarreaueb0c6142007-05-07 00:53:22 +020057#include <proto/acl.h>
Christopher Faulet4fce0d82017-09-18 11:57:31 +020058#include <proto/action.h>
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +010059#include <proto/auth.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020060#include <proto/backend.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020061#include <proto/channel.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020062#include <proto/checks.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020063#include <proto/compression.h>
Baptiste Assmann201c07f2017-05-22 15:17:15 +020064#include <proto/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010065#include <proto/stats.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020066#include <proto/filters.h>
Willy Tarreaueb472682010-05-28 18:46:57 +020067#include <proto/frontend.h>
Willy Tarreau34eb6712011-10-24 18:15:04 +020068#include <proto/hdr_idx.h>
Willy Tarreau6b2e11b2009-10-01 07:52:15 +020069#include <proto/lb_chash.h>
Willy Tarreauf09c6602012-02-13 17:12:08 +010070#include <proto/lb_fas.h>
Willy Tarreauf89c1872009-10-01 11:19:37 +020071#include <proto/lb_fwlc.h>
72#include <proto/lb_fwrr.h>
73#include <proto/lb_map.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020074#include <proto/listener.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020075#include <proto/log.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020076#include <proto/protocol.h>
Willy Tarreaue6b98942007-10-29 01:09:36 +010077#include <proto/proto_http.h>
Willy Tarreau2b5652f2006-12-31 17:46:05 +010078#include <proto/proxy.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020079#include <proto/peers.h>
Willy Tarreaucd3b0942012-04-27 21:52:18 +020080#include <proto/sample.h>
Willy Tarreau9903f0e2015-04-04 18:50:31 +020081#include <proto/session.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020082#include <proto/server.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020083#include <proto/stream.h>
Emeric Brunb982a3d2010-01-04 15:45:53 +010084#include <proto/stick_table.h>
Willy Tarreau39713102016-11-25 15:49:32 +010085#include <proto/task.h>
86#include <proto/tcp_rules.h>
Olivier Houchard673867c2018-05-25 16:58:52 +020087#include <proto/connection.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020088
89
Willy Tarreauf3c69202006-07-09 16:42:34 +020090/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
91 * ssl-hello-chk option to ensure that the remote server speaks SSL.
92 *
93 * Check RFC 2246 (TLSv1.0) sections A.3 and A.4 for details.
94 */
95const char sslv3_client_hello_pkt[] = {
96 "\x16" /* ContentType : 0x16 = Hanshake */
97 "\x03\x00" /* ProtocolVersion : 0x0300 = SSLv3 */
98 "\x00\x79" /* ContentLength : 0x79 bytes after this one */
99 "\x01" /* HanshakeType : 0x01 = CLIENT HELLO */
100 "\x00\x00\x75" /* HandshakeLength : 0x75 bytes after this one */
101 "\x03\x00" /* Hello Version : 0x0300 = v3 */
102 "\x00\x00\x00\x00" /* Unix GMT Time (s) : filled with <now> (@0x0B) */
103 "HAPROXYSSLCHK\nHAPROXYSSLCHK\n" /* Random : must be exactly 28 bytes */
104 "\x00" /* Session ID length : empty (no session ID) */
105 "\x00\x4E" /* Cipher Suite Length : 78 bytes after this one */
106 "\x00\x01" "\x00\x02" "\x00\x03" "\x00\x04" /* 39 most common ciphers : */
107 "\x00\x05" "\x00\x06" "\x00\x07" "\x00\x08" /* 0x01...0x1B, 0x2F...0x3A */
108 "\x00\x09" "\x00\x0A" "\x00\x0B" "\x00\x0C" /* This covers RSA/DH, */
109 "\x00\x0D" "\x00\x0E" "\x00\x0F" "\x00\x10" /* various bit lengths, */
110 "\x00\x11" "\x00\x12" "\x00\x13" "\x00\x14" /* SHA1/MD5, DES/3DES/AES... */
111 "\x00\x15" "\x00\x16" "\x00\x17" "\x00\x18"
112 "\x00\x19" "\x00\x1A" "\x00\x1B" "\x00\x2F"
113 "\x00\x30" "\x00\x31" "\x00\x32" "\x00\x33"
114 "\x00\x34" "\x00\x35" "\x00\x36" "\x00\x37"
115 "\x00\x38" "\x00\x39" "\x00\x3A"
116 "\x01" /* Compression Length : 0x01 = 1 byte for types */
117 "\x00" /* Compression Type : 0x00 = NULL compression */
118};
119
Willy Tarreau3842f002009-06-14 11:39:52 +0200120/* various keyword modifiers */
121enum kw_mod {
122 KWM_STD = 0, /* normal */
123 KWM_NO, /* "no" prefixed before the keyword */
124 KWM_DEF, /* "default" prefixed before the keyword */
125};
126
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100127/* permit to store configuration section */
128struct cfg_section {
129 struct list list;
130 char *section_name;
131 int (*section_parser)(const char *, int, char **, int);
William Lallemandd2ff56d2017-10-16 11:06:50 +0200132 int (*post_section_parser)();
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100133};
134
135/* Used to chain configuration sections definitions. This list
136 * stores struct cfg_section
137 */
138struct list sections = LIST_HEAD_INIT(sections);
139
William Lallemand48b4bb42017-10-23 14:36:34 +0200140/* store post configuration parsing */
141
142struct cfg_postparser {
143 struct list list;
144 char *name;
145 int (*func)();
146};
147
148struct list postparsers = LIST_HEAD_INIT(postparsers);
149
Willy Tarreau13943ab2006-12-31 00:24:10 +0100150/* some of the most common options which are also the easiest to handle */
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100151struct cfg_opt {
Willy Tarreau13943ab2006-12-31 00:24:10 +0100152 const char *name;
153 unsigned int val;
154 unsigned int cap;
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100155 unsigned int checks;
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100156 unsigned int mode;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100157};
158
159/* proxy->options */
160static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100161{
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100162 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
163 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
164 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
165 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
166 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
167 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100168 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau9fbe18e2015-05-01 22:42:08 +0200169 { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau0f228a02015-05-01 15:37:53 +0200170 { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreau9420b122013-12-15 18:58:25 +0100171 { "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100172 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
173 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
174 { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100175 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100176#ifdef TPROXY
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100177 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100178#else
179 { "transparent", 0, 0, 0, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100180#endif
181
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100182 { NULL, 0, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100183};
184
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100185/* proxy->options2 */
186static const struct cfg_opt cfg_opts2[] =
187{
188#ifdef CONFIG_HAP_LINUX_SPLICE
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100189 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
190 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
191 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100192#else
193 { "splice-request", 0, 0, 0, 0 },
194 { "splice-response", 0, 0, 0, 0 },
195 { "splice-auto", 0, 0, 0, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100196#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100197 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
198 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
199 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
200 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
201 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0, 0 },
202 { "socket-stats", PR_O2_SOCKSTAT, PR_CAP_FE, 0, 0 },
203 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0, 0 },
204 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0, 0 },
205 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Jamie Gloudon801a0a32012-08-25 00:18:33 -0400206 { "independent-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100207 { "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreaue52564c2010-04-27 22:19:14 +0200208 { "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau96e31212011-05-30 18:10:30 +0200209 { "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100210 { NULL, 0, 0, 0 }
211};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200212
Willy Tarreau6daf3432008-01-22 16:44:08 +0100213static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200214static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
215int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100216int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100217char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200218
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200219/* List head of all known configuration keywords */
220static struct cfg_kw_list cfg_keywords = {
221 .list = LIST_HEAD_INIT(cfg_keywords.list)
222};
223
Willy Tarreaubaaee002006-06-26 02:48:02 +0200224/*
225 * converts <str> to a list of listeners which are dynamically allocated.
226 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
227 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
228 * - <port> is a numerical port from 1 to 65535 ;
229 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
230 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200231 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
232 * not NULL, it must be a valid pointer to either NULL or a freeable area that
233 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200234 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200235int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200236{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100237 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200238 int port, end;
239
240 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200241
Willy Tarreaubaaee002006-06-26 02:48:02 +0200242 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100243 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200244 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100245 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200246
247 str = next;
248 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100249 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200250 *next++ = 0;
251 }
252
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100253 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200254 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200255 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100256 if (!ss2)
257 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200258
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100259 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100260 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200261 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100262 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200263 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200264
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100265 if (!port || !end) {
266 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
267 goto fail;
268 }
269
Emeric Bruned760922010-10-22 17:59:25 +0200270 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200271 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200272 goto fail;
273 }
274
275 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200276 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200277 goto fail;
278 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200279 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100280 else if (ss2->ss_family == AF_UNSPEC) {
281 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100282 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100283
284 /* We want to attach to an already bound fd whose number
285 * is in the addr part of ss2 when cast to sockaddr_in.
286 * Note that by definition there is a single listener.
287 * We still have to determine the address family to
288 * register the correct protocol.
289 */
290 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
291 addr_len = sizeof(*ss2);
292 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
293 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
294 goto fail;
295 }
296
297 port = end = get_host_port(ss2);
298 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200299
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100300 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100301 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200302 memprintf(err, "%s for address '%s'.\n", *err, str);
303 goto fail;
304 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200305 } /* end while(next) */
306 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200307 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200308 fail:
309 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200310 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200311}
312
William Lallemand6e62fb62015-04-28 16:55:23 +0200313/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100314 * Report an error in <msg> when there are too many arguments. This version is
315 * intended to be used by keyword parsers so that the message will be included
316 * into the general error message. The index is the current keyword in args.
317 * Return 0 if the number of argument is correct, otherwise build a message and
318 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
319 * message may also be null, it will simply not be produced (useful to check only).
320 * <msg> and <err_code> are only affected on error.
321 */
322int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
323{
324 int i;
325
326 if (!*args[index + maxarg + 1])
327 return 0;
328
329 if (msg) {
330 *msg = NULL;
331 memprintf(msg, "%s", args[0]);
332 for (i = 1; i <= index; i++)
333 memprintf(msg, "%s %s", *msg, args[i]);
334
335 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
336 }
337 if (err_code)
338 *err_code |= ERR_ALERT | ERR_FATAL;
339
340 return 1;
341}
342
343/*
344 * same as too_many_args_idx with a 0 index
345 */
346int too_many_args(int maxarg, char **args, char **msg, int *err_code)
347{
348 return too_many_args_idx(maxarg, 0, args, msg, err_code);
349}
350
351/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200352 * Report a fatal Alert when there is too much arguments
353 * The index is the current keyword in args
354 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
355 * Fill err_code with an ERR_ALERT and an ERR_FATAL
356 */
357int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
358{
359 char *kw = NULL;
360 int i;
361
362 if (!*args[index + maxarg + 1])
363 return 0;
364
365 memprintf(&kw, "%s", args[0]);
366 for (i = 1; i <= index; i++) {
367 memprintf(&kw, "%s %s", kw, args[i]);
368 }
369
Christopher Faulet767a84b2017-11-24 16:50:31 +0100370 ha_alert("parsing [%s:%d] : '%s' cannot handle unexpected argument '%s'.\n", file, linenum, kw, args[index + maxarg + 1]);
William Lallemand6e62fb62015-04-28 16:55:23 +0200371 free(kw);
372 *err_code |= ERR_ALERT | ERR_FATAL;
373 return 1;
374}
375
376/*
377 * same as alertif_too_many_args_idx with a 0 index
378 */
379int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
380{
381 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
382}
383
Willy Tarreau620408f2016-10-21 16:37:51 +0200384/* Report a warning if a rule is placed after a 'tcp-request session' rule.
385 * Return 1 if the warning has been emitted, otherwise 0.
386 */
387int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
388{
389 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100390 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
391 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200392 return 1;
393 }
394 return 0;
395}
396
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200397/* Report a warning if a rule is placed after a 'tcp-request content' rule.
398 * Return 1 if the warning has been emitted, otherwise 0.
399 */
400int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
401{
402 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100403 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
404 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200405 return 1;
406 }
407 return 0;
408}
409
Willy Tarreau721d8e02017-12-01 18:25:08 +0100410/* Report a warning if a rule is placed after a 'monitor fail' rule.
411 * Return 1 if the warning has been emitted, otherwise 0.
412 */
413int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
414{
415 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
416 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
417 file, line, arg);
418 return 1;
419 }
420 return 0;
421}
422
Willy Tarreau61d18892009-03-31 10:49:21 +0200423/* Report a warning if a rule is placed after a 'block' rule.
424 * Return 1 if the warning has been emitted, otherwise 0.
425 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100426int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200427{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200428 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100429 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
430 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200431 return 1;
432 }
433 return 0;
434}
435
Willy Tarreau5002f572014-04-23 01:32:02 +0200436/* Report a warning if a rule is placed after an 'http_request' rule.
437 * Return 1 if the warning has been emitted, otherwise 0.
438 */
439int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
440{
441 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100442 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
443 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200444 return 1;
445 }
446 return 0;
447}
448
Willy Tarreau61d18892009-03-31 10:49:21 +0200449/* Report a warning if a rule is placed after a reqrewrite rule.
450 * Return 1 if the warning has been emitted, otherwise 0.
451 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100452int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200453{
454 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100455 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
456 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200457 return 1;
458 }
459 return 0;
460}
461
462/* Report a warning if a rule is placed after a reqadd rule.
463 * Return 1 if the warning has been emitted, otherwise 0.
464 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100465int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200466{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100467 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100468 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
469 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200470 return 1;
471 }
472 return 0;
473}
474
475/* Report a warning if a rule is placed after a redirect rule.
476 * Return 1 if the warning has been emitted, otherwise 0.
477 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100478int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200479{
480 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100481 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
482 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200483 return 1;
484 }
485 return 0;
486}
487
488/* Report a warning if a rule is placed after a 'use_backend' rule.
489 * Return 1 if the warning has been emitted, otherwise 0.
490 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100491int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200492{
493 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100494 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
495 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200496 return 1;
497 }
498 return 0;
499}
500
Willy Tarreauee445d92014-04-23 01:39:04 +0200501/* Report a warning if a rule is placed after a 'use-server' rule.
502 * Return 1 if the warning has been emitted, otherwise 0.
503 */
504int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
505{
506 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100507 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
508 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200509 return 1;
510 }
511 return 0;
512}
513
Willy Tarreaud39ad442016-11-25 15:16:12 +0100514/* report a warning if a redirect rule is dangerously placed */
515int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200516{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100517 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200518 warnif_rule_after_use_server(proxy, file, line, arg);
519}
520
Willy Tarreaud39ad442016-11-25 15:16:12 +0100521/* report a warning if a reqadd rule is dangerously placed */
522int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200523{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100524 return warnif_rule_after_redirect(proxy, file, line, arg) ||
525 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200526}
527
Willy Tarreaud39ad442016-11-25 15:16:12 +0100528/* report a warning if a reqxxx rule is dangerously placed */
529int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200530{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100531 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
532 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200533}
534
535/* report a warning if an http-request rule is dangerously placed */
536int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
537{
Willy Tarreau61d18892009-03-31 10:49:21 +0200538 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100539 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200540}
541
Willy Tarreaud39ad442016-11-25 15:16:12 +0100542/* report a warning if a block rule is dangerously placed */
543int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200544{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100545 return warnif_rule_after_http_req(proxy, file, line, arg) ||
546 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200547}
548
Willy Tarreau721d8e02017-12-01 18:25:08 +0100549/* report a warning if a block rule is dangerously placed */
550int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200551{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100552 return warnif_rule_after_block(proxy, file, line, arg) ||
553 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200554}
555
Willy Tarreau721d8e02017-12-01 18:25:08 +0100556/* report a warning if a "tcp request content" rule is dangerously placed */
557int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
558{
559 return warnif_rule_after_monitor(proxy, file, line, arg) ||
560 warnif_misplaced_monitor(proxy, file, line, arg);
561}
562
Willy Tarreaud39ad442016-11-25 15:16:12 +0100563/* report a warning if a "tcp request session" rule is dangerously placed */
564int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200565{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100566 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
567 warnif_misplaced_tcp_cont(proxy, file, line, arg);
568}
569
570/* report a warning if a "tcp request connection" rule is dangerously placed */
571int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
572{
573 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
574 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200575}
576
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100577/* Report it if a request ACL condition uses some keywords that are incompatible
578 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
579 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
580 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100581 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100582static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100583{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100584 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200585 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100586
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100587 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100588 return 0;
589
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100590 acl = acl_cond_conflicts(cond, where);
591 if (acl) {
592 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100593 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
594 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100595 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100596 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
597 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100598 return ERR_WARN;
599 }
600 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100601 return 0;
602
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100603 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100604 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
605 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100606 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100607 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
608 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100609 return ERR_WARN;
610}
611
Christopher Faulet62519022017-10-16 15:49:32 +0200612/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100613 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100614 * two such numbers delimited by a dash ('-'). On success, it returns
615 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200616 *
617 * Note: this function can also be used to parse a thread number or a set of
618 * threads.
619 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100620int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200621{
Christopher Faulet26028f62017-11-22 15:01:51 +0100622 if (autoinc) {
623 *autoinc = 0;
624 if (strncmp(arg, "auto:", 5) == 0) {
625 arg += 5;
626 *autoinc = 1;
627 }
628 }
629
Christopher Faulet62519022017-10-16 15:49:32 +0200630 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100631 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200632 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100633 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200634 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100635 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200636 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100637 char *dash;
638 unsigned int low, high;
639
Christopher Faulet5ab51772017-11-22 11:21:58 +0100640 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100641 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100642 return -1;
643 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100644
645 low = high = str2uic(arg);
646 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100647 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
648
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100649 if (high < low) {
650 unsigned int swap = low;
651 low = high;
652 high = swap;
653 }
654
Christopher Faulet5ab51772017-11-22 11:21:58 +0100655 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100656 memprintf(err, "'%s' is not a valid number/range."
657 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100658 arg, LONGBITS);
659 return 1;
660 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100661
662 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100663 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200664 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100665
Christopher Faulet5ab51772017-11-22 11:21:58 +0100666 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200667}
668
David Carlier7e351ee2017-12-01 09:14:02 +0000669#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200670/* Parse cpu sets. Each CPU set is either a unique number between 0 and
671 * <LONGBITS> or a range with two such numbers delimited by a dash
672 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
673 * returns 0. otherwise it returns 1 with an error message in <err>.
674 */
675static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
676{
677 int cur_arg = 0;
678
679 *cpu_set = 0;
680 while (*args[cur_arg]) {
681 char *dash;
682 unsigned int low, high;
683
684 if (!isdigit((int)*args[cur_arg])) {
685 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
686 return -1;
687 }
688
689 low = high = str2uic(args[cur_arg]);
690 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100691 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200692
693 if (high < low) {
694 unsigned int swap = low;
695 low = high;
696 high = swap;
697 }
698
699 if (high >= LONGBITS) {
700 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
701 return 1;
702 }
703
704 while (low <= high)
705 *cpu_set |= 1UL << low++;
706
707 cur_arg++;
708 }
709 return 0;
710}
David Carlier7e351ee2017-12-01 09:14:02 +0000711#endif
712
Willy Tarreaubaaee002006-06-26 02:48:02 +0200713/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200714 * parse a line in a <global> section. Returns the error code, 0 if OK, or
715 * any combination of :
716 * - ERR_ABORT: must abort ASAP
717 * - ERR_FATAL: we can continue parsing but not start the service
718 * - ERR_WARN: a warning has been emitted
719 * - ERR_ALERT: an alert has been emitted
720 * Only the two first ones can stop processing, the two others are just
721 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200722 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200723int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200724{
Willy Tarreau058e9072009-07-20 09:30:05 +0200725 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200726 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200727
728 if (!strcmp(args[0], "global")) { /* new section */
729 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200730 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200731 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200732 }
733 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200734 if (alertif_too_many_args(0, file, linenum, args, &err_code))
735 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200736 global.mode |= MODE_DAEMON;
737 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200738 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200739 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200740 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200741 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100742 if (!strcmp(args[1], "no-exit-on-failure")) {
743 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200744 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100745 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
William Lallemand69f9b3b2017-06-01 17:38:54 +0200746 err_code |= ERR_ALERT | ERR_FATAL;
747 goto out;
748 }
749 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200750 global.mode |= MODE_MWORKER;
751 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200752 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200753 if (alertif_too_many_args(0, file, linenum, args, &err_code))
754 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200755 global.mode |= MODE_DEBUG;
756 }
757 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200758 if (alertif_too_many_args(0, file, linenum, args, &err_code))
759 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100760 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200761 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200762 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200763 if (alertif_too_many_args(0, file, linenum, args, &err_code))
764 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100765 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200766 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200767 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200768 if (alertif_too_many_args(0, file, linenum, args, &err_code))
769 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100770 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200771 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100772 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200773 if (alertif_too_many_args(0, file, linenum, args, &err_code))
774 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100775 global.tune.options &= ~GTUNE_USE_SPLICE;
776 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200777 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200778 if (alertif_too_many_args(0, file, linenum, args, &err_code))
779 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200780 global.tune.options &= ~GTUNE_USE_GAI;
781 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000782 else if (!strcmp(args[0], "noreuseport")) {
783 if (alertif_too_many_args(0, file, linenum, args, &err_code))
784 goto out;
785 global.tune.options &= ~GTUNE_USE_REUSEPORT;
786 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200787 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200788 if (alertif_too_many_args(0, file, linenum, args, &err_code))
789 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200790 global.mode |= MODE_QUIET;
791 }
Olivier Houchard1599b802018-05-24 18:59:04 +0200792 else if (!strcmp(args[0], "tune.runqueue-depth")) {
793 if (alertif_too_many_args(1, file, linenum, args, &err_code))
794 goto out;
795 if (global.tune.runqueue_depth != 0) {
796 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
797 err_code |= ERR_ALERT;
798 goto out;
799 }
800 if (*(args[1]) == 0) {
801 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
802 err_code |= ERR_ALERT | ERR_FATAL;
803 goto out;
804 }
805 global.tune.runqueue_depth = atol(args[1]);
806
807 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200808 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200809 if (alertif_too_many_args(1, file, linenum, args, &err_code))
810 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200811 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100812 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200813 err_code |= ERR_ALERT;
814 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200815 }
816 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100817 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200818 err_code |= ERR_ALERT | ERR_FATAL;
819 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200820 }
821 global.tune.maxpollevents = atol(args[1]);
822 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100823 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200824 if (alertif_too_many_args(1, file, linenum, args, &err_code))
825 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100826 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100827 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200828 err_code |= ERR_ALERT;
829 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100830 }
831 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100832 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200833 err_code |= ERR_ALERT | ERR_FATAL;
834 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100835 }
836 global.tune.maxaccept = atol(args[1]);
837 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200838 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200839 if (alertif_too_many_args(1, file, linenum, args, &err_code))
840 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200841 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100842 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200843 err_code |= ERR_ALERT | ERR_FATAL;
844 goto out;
845 }
846 global.tune.chksize = atol(args[1]);
847 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100848 else if (!strcmp(args[0], "tune.recv_enough")) {
849 if (alertif_too_many_args(1, file, linenum, args, &err_code))
850 goto out;
851 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100852 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100853 err_code |= ERR_ALERT | ERR_FATAL;
854 goto out;
855 }
856 global.tune.recv_enough = atol(args[1]);
857 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100858 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200859 if (alertif_too_many_args(1, file, linenum, args, &err_code))
860 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100861 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100862 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100863 err_code |= ERR_ALERT | ERR_FATAL;
864 goto out;
865 }
866 global.tune.buf_limit = atol(args[1]);
867 if (global.tune.buf_limit) {
868 if (global.tune.buf_limit < 3)
869 global.tune.buf_limit = 3;
870 if (global.tune.buf_limit <= global.tune.reserved_bufs)
871 global.tune.buf_limit = global.tune.reserved_bufs + 1;
872 }
873 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100874 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200875 if (alertif_too_many_args(1, file, linenum, args, &err_code))
876 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100877 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100878 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100879 err_code |= ERR_ALERT | ERR_FATAL;
880 goto out;
881 }
882 global.tune.reserved_bufs = atol(args[1]);
883 if (global.tune.reserved_bufs < 2)
884 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100885 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
886 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100887 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200888 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200889 if (alertif_too_many_args(1, file, linenum, args, &err_code))
890 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200891 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100892 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200893 err_code |= ERR_ALERT | ERR_FATAL;
894 goto out;
895 }
896 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200897 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100898 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200899 err_code |= ERR_ALERT | ERR_FATAL;
900 goto out;
901 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200902 }
903 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200904 if (alertif_too_many_args(1, file, linenum, args, &err_code))
905 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200906 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100907 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200908 err_code |= ERR_ALERT | ERR_FATAL;
909 goto out;
910 }
911 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200912 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100913 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200914 err_code |= ERR_ALERT | ERR_FATAL;
915 goto out;
916 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200917 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100918 else if (!strcmp(args[0], "tune.idletimer")) {
919 unsigned int idle;
920 const char *res;
921
William Lallemand1a748ae2015-05-19 16:37:23 +0200922 if (alertif_too_many_args(1, file, linenum, args, &err_code))
923 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100924 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100925 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100926 err_code |= ERR_ALERT | ERR_FATAL;
927 goto out;
928 }
929
930 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
931 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100932 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100933 file, linenum, *res, args[0]);
934 err_code |= ERR_ALERT | ERR_FATAL;
935 goto out;
936 }
937
938 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100939 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100940 err_code |= ERR_ALERT | ERR_FATAL;
941 goto out;
942 }
943 global.tune.idle_timer = idle;
944 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100945 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200946 if (alertif_too_many_args(1, file, linenum, args, &err_code))
947 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100948 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100949 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100950 err_code |= ERR_ALERT;
951 goto out;
952 }
953 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100954 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100955 err_code |= ERR_ALERT | ERR_FATAL;
956 goto out;
957 }
958 global.tune.client_rcvbuf = atol(args[1]);
959 }
960 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200961 if (alertif_too_many_args(1, file, linenum, args, &err_code))
962 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100963 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100964 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100965 err_code |= ERR_ALERT;
966 goto out;
967 }
968 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100969 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100970 err_code |= ERR_ALERT | ERR_FATAL;
971 goto out;
972 }
973 global.tune.server_rcvbuf = atol(args[1]);
974 }
975 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200976 if (alertif_too_many_args(1, file, linenum, args, &err_code))
977 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100978 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100979 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100980 err_code |= ERR_ALERT;
981 goto out;
982 }
983 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100984 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100985 err_code |= ERR_ALERT | ERR_FATAL;
986 goto out;
987 }
988 global.tune.client_sndbuf = atol(args[1]);
989 }
990 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200991 if (alertif_too_many_args(1, file, linenum, args, &err_code))
992 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100993 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100994 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100995 err_code |= ERR_ALERT;
996 goto out;
997 }
998 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100999 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001000 err_code |= ERR_ALERT | ERR_FATAL;
1001 goto out;
1002 }
1003 global.tune.server_sndbuf = atol(args[1]);
1004 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001005 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001006 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1007 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001008 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001009 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001010 err_code |= ERR_ALERT | ERR_FATAL;
1011 goto out;
1012 }
1013 global.tune.pipesize = atol(args[1]);
1014 }
Willy Tarreau193b8c62012-11-22 00:17:38 +01001015 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001016 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1017 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001018 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001019 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001020 err_code |= ERR_ALERT | ERR_FATAL;
1021 goto out;
1022 }
1023 global.tune.cookie_len = atol(args[1]) + 1;
1024 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001025 else if (!strcmp(args[0], "tune.http.logurilen")) {
1026 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1027 goto out;
1028 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001029 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001030 err_code |= ERR_ALERT | ERR_FATAL;
1031 goto out;
1032 }
1033 global.tune.requri_len = atol(args[1]) + 1;
1034 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001035 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001036 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1037 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001038 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001039 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001040 err_code |= ERR_ALERT | ERR_FATAL;
1041 goto out;
1042 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001043 global.tune.max_http_hdr = atoi(args[1]);
1044 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001045 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1046 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001047 err_code |= ERR_ALERT | ERR_FATAL;
1048 goto out;
1049 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001050 }
William Lallemandf3747832012-11-09 12:33:10 +01001051 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001052 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1053 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001054 if (*args[1]) {
1055 global.tune.comp_maxlevel = atoi(args[1]);
1056 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001057 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1058 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001059 err_code |= ERR_ALERT | ERR_FATAL;
1060 goto out;
1061 }
1062 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001063 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1064 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001065 err_code |= ERR_ALERT | ERR_FATAL;
1066 goto out;
1067 }
1068 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001069 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1070 if (*args[1]) {
1071 global.tune.pattern_cache = atoi(args[1]);
1072 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001073 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1074 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001075 err_code |= ERR_ALERT | ERR_FATAL;
1076 goto out;
1077 }
1078 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001079 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1080 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001081 err_code |= ERR_ALERT | ERR_FATAL;
1082 goto out;
1083 }
1084 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001085 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001086 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1087 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001088 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001089 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001090 err_code |= ERR_ALERT;
1091 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001092 }
1093 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001094 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001095 err_code |= ERR_ALERT | ERR_FATAL;
1096 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001097 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001098 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001099 ha_warning("parsing [%s:%d] : uid: string '%s' is not a number.\n | You might want to use the 'user' parameter to use a system user name.\n", file, linenum, args[1]);
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001100 err_code |= ERR_WARN;
1101 goto out;
1102 }
1103
Willy Tarreaubaaee002006-06-26 02:48:02 +02001104 }
1105 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001106 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1107 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001108 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001109 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001110 err_code |= ERR_ALERT;
1111 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001112 }
1113 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001114 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001115 err_code |= ERR_ALERT | ERR_FATAL;
1116 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001117 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001118 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001119 ha_warning("parsing [%s:%d] : gid: string '%s' is not a number.\n | You might want to use the 'group' parameter to use a system group name.\n", file, linenum, args[1]);
Baptiste Assmann776e5182016-03-11 17:21:15 +01001120 err_code |= ERR_WARN;
1121 goto out;
1122 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001123 }
Simon Horman98637e52014-06-20 12:30:16 +09001124 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001125 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1126 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001127 global.external_check = 1;
1128 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001129 /* user/group name handling */
1130 else if (!strcmp(args[0], "user")) {
1131 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001132 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1133 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001134 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001135 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001136 err_code |= ERR_ALERT;
1137 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001138 }
1139 errno = 0;
1140 ha_user = getpwnam(args[1]);
1141 if (ha_user != NULL) {
1142 global.uid = (int)ha_user->pw_uid;
1143 }
1144 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001145 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001146 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001147 }
1148 }
1149 else if (!strcmp(args[0], "group")) {
1150 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001151 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1152 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001153 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001154 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001155 err_code |= ERR_ALERT;
1156 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001157 }
1158 errno = 0;
1159 ha_group = getgrnam(args[1]);
1160 if (ha_group != NULL) {
1161 global.gid = (int)ha_group->gr_gid;
1162 }
1163 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001164 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001165 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001166 }
1167 }
1168 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001169 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001170 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1171 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001172 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001173 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001174 err_code |= ERR_ALERT | ERR_FATAL;
1175 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001176 }
1177 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001178 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1180 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001181 err_code |= ERR_ALERT | ERR_FATAL;
1182 goto out;
1183 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001184 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001185 else if (!strcmp(args[0], "nbthread")) {
1186 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1187 goto out;
1188 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001189 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001190 err_code |= ERR_ALERT | ERR_FATAL;
1191 goto out;
1192 }
1193 global.nbthread = atol(args[1]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001194#ifndef USE_THREAD
1195 if (global.nbthread > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001196 ha_alert("HAProxy is not compiled with threads support, please check build options for USE_THREAD.\n");
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001197 global.nbthread = 1;
1198 err_code |= ERR_ALERT | ERR_FATAL;
1199 goto out;
1200 }
1201#endif
Willy Tarreau421f02e2018-01-20 18:19:22 +01001202 if (global.nbthread < 1 || global.nbthread > MAX_THREADS) {
1203 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1204 file, linenum, args[0], MAX_THREADS, global.nbthread);
1205 err_code |= ERR_ALERT | ERR_FATAL;
1206 goto out;
1207 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001208 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001209 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001210 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1211 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001212 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001213 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001214 err_code |= ERR_ALERT;
1215 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001216 }
1217 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001218 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001219 err_code |= ERR_ALERT | ERR_FATAL;
1220 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001221 }
1222 global.maxconn = atol(args[1]);
1223#ifdef SYSTEM_MAXCONN
1224 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001225 ha_alert("parsing [%s:%d] : maxconn value %d too high for this system.\nLimiting to %d. Please use '-n' to force the value.\n", file, linenum, global.maxconn, DEFAULT_MAXCONN);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001226 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001227 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001228 }
1229#endif /* SYSTEM_MAXCONN */
1230 }
Emeric Brun850efd52014-01-29 12:24:34 +01001231 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001232 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1233 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001234 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001235 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001236 err_code |= ERR_ALERT | ERR_FATAL;
1237 goto out;
1238 }
1239 if (strcmp(args[1],"none") == 0)
1240 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1241 else if (strcmp(args[1],"required") == 0)
1242 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1243 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001244 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001245 err_code |= ERR_ALERT | ERR_FATAL;
1246 goto out;
1247 }
1248 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001249 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001250 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1251 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001252 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001253 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001254 err_code |= ERR_ALERT;
1255 goto out;
1256 }
1257 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001258 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001259 err_code |= ERR_ALERT | ERR_FATAL;
1260 goto out;
1261 }
1262 global.cps_lim = atol(args[1]);
1263 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001264 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001265 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1266 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001267 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001268 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001269 err_code |= ERR_ALERT;
1270 goto out;
1271 }
1272 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001273 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001274 err_code |= ERR_ALERT | ERR_FATAL;
1275 goto out;
1276 }
1277 global.sps_lim = atol(args[1]);
1278 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001279 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001280 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1281 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001282 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001283 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001284 err_code |= ERR_ALERT;
1285 goto out;
1286 }
1287 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001288 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001289 err_code |= ERR_ALERT | ERR_FATAL;
1290 goto out;
1291 }
1292 global.ssl_lim = atol(args[1]);
1293 }
William Lallemandd85f9172012-11-09 17:05:39 +01001294 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001295 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1296 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001297 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001298 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
William Lallemandd85f9172012-11-09 17:05:39 +01001299 err_code |= ERR_ALERT | ERR_FATAL;
1300 goto out;
1301 }
1302 global.comp_rate_lim = atoi(args[1]) * 1024;
1303 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001304 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001305 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1306 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001307 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001308 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001309 err_code |= ERR_ALERT;
1310 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001311 }
1312 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001313 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001314 err_code |= ERR_ALERT | ERR_FATAL;
1315 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001316 }
1317 global.maxpipes = atol(args[1]);
1318 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001319 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001320 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1321 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001322 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001323 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001324 err_code |= ERR_ALERT | ERR_FATAL;
1325 goto out;
1326 }
William Lallemande3a7d992012-11-20 11:25:20 +01001327 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001328 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001329 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001330 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1331 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001332 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001333 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
William Lallemand072a2bf2012-11-20 17:01:01 +01001334 err_code |= ERR_ALERT | ERR_FATAL;
1335 goto out;
1336 }
1337 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001338 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001339 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
William Lallemand072a2bf2012-11-20 17:01:01 +01001340 err_code |= ERR_ALERT | ERR_FATAL;
1341 goto out;
1342 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001343 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001344
Willy Tarreaubaaee002006-06-26 02:48:02 +02001345 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001346 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1347 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001348 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001349 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001350 err_code |= ERR_ALERT;
1351 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001352 }
1353 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001354 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001355 err_code |= ERR_ALERT | ERR_FATAL;
1356 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001357 }
1358 global.rlimit_nofile = atol(args[1]);
1359 }
1360 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001361 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1362 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001363 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001364 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001365 err_code |= ERR_ALERT;
1366 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001367 }
1368 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001369 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001370 err_code |= ERR_ALERT | ERR_FATAL;
1371 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001372 }
1373 global.chroot = strdup(args[1]);
1374 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001375 else if (!strcmp(args[0], "description")) {
1376 int i, len=0;
1377 char *d;
1378
1379 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001380 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1381 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001382 err_code |= ERR_ALERT | ERR_FATAL;
1383 goto out;
1384 }
1385
Willy Tarreau348acfe2014-04-14 15:00:39 +02001386 for (i = 1; *args[i]; i++)
1387 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001388
1389 if (global.desc)
1390 free(global.desc);
1391
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001392 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001393
Willy Tarreau348acfe2014-04-14 15:00:39 +02001394 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1395 for (i = 2; *args[i]; i++)
1396 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001397 }
1398 else if (!strcmp(args[0], "node")) {
1399 int i;
1400 char c;
1401
William Lallemand1a748ae2015-05-19 16:37:23 +02001402 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1403 goto out;
1404
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001405 for (i=0; args[1][i]; i++) {
1406 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001407 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1408 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001409 break;
1410 }
1411
1412 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001413 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1414 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1415 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001416 err_code |= ERR_ALERT | ERR_FATAL;
1417 goto out;
1418 }
1419
1420 if (global.node)
1421 free(global.node);
1422
1423 global.node = strdup(args[1]);
1424 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001425 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001426 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1427 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001428 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001429 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001430 err_code |= ERR_ALERT;
1431 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001432 }
1433 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001434 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001435 err_code |= ERR_ALERT | ERR_FATAL;
1436 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001437 }
1438 global.pidfile = strdup(args[1]);
1439 }
Emeric Bruned760922010-10-22 17:59:25 +02001440 else if (!strcmp(args[0], "unix-bind")) {
1441 int cur_arg = 1;
1442 while (*(args[cur_arg])) {
1443 if (!strcmp(args[cur_arg], "prefix")) {
1444 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001445 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001446 err_code |= ERR_ALERT;
1447 cur_arg += 2;
1448 continue;
1449 }
1450
1451 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001452 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001453 err_code |= ERR_ALERT | ERR_FATAL;
1454 goto out;
1455 }
1456 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1457 cur_arg += 2;
1458 continue;
1459 }
1460
1461 if (!strcmp(args[cur_arg], "mode")) {
1462
1463 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1464 cur_arg += 2;
1465 continue;
1466 }
1467
1468 if (!strcmp(args[cur_arg], "uid")) {
1469
1470 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1471 cur_arg += 2;
1472 continue;
1473 }
1474
1475 if (!strcmp(args[cur_arg], "gid")) {
1476
1477 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1478 cur_arg += 2;
1479 continue;
1480 }
1481
1482 if (!strcmp(args[cur_arg], "user")) {
1483 struct passwd *user;
1484
1485 user = getpwnam(args[cur_arg + 1]);
1486 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001487 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1488 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001489 err_code |= ERR_ALERT | ERR_FATAL;
1490 goto out;
1491 }
1492
1493 global.unix_bind.ux.uid = user->pw_uid;
1494 cur_arg += 2;
1495 continue;
1496 }
1497
1498 if (!strcmp(args[cur_arg], "group")) {
1499 struct group *group;
1500
1501 group = getgrnam(args[cur_arg + 1]);
1502 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001503 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1504 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001505 err_code |= ERR_ALERT | ERR_FATAL;
1506 goto out;
1507 }
1508
1509 global.unix_bind.ux.gid = group->gr_gid;
1510 cur_arg += 2;
1511 continue;
1512 }
1513
Christopher Faulet767a84b2017-11-24 16:50:31 +01001514 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1515 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001516 err_code |= ERR_ALERT | ERR_FATAL;
1517 goto out;
1518 }
1519 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001520 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1521 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1522 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001523 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001524 goto out;
1525 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001526 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001527 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1528 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001529
1530 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001531 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001532 err_code |= ERR_ALERT;
1533 goto out;
1534 }
1535
1536 if (*(args[1]))
1537 name = args[1];
1538 else
1539 name = hostname;
1540
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001541 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001542 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001543 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001544 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1545 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001546 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001547 err_code |= ERR_ALERT;
1548 goto out;
1549 }
1550
1551 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001552 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001553 err_code |= ERR_FATAL;
1554 goto out;
1555 }
1556
1557 global.server_state_base = strdup(args[1]);
1558 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001559 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1560 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001561 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001562 err_code |= ERR_ALERT;
1563 goto out;
1564 }
1565
1566 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001567 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001568 err_code |= ERR_FATAL;
1569 goto out;
1570 }
1571
1572 global.server_state_file = strdup(args[1]);
1573 }
Kevinm48936af2010-12-22 16:08:21 +00001574 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001575 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1576 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001577 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001578 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001579 err_code |= ERR_ALERT | ERR_FATAL;
1580 goto out;
1581 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001582 chunk_destroy(&global.log_tag);
1583 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001584 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001585 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001586 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1587 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001588 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001589 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001590 err_code |= ERR_ALERT;
1591 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001592 }
1593 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001594 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001595 err_code |= ERR_ALERT | ERR_FATAL;
1596 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001597 }
1598 global.spread_checks = atol(args[1]);
1599 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001600 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001601 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001602 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001603 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001604 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1605 const char *err;
1606 unsigned int val;
1607
William Lallemand1a748ae2015-05-19 16:37:23 +02001608 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1609 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001610 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001611 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001612 err_code |= ERR_ALERT | ERR_FATAL;
1613 goto out;
1614 }
1615
1616 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1617 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001618 ha_alert("parsing [%s:%d]: unsupported character '%c' in '%s' (wants an integer delay).\n", file, linenum, *err, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001619 err_code |= ERR_ALERT | ERR_FATAL;
1620 }
1621 global.max_spread_checks = val;
1622 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001623 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001624 err_code |= ERR_ALERT | ERR_FATAL;
1625 }
1626 }
Christopher Faulet62519022017-10-16 15:49:32 +02001627 else if (strcmp(args[0], "cpu-map") == 0) {
1628 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001629#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001630 char *slash;
1631 unsigned long proc = 0, thread = 0, cpus;
1632 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001633
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001634 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001635 ha_alert("parsing [%s:%d] : %s expects a process number "
1636 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1637 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1638 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001639 err_code |= ERR_ALERT | ERR_FATAL;
1640 goto out;
1641 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001642
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001643 if ((slash = strchr(args[1], '/')) != NULL)
1644 *slash = 0;
1645
Christopher Faulet26028f62017-11-22 15:01:51 +01001646 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001647 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001648 err_code |= ERR_ALERT | ERR_FATAL;
1649 goto out;
1650 }
1651
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001652 if (slash) {
1653 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001654 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001655 err_code |= ERR_ALERT | ERR_FATAL;
1656 goto out;
1657 }
1658 *slash = '/';
1659
1660 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001661 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1662 "a process range _AND_ a thread range\n",
1663 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001664 err_code |= ERR_ALERT | ERR_FATAL;
1665 goto out;
1666 }
1667 }
1668
Christopher Faulet62519022017-10-16 15:49:32 +02001669 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001670 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001671 err_code |= ERR_ALERT | ERR_FATAL;
1672 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001673 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001674
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001675 if (autoinc &&
1676 my_popcountl(proc) != my_popcountl(cpus) &&
1677 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001678 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1679 "must have the same size to be automatically bound\n",
1680 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001681 err_code |= ERR_ALERT | ERR_FATAL;
1682 goto out;
1683 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001684
Christopher Faulet26028f62017-11-22 15:01:51 +01001685 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001686 /* No mapping for this process */
1687 if (!(proc & (1UL << i)))
1688 continue;
1689
1690 /* Mapping at the process level */
1691 if (!thread) {
1692 if (!autoinc)
1693 global.cpu_map.proc[i] = cpus;
1694 else {
1695 n += my_ffsl(cpus >> n);
1696 global.cpu_map.proc[i] = (1UL << (n-1));
1697 }
1698 continue;
1699 }
1700
1701 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001702 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001703 /* Np mapping for this thread */
1704 if (!(thread & (1UL << j)))
1705 continue;
1706
1707 if (!autoinc)
1708 global.cpu_map.thread[i][j] = cpus;
1709 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001710 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001711 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001712 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001713 }
1714 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001715#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001716 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1717 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001718 err_code |= ERR_ALERT | ERR_FATAL;
1719 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001720#endif /* ! USE_CPU_AFFINITY */
1721 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001722 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1723 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1724 goto out;
1725
1726 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001727 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001728 err_code |= ERR_ALERT | ERR_FATAL;
1729 goto out;
1730 }
1731
1732 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1733 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001734 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
Willy Tarreau1d549722016-02-16 12:41:57 +01001735 err_code |= ERR_ALERT | ERR_FATAL;
1736 goto out;
1737 }
1738 }
1739 else if (!strcmp(args[0], "unsetenv")) {
1740 int arg;
1741
1742 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001743 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001744 err_code |= ERR_ALERT | ERR_FATAL;
1745 goto out;
1746 }
1747
1748 for (arg = 1; *args[arg]; arg++) {
1749 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001750 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
Willy Tarreau1d549722016-02-16 12:41:57 +01001751 err_code |= ERR_ALERT | ERR_FATAL;
1752 goto out;
1753 }
1754 }
1755 }
1756 else if (!strcmp(args[0], "resetenv")) {
1757 extern char **environ;
1758 char **env = environ;
1759
1760 /* args contain variable names to keep, one per argument */
1761 while (*env) {
1762 int arg;
1763
1764 /* look for current variable in among all those we want to keep */
1765 for (arg = 1; *args[arg]; arg++) {
1766 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1767 (*env)[strlen(args[arg])] == '=')
1768 break;
1769 }
1770
1771 /* delete this variable */
1772 if (!*args[arg]) {
1773 char *delim = strchr(*env, '=');
1774
1775 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001776 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
Willy Tarreau1d549722016-02-16 12:41:57 +01001777 err_code |= ERR_ALERT | ERR_FATAL;
1778 goto out;
1779 }
1780
1781 memcpy(trash.str, *env, delim - *env);
1782 trash.str[delim - *env] = 0;
1783
1784 if (unsetenv(trash.str) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001785 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
Willy Tarreau1d549722016-02-16 12:41:57 +01001786 err_code |= ERR_ALERT | ERR_FATAL;
1787 goto out;
1788 }
1789 }
1790 else
1791 env++;
1792 }
1793 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001794 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001795 struct cfg_kw_list *kwl;
1796 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001797 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001798
1799 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1800 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1801 if (kwl->kw[index].section != CFG_GLOBAL)
1802 continue;
1803 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001804 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001805 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001806 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001807 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001808 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001809 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001810 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001811 err_code |= ERR_WARN;
1812 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001813 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001814 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001815 }
1816 }
1817 }
1818
Christopher Faulet767a84b2017-11-24 16:50:31 +01001819 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001820 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001821 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001822
Willy Tarreau058e9072009-07-20 09:30:05 +02001823 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001824 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001825 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001826}
1827
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001828void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001829{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001830 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001831 defproxy.mode = PR_MODE_TCP;
1832 defproxy.state = PR_STNEW;
1833 defproxy.maxconn = cfg_maxpconn;
1834 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001835 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001836 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001837
Simon Horman66183002013-02-23 10:16:43 +09001838 defproxy.defsrv.check.inter = DEF_CHKINTR;
1839 defproxy.defsrv.check.fastinter = 0;
1840 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001841 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1842 defproxy.defsrv.agent.fastinter = 0;
1843 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001844 defproxy.defsrv.check.rise = DEF_RISETIME;
1845 defproxy.defsrv.check.fall = DEF_FALLTIME;
1846 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1847 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001848 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001849 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001850 defproxy.defsrv.maxqueue = 0;
1851 defproxy.defsrv.minconn = 0;
1852 defproxy.defsrv.maxconn = 0;
1853 defproxy.defsrv.slowstart = 0;
1854 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1855 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1856 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001857
1858 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001859 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001860}
1861
Willy Tarreauade5ec42010-01-28 19:33:49 +01001862
Willy Tarreau63af98d2014-05-18 08:11:41 +02001863/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1864 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1865 * ERR_FATAL in case of error.
1866 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001867static int create_cond_regex_rule(const char *file, int line,
1868 struct proxy *px, int dir, int action, int flags,
1869 const char *cmd, const char *reg, const char *repl,
1870 const char **cond_start)
1871{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001872 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001873 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001874 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001875 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001876 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001877 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001878 int cs;
1879 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001880
1881 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001882 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001883 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001884 goto err;
1885 }
1886
1887 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001888 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001889 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001890 goto err;
1891 }
1892
Christopher Faulet898566e2016-10-26 11:06:28 +02001893 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001894 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001895
Willy Tarreau5321c422010-01-28 20:35:13 +01001896 if (cond_start &&
1897 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001898 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001899 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1900 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001901 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001902 goto err;
1903 }
1904 }
1905 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001906 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1907 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001908 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001909 goto err;
1910 }
1911
Willy Tarreau63af98d2014-05-18 08:11:41 +02001912 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001913 (dir == SMP_OPT_DIR_REQ) ?
1914 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1915 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1916 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001917
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001918 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001919 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001920 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001921 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001922 goto err;
1923 }
1924
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001925 cs = !(flags & REG_ICASE);
1926 cap = !(flags & REG_NOSUB);
1927 error = NULL;
1928 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001929 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001930 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001931 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001932 goto err;
1933 }
1934
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001935 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001936 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001937 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001938 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1939 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001940 ret_code |= ERR_ALERT | ERR_FATAL;
1941 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001942 }
1943
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001944 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001945 ret_code |= ERR_WARN;
1946
1947 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001948
Willy Tarreau63af98d2014-05-18 08:11:41 +02001949 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001950 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001951 err:
1952 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001953 free(errmsg);
1954 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001955}
1956
Willy Tarreaubaaee002006-06-26 02:48:02 +02001957/*
William Lallemand51097192015-04-14 16:35:22 +02001958 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001959 * Returns the error code, 0 if OK, or any combination of :
1960 * - ERR_ABORT: must abort ASAP
1961 * - ERR_FATAL: we can continue parsing but not start the service
1962 * - ERR_WARN: a warning has been emitted
1963 * - ERR_ALERT: an alert has been emitted
1964 * Only the two first ones can stop processing, the two others are just
1965 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001966 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001967int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1968{
1969 static struct peers *curpeers = NULL;
1970 struct peer *newpeer = NULL;
1971 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001972 struct bind_conf *bind_conf;
1973 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001974 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001975 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001976
1977 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001978 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001979 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001980 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001981 goto out;
1982 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001983
William Lallemand6e62fb62015-04-28 16:55:23 +02001984 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1985 goto out;
1986
Emeric Brun32da3c42010-09-23 18:39:19 +02001987 err = invalid_char(args[1]);
1988 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001989 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1990 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001991 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001992 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02001993 }
1994
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02001995 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02001996 /*
1997 * If there are two proxies with the same name only following
1998 * combinations are allowed:
1999 */
2000 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002001 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2002 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002003 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002004 }
2005 }
2006
Vincent Bernat02779b62016-04-03 13:48:43 +02002007 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002008 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002009 err_code |= ERR_ALERT | ERR_ABORT;
2010 goto out;
2011 }
2012
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002013 curpeers->next = cfg_peers;
2014 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002015 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002016 curpeers->conf.line = linenum;
2017 curpeers->last_change = now.tv_sec;
2018 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002019 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002020 }
2021 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002022 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002023 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002024 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002025
2026 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002027 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2028 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002029 err_code |= ERR_ALERT | ERR_FATAL;
2030 goto out;
2031 }
2032
2033 err = invalid_char(args[1]);
2034 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002035 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2036 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002037 err_code |= ERR_ALERT | ERR_FATAL;
2038 goto out;
2039 }
2040
Vincent Bernat02779b62016-04-03 13:48:43 +02002041 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002042 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002043 err_code |= ERR_ALERT | ERR_ABORT;
2044 goto out;
2045 }
2046
2047 /* the peers are linked backwards first */
2048 curpeers->count++;
2049 newpeer->next = curpeers->remote;
2050 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002051 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002052 newpeer->conf.line = linenum;
2053
2054 newpeer->last_change = now.tv_sec;
2055 newpeer->id = strdup(args[1]);
2056
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002057 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002058 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002059 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002060 err_code |= ERR_ALERT | ERR_FATAL;
2061 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002062 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002063
2064 proto = protocol_by_family(sk->ss_family);
2065 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002066 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2067 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002068 err_code |= ERR_ALERT | ERR_FATAL;
2069 goto out;
2070 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002071
2072 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002073 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2074 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002075 err_code |= ERR_ALERT | ERR_FATAL;
2076 goto out;
2077 }
2078
Willy Tarreau2aa38802013-02-20 19:20:59 +01002079 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002080 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2081 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002082 err_code |= ERR_ALERT | ERR_FATAL;
2083 goto out;
2084 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002085
Emeric Brun32da3c42010-09-23 18:39:19 +02002086 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002087 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002088 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002089 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002090 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002091
Emeric Brun32da3c42010-09-23 18:39:19 +02002092 if (strcmp(newpeer->id, localpeer) == 0) {
2093 /* Current is local peer, it define a frontend */
2094 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002095 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002096
2097 if (!curpeers->peers_fe) {
2098 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002099 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002100 err_code |= ERR_ALERT | ERR_ABORT;
2101 goto out;
2102 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002103
Willy Tarreau237250c2011-07-29 01:49:03 +02002104 init_new_proxy(curpeers->peers_fe);
2105 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002106 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002107 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2108 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002109 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002110
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002111 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002112
Willy Tarreau902636f2013-03-10 19:44:48 +01002113 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2114 if (errmsg && *errmsg) {
2115 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002116 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002117 }
2118 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002119 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2120 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002121 err_code |= ERR_FATAL;
2122 goto out;
2123 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002124
2125 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002126 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002127 l->maxconn = curpeers->peers_fe->maxconn;
2128 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002129 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002130 l->analysers |= curpeers->peers_fe->fe_req_ana;
2131 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002132 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2133 global.maxsock += l->maxconn;
2134 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002135 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002136 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002137 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2138 file, linenum, args[0], args[1],
2139 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002140 err_code |= ERR_FATAL;
2141 goto out;
2142 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002143 }
2144 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002145 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2146 curpeers->state = PR_STSTOPPED;
2147 }
2148 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2149 curpeers->state = PR_STNEW;
2150 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002151 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002152 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002153 err_code |= ERR_ALERT | ERR_FATAL;
2154 goto out;
2155 }
2156
2157out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002158 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002159 return err_code;
2160}
2161
Baptiste Assmann325137d2015-04-13 23:40:55 +02002162/*
2163 * Parse a <resolvers> section.
2164 * Returns the error code, 0 if OK, or any combination of :
2165 * - ERR_ABORT: must abort ASAP
2166 * - ERR_FATAL: we can continue parsing but not start the service
2167 * - ERR_WARN: a warning has been emitted
2168 * - ERR_ALERT: an alert has been emitted
2169 * Only the two first ones can stop processing, the two others are just
2170 * indicators.
2171 */
2172int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2173{
2174 static struct dns_resolvers *curr_resolvers = NULL;
2175 struct dns_nameserver *newnameserver = NULL;
2176 const char *err;
2177 int err_code = 0;
2178 char *errmsg = NULL;
2179
2180 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2181 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002182 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002183 err_code |= ERR_ALERT | ERR_ABORT;
2184 goto out;
2185 }
2186
2187 err = invalid_char(args[1]);
2188 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002189 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2190 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002191 err_code |= ERR_ALERT | ERR_ABORT;
2192 goto out;
2193 }
2194
2195 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2196 /* Error if two resolvers owns the same name */
2197 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002198 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2199 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002200 err_code |= ERR_ALERT | ERR_ABORT;
2201 }
2202 }
2203
Vincent Bernat02779b62016-04-03 13:48:43 +02002204 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002205 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002206 err_code |= ERR_ALERT | ERR_ABORT;
2207 goto out;
2208 }
2209
2210 /* default values */
2211 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2212 curr_resolvers->conf.file = strdup(file);
2213 curr_resolvers->conf.line = linenum;
2214 curr_resolvers->id = strdup(args[1]);
2215 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002216 /* default maximum response size */
2217 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002218 /* default hold period for nx, other, refuse and timeout is 30s */
2219 curr_resolvers->hold.nx = 30000;
2220 curr_resolvers->hold.other = 30000;
2221 curr_resolvers->hold.refused = 30000;
2222 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002223 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002224 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002225 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002226 curr_resolvers->timeout.resolve = 1000;
2227 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002228 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002229 curr_resolvers->nb_nameservers = 0;
2230 LIST_INIT(&curr_resolvers->nameservers);
2231 LIST_INIT(&curr_resolvers->resolutions.curr);
2232 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002233 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002234 }
2235 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2236 struct sockaddr_storage *sk;
2237 int port1, port2;
2238 struct protocol *proto;
2239
2240 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002241 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2242 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002243 err_code |= ERR_ALERT | ERR_FATAL;
2244 goto out;
2245 }
2246
2247 err = invalid_char(args[1]);
2248 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002249 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2250 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002251 err_code |= ERR_ALERT | ERR_FATAL;
2252 goto out;
2253 }
2254
Christopher Faulet67957bd2017-09-27 11:00:59 +02002255 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002256 /* Error if two resolvers owns the same name */
2257 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002258 ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
2259 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002260 err_code |= ERR_ALERT | ERR_FATAL;
2261 }
2262 }
2263
Vincent Bernat02779b62016-04-03 13:48:43 +02002264 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002265 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002266 err_code |= ERR_ALERT | ERR_ABORT;
2267 goto out;
2268 }
2269
2270 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002271 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002272 newnameserver->resolvers = curr_resolvers;
2273 newnameserver->conf.file = strdup(file);
2274 newnameserver->conf.line = linenum;
2275 newnameserver->id = strdup(args[1]);
2276
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002277 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002278 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002279 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002280 err_code |= ERR_ALERT | ERR_FATAL;
2281 goto out;
2282 }
2283
2284 proto = protocol_by_family(sk->ss_family);
2285 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002286 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002287 file, linenum, args[0], args[1]);
2288 err_code |= ERR_ALERT | ERR_FATAL;
2289 goto out;
2290 }
2291
2292 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002293 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2294 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002295 err_code |= ERR_ALERT | ERR_FATAL;
2296 goto out;
2297 }
2298
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002299 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002300 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2301 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002302 err_code |= ERR_ALERT | ERR_FATAL;
2303 goto out;
2304 }
2305
Baptiste Assmann325137d2015-04-13 23:40:55 +02002306 newnameserver->addr = *sk;
2307 }
2308 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2309 const char *res;
2310 unsigned int time;
2311
2312 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002313 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2314 file, linenum, args[0]);
2315 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002316 err_code |= ERR_ALERT | ERR_FATAL;
2317 goto out;
2318 }
2319 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2320 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002321 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2322 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002323 err_code |= ERR_ALERT | ERR_FATAL;
2324 goto out;
2325 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002326 if (strcmp(args[1], "nx") == 0)
2327 curr_resolvers->hold.nx = time;
2328 else if (strcmp(args[1], "other") == 0)
2329 curr_resolvers->hold.other = time;
2330 else if (strcmp(args[1], "refused") == 0)
2331 curr_resolvers->hold.refused = time;
2332 else if (strcmp(args[1], "timeout") == 0)
2333 curr_resolvers->hold.timeout = time;
2334 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002335 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002336 else if (strcmp(args[1], "obsolete") == 0)
2337 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002338 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002339 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2340 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002341 err_code |= ERR_ALERT | ERR_FATAL;
2342 goto out;
2343 }
2344
2345 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002346 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002347 int i = 0;
2348
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002349 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002350 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2351 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002352 err_code |= ERR_ALERT | ERR_FATAL;
2353 goto out;
2354 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002355
2356 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002357 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002358 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2359 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002360 err_code |= ERR_ALERT | ERR_FATAL;
2361 goto out;
2362 }
2363
2364 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002365 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002366 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002367 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2368 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002369 err_code |= ERR_WARN;
2370 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002371 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002372 else if (strcmp(args[0], "resolve_retries") == 0) {
2373 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002374 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2375 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002376 err_code |= ERR_ALERT | ERR_FATAL;
2377 goto out;
2378 }
2379 curr_resolvers->resolve_retries = atoi(args[1]);
2380 }
2381 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002382 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002383 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2384 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002385 err_code |= ERR_ALERT | ERR_FATAL;
2386 goto out;
2387 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002388 else if (strcmp(args[1], "retry") == 0 ||
2389 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002390 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002391 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002392
2393 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002394 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2395 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002396 err_code |= ERR_ALERT | ERR_FATAL;
2397 goto out;
2398 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002399 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002400 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002401 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2402 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002403 err_code |= ERR_ALERT | ERR_FATAL;
2404 goto out;
2405 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002406 if (args[1][2] == 't')
2407 curr_resolvers->timeout.retry = tout;
2408 else
2409 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002410 }
2411 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002412 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2413 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002414 err_code |= ERR_ALERT | ERR_FATAL;
2415 goto out;
2416 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002417 } /* neither "nameserver" nor "resolvers" */
2418 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002419 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002420 err_code |= ERR_ALERT | ERR_FATAL;
2421 goto out;
2422 }
2423
2424 out:
2425 free(errmsg);
2426 return err_code;
2427}
Simon Horman0d16a402015-01-30 11:22:58 +09002428
2429/*
William Lallemand51097192015-04-14 16:35:22 +02002430 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002431 * Returns the error code, 0 if OK, or any combination of :
2432 * - ERR_ABORT: must abort ASAP
2433 * - ERR_FATAL: we can continue parsing but not start the service
2434 * - ERR_WARN: a warning has been emitted
2435 * - ERR_ALERT: an alert has been emitted
2436 * Only the two first ones can stop processing, the two others are just
2437 * indicators.
2438 */
2439int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2440{
2441 static struct mailers *curmailers = NULL;
2442 struct mailer *newmailer = NULL;
2443 const char *err;
2444 int err_code = 0;
2445 char *errmsg = NULL;
2446
2447 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2448 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002449 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002450 err_code |= ERR_ALERT | ERR_ABORT;
2451 goto out;
2452 }
2453
2454 err = invalid_char(args[1]);
2455 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002456 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2457 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002458 err_code |= ERR_ALERT | ERR_ABORT;
2459 goto out;
2460 }
2461
2462 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2463 /*
2464 * If there are two proxies with the same name only following
2465 * combinations are allowed:
2466 */
2467 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002468 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2469 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002470 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002471 }
2472 }
2473
Vincent Bernat02779b62016-04-03 13:48:43 +02002474 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002475 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002476 err_code |= ERR_ALERT | ERR_ABORT;
2477 goto out;
2478 }
2479
2480 curmailers->next = mailers;
2481 mailers = curmailers;
2482 curmailers->conf.file = strdup(file);
2483 curmailers->conf.line = linenum;
2484 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002485 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2486 * But need enough time so that timeouts don't occur
2487 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002488 }
2489 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2490 struct sockaddr_storage *sk;
2491 int port1, port2;
2492 struct protocol *proto;
2493
2494 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002495 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2496 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002497 err_code |= ERR_ALERT | ERR_FATAL;
2498 goto out;
2499 }
2500
2501 err = invalid_char(args[1]);
2502 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002503 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2504 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002505 err_code |= ERR_ALERT | ERR_FATAL;
2506 goto out;
2507 }
2508
Vincent Bernat02779b62016-04-03 13:48:43 +02002509 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002510 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002511 err_code |= ERR_ALERT | ERR_ABORT;
2512 goto out;
2513 }
2514
2515 /* the mailers are linked backwards first */
2516 curmailers->count++;
2517 newmailer->next = curmailers->mailer_list;
2518 curmailers->mailer_list = newmailer;
2519 newmailer->mailers = curmailers;
2520 newmailer->conf.file = strdup(file);
2521 newmailer->conf.line = linenum;
2522
2523 newmailer->id = strdup(args[1]);
2524
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002525 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002526 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002527 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002528 err_code |= ERR_ALERT | ERR_FATAL;
2529 goto out;
2530 }
2531
2532 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002533 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002534 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2535 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002536 err_code |= ERR_ALERT | ERR_FATAL;
2537 goto out;
2538 }
2539
2540 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002541 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2542 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002543 err_code |= ERR_ALERT | ERR_FATAL;
2544 goto out;
2545 }
2546
2547 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002548 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2549 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002550 err_code |= ERR_ALERT | ERR_FATAL;
2551 goto out;
2552 }
2553
2554 newmailer->addr = *sk;
2555 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002556 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002557 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002558 }
2559 else if (strcmp(args[0], "timeout") == 0) {
2560 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002561 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2562 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002563 err_code |= ERR_ALERT | ERR_FATAL;
2564 goto out;
2565 }
2566 else if (strcmp(args[1], "mail") == 0) {
2567 const char *res;
2568 unsigned int timeout_mail;
2569 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002570 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2571 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002572 err_code |= ERR_ALERT | ERR_FATAL;
2573 goto out;
2574 }
2575 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2576 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002577 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2578 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002579 err_code |= ERR_ALERT | ERR_FATAL;
2580 goto out;
2581 }
2582 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002583 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 +01002584 err_code |= ERR_ALERT | ERR_FATAL;
2585 goto out;
2586 }
2587 curmailers->timeout.mail = timeout_mail;
2588 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002589 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002590 file, linenum, args[0], args[1]);
2591 err_code |= ERR_ALERT | ERR_FATAL;
2592 goto out;
2593 }
2594 }
Simon Horman0d16a402015-01-30 11:22:58 +09002595 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002596 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002597 err_code |= ERR_ALERT | ERR_FATAL;
2598 goto out;
2599 }
2600
2601out:
2602 free(errmsg);
2603 return err_code;
2604}
2605
Simon Horman9dc49962015-01-30 11:22:59 +09002606static void free_email_alert(struct proxy *p)
2607{
2608 free(p->email_alert.mailers.name);
2609 p->email_alert.mailers.name = NULL;
2610 free(p->email_alert.from);
2611 p->email_alert.from = NULL;
2612 free(p->email_alert.to);
2613 p->email_alert.to = NULL;
2614 free(p->email_alert.myhostname);
2615 p->email_alert.myhostname = NULL;
2616}
2617
Willy Tarreau3842f002009-06-14 11:39:52 +02002618int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002619{
2620 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002621 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002622 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002623 int rc;
2624 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002625 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002626 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002627 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002628 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002629 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002630
Willy Tarreau977b8e42006-12-29 14:19:17 +01002631 if (!strcmp(args[0], "listen"))
2632 rc = PR_CAP_LISTEN;
2633 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002634 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002635 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002636 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002637 else
2638 rc = PR_CAP_NONE;
2639
2640 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002641 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002642 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2643 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2644 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002645 err_code |= ERR_ALERT | ERR_ABORT;
2646 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002647 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002648
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002649 err = invalid_char(args[1]);
2650 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002651 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2652 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002653 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002654 }
2655
Willy Tarreau8f50b682015-05-26 11:45:02 +02002656 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2657 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002658 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2659 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2660 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002661 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002662 }
2663
Vincent Bernat02779b62016-04-03 13:48:43 +02002664 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002665 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002666 err_code |= ERR_ALERT | ERR_ABORT;
2667 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002668 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002669
Willy Tarreau97cb7802010-01-03 20:23:58 +01002670 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002671 curproxy->next = proxies_list;
2672 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002673 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2674 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002675 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002676 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002677 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002678 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002679
William Lallemand6e62fb62015-04-28 16:55:23 +02002680 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2681 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002682 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002683 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002684 }
2685
2686 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002687 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002688 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002689
Willy Tarreaubaaee002006-06-26 02:48:02 +02002690 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002691 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002692 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002693 curproxy->no_options = defproxy.no_options;
2694 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002695 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002696 curproxy->except_net = defproxy.except_net;
2697 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002698 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002699 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002700
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002701 if (defproxy.fwdfor_hdr_len) {
2702 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2703 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2704 }
2705
Willy Tarreaub86db342009-11-30 11:50:16 +01002706 if (defproxy.orgto_hdr_len) {
2707 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2708 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2709 }
2710
Mark Lamourinec2247f02012-01-04 13:02:01 -05002711 if (defproxy.server_id_hdr_len) {
2712 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2713 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2714 }
2715
Willy Tarreau977b8e42006-12-29 14:19:17 +01002716 if (curproxy->cap & PR_CAP_FE) {
2717 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002718 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002719 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002720
2721 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002722 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2723 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002724
2725 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2726 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002727
Willy Tarreau977b8e42006-12-29 14:19:17 +01002728 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002729 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002730 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002731 curproxy->fullconn = defproxy.fullconn;
2732 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002733 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002734 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002735
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002736 if (defproxy.check_req) {
2737 curproxy->check_req = calloc(1, defproxy.check_len);
2738 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2739 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002740 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002741
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002742 if (defproxy.expect_str) {
2743 curproxy->expect_str = strdup(defproxy.expect_str);
2744 if (defproxy.expect_regex) {
2745 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002746 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2747 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002748 }
2749 }
2750
Willy Tarreau67402132012-05-31 20:40:20 +02002751 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002752 if (defproxy.cookie_name)
2753 curproxy->cookie_name = strdup(defproxy.cookie_name);
2754 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002755
2756 if (defproxy.dyncookie_key)
2757 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002758 if (defproxy.cookie_domain)
2759 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002760
Willy Tarreau31936852010-10-06 16:59:56 +02002761 if (defproxy.cookie_maxidle)
2762 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2763
2764 if (defproxy.cookie_maxlife)
2765 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2766
Emeric Brun647caf12009-06-30 17:57:00 +02002767 if (defproxy.rdp_cookie_name)
2768 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2769 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2770
Willy Tarreau01732802007-11-01 22:48:15 +01002771 if (defproxy.url_param_name)
2772 curproxy->url_param_name = strdup(defproxy.url_param_name);
2773 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002774
Benoitaffb4812009-03-25 13:02:10 +01002775 if (defproxy.hh_name)
2776 curproxy->hh_name = strdup(defproxy.hh_name);
2777 curproxy->hh_len = defproxy.hh_len;
2778 curproxy->hh_match_domain = defproxy.hh_match_domain;
2779
Willy Tarreauef9a3602012-12-08 22:29:20 +01002780 if (defproxy.conn_src.iface_name)
2781 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2782 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002783 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002784#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002785 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002786#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002787 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002788 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002789
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002790 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002791 if (defproxy.capture_name)
2792 curproxy->capture_name = strdup(defproxy.capture_name);
2793 curproxy->capture_namelen = defproxy.capture_namelen;
2794 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002795 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002796
Willy Tarreau977b8e42006-12-29 14:19:17 +01002797 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002798 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002799 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002800 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002801 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002802 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002803 curproxy->mon_net = defproxy.mon_net;
2804 curproxy->mon_mask = defproxy.mon_mask;
2805 if (defproxy.monitor_uri)
2806 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2807 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002808 if (defproxy.defbe.name)
2809 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002810
2811 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002812 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2813 if (curproxy->conf.logformat_string &&
2814 curproxy->conf.logformat_string != default_http_log_format &&
2815 curproxy->conf.logformat_string != default_tcp_log_format &&
2816 curproxy->conf.logformat_string != clf_http_log_format)
2817 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2818
2819 if (defproxy.conf.lfs_file) {
2820 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2821 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2822 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002823
2824 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2825 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2826 if (curproxy->conf.logformat_sd_string &&
2827 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2828 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2829
2830 if (defproxy.conf.lfsd_file) {
2831 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2832 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2833 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002834 }
2835
2836 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002837 curproxy->timeout.connect = defproxy.timeout.connect;
2838 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002839 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002840 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002841 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002842 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002843 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002844 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002845 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002846 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002847 }
2848
Willy Tarreaubaaee002006-06-26 02:48:02 +02002849 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002850 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002851
2852 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002853 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002854 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002855 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002856 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002857 LIST_INIT(&node->list);
2858 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2859 }
2860
Willy Tarreau62a61232013-04-12 18:13:46 +02002861 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2862 if (curproxy->conf.uniqueid_format_string)
2863 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2864
Dragan Dosen43885c72015-10-01 13:18:13 +02002865 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002866
Willy Tarreau62a61232013-04-12 18:13:46 +02002867 if (defproxy.conf.uif_file) {
2868 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2869 curproxy->conf.uif_line = defproxy.conf.uif_line;
2870 }
William Lallemanda73203e2012-03-12 12:48:57 +01002871
2872 /* copy default header unique id */
2873 if (defproxy.header_unique_id)
2874 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2875
William Lallemand82fe75c2012-10-23 10:25:10 +02002876 /* default compression options */
2877 if (defproxy.comp != NULL) {
2878 curproxy->comp = calloc(1, sizeof(struct comp));
2879 curproxy->comp->algos = defproxy.comp->algos;
2880 curproxy->comp->types = defproxy.comp->types;
2881 }
2882
Willy Tarreaubaaee002006-06-26 02:48:02 +02002883 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002884 curproxy->conf.used_listener_id = EB_ROOT;
2885 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002886
Simon Horman98637e52014-06-20 12:30:16 +09002887 if (defproxy.check_path)
2888 curproxy->check_path = strdup(defproxy.check_path);
2889 if (defproxy.check_command)
2890 curproxy->check_command = strdup(defproxy.check_command);
2891
Simon Horman9dc49962015-01-30 11:22:59 +09002892 if (defproxy.email_alert.mailers.name)
2893 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
2894 if (defproxy.email_alert.from)
2895 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
2896 if (defproxy.email_alert.to)
2897 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
2898 if (defproxy.email_alert.myhostname)
2899 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09002900 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01002901 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09002902
Willy Tarreau93893792009-07-23 13:19:11 +02002903 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002904 }
2905 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
2906 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002907 /* FIXME-20070101: we should do this too at the end of the
2908 * config parsing to free all default values.
2909 */
William Lallemand6e62fb62015-04-28 16:55:23 +02002910 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2911 err_code |= ERR_ABORT;
2912 goto out;
2913 }
2914
Willy Tarreaua534fea2008-08-03 12:19:50 +02002915 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09002916 free(defproxy.check_command);
2917 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02002918 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02002919 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01002920 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002921 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02002922 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01002923 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02002924 free(defproxy.capture_name);
2925 free(defproxy.monitor_uri);
2926 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01002927 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002928 free(defproxy.fwdfor_hdr_name);
2929 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01002930 free(defproxy.orgto_hdr_name);
2931 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05002932 free(defproxy.server_id_hdr_name);
2933 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002934 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02002935 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002936 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02002937 free(defproxy.expect_regex);
2938 defproxy.expect_regex = NULL;
2939 }
Willy Tarreau0f772532006-12-23 20:51:41 +01002940
Willy Tarreau62a61232013-04-12 18:13:46 +02002941 if (defproxy.conf.logformat_string != default_http_log_format &&
2942 defproxy.conf.logformat_string != default_tcp_log_format &&
2943 defproxy.conf.logformat_string != clf_http_log_format)
2944 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02002945
Willy Tarreau62a61232013-04-12 18:13:46 +02002946 free(defproxy.conf.uniqueid_format_string);
2947 free(defproxy.conf.lfs_file);
2948 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02002949 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09002950 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02002951
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002952 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
2953 free(defproxy.conf.logformat_sd_string);
2954 free(defproxy.conf.lfsd_file);
2955
Willy Tarreaua534fea2008-08-03 12:19:50 +02002956 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002957 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01002958
Willy Tarreaubaaee002006-06-26 02:48:02 +02002959 /* we cannot free uri_auth because it might already be used */
2960 init_default_instance();
2961 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002962 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2963 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002964 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02002965 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002966 }
2967 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002968 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002969 err_code |= ERR_ALERT | ERR_FATAL;
2970 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002971 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002972
2973 /* update the current file and line being parsed */
2974 curproxy->conf.args.file = curproxy->conf.file;
2975 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002976
2977 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02002978 if (!strcmp(args[0], "server") ||
2979 !strcmp(args[0], "default-server") ||
2980 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02002981 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
2982 if (err_code & ERR_FATAL)
2983 goto out;
2984 }
2985 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002986 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01002987 int cur_arg;
2988
Willy Tarreaubaaee002006-06-26 02:48:02 +02002989 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002990 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002991 err_code |= ERR_ALERT | ERR_FATAL;
2992 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002993 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002994 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002995 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002996
Willy Tarreau24709282013-03-10 21:32:12 +01002997 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002998 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
2999 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003000 err_code |= ERR_ALERT | ERR_FATAL;
3001 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003002 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003003
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003004 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003005
3006 /* use default settings for unix sockets */
3007 bind_conf->ux.uid = global.unix_bind.ux.uid;
3008 bind_conf->ux.gid = global.unix_bind.ux.gid;
3009 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003010
3011 /* NOTE: the following line might create several listeners if there
3012 * are comma-separated IPs or port ranges. So all further processing
3013 * will have to be applied to all listeners created after last_listen.
3014 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003015 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3016 if (errmsg && *errmsg) {
3017 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003018 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003019 }
3020 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003021 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3022 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003023 err_code |= ERR_ALERT | ERR_FATAL;
3024 goto out;
3025 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003026
Willy Tarreau4348fad2012-09-20 16:48:07 +02003027 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3028 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003029 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003030 }
3031
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003032 cur_arg = 2;
3033 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003034 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003035 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003036 char *err;
3037
Willy Tarreau26982662012-09-12 23:17:10 +02003038 kw = bind_find_kw(args[cur_arg]);
3039 if (kw) {
3040 char *err = NULL;
3041 int code;
3042
3043 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003044 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3045 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003046 cur_arg += 1 + kw->skip ;
3047 err_code |= ERR_ALERT | ERR_FATAL;
3048 goto out;
3049 }
3050
Willy Tarreau4348fad2012-09-20 16:48:07 +02003051 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003052 err_code |= code;
3053
3054 if (code) {
3055 if (err && *err) {
3056 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003057 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003058 }
3059 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003060 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3061 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003062 if (code & ERR_FATAL) {
3063 free(err);
3064 cur_arg += 1 + kw->skip;
3065 goto out;
3066 }
3067 }
3068 free(err);
3069 cur_arg += 1 + kw->skip;
3070 continue;
3071 }
3072
Willy Tarreau8638f482012-09-18 18:01:17 +02003073 err = NULL;
3074 if (!bind_dumped) {
3075 bind_dump_kws(&err);
3076 indent_msg(&err, 4);
3077 bind_dumped = 1;
3078 }
3079
Christopher Faulet767a84b2017-11-24 16:50:31 +01003080 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3081 file, linenum, args[0], args[1], args[cur_arg],
3082 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003083 free(err);
3084
Willy Tarreau93893792009-07-23 13:19:11 +02003085 err_code |= ERR_ALERT | ERR_FATAL;
3086 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003087 }
Willy Tarreau93893792009-07-23 13:19:11 +02003088 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003089 }
3090 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003091 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003092 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3093 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003094 err_code |= ERR_ALERT | ERR_FATAL;
3095 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003096 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003097 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003098 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003099
Willy Tarreaubaaee002006-06-26 02:48:02 +02003100 /* flush useless bits */
3101 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003102 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003103 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003104 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003105 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003106 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003107
William Lallemanddf1425a2015-04-28 20:17:49 +02003108 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3109 goto out;
3110
Willy Tarreau1c47f852006-07-09 08:22:27 +02003111 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003112 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3113 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003114 err_code |= ERR_ALERT | ERR_FATAL;
3115 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003116 }
3117
Willy Tarreaua534fea2008-08-03 12:19:50 +02003118 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003119 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003120 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003121 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003122 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3123
Willy Tarreau93893792009-07-23 13:19:11 +02003124 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003125 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003126 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003127 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3128 goto out;
3129
Willy Tarreaubaaee002006-06-26 02:48:02 +02003130 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3131 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3132 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3133 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003134 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003135 err_code |= ERR_ALERT | ERR_FATAL;
3136 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003137 }
3138 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003139 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003140 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003141
3142 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003143 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003144 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003145 err_code |= ERR_ALERT | ERR_FATAL;
3146 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003147 }
3148
William Lallemanddf1425a2015-04-28 20:17:49 +02003149 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3150 goto out;
3151
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003152 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003153 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3154 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003155 err_code |= ERR_ALERT | ERR_FATAL;
3156 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003157 }
3158
3159 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003160 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003161 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003162
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003163 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003164 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3165 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003166 err_code |= ERR_ALERT | ERR_FATAL;
3167 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003168 }
3169
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003170 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3171 if (node) {
3172 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003173 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3174 file, linenum, proxy_type_str(curproxy), curproxy->id,
3175 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003176 err_code |= ERR_ALERT | ERR_FATAL;
3177 goto out;
3178 }
3179 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003180 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003181 else if (!strcmp(args[0], "description")) {
3182 int i, len=0;
3183 char *d;
3184
Cyril Bonté99ed3272010-01-24 23:29:44 +01003185 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003186 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003187 file, linenum, args[0]);
3188 err_code |= ERR_ALERT | ERR_FATAL;
3189 goto out;
3190 }
3191
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003192 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003193 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3194 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003195 return -1;
3196 }
3197
Willy Tarreau348acfe2014-04-14 15:00:39 +02003198 for (i = 1; *args[i]; i++)
3199 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003200
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003201 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003202 curproxy->desc = d;
3203
Willy Tarreau348acfe2014-04-14 15:00:39 +02003204 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3205 for (i = 2; *args[i]; i++)
3206 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003207
3208 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003209 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003210 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3211 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003212 curproxy->state = PR_STSTOPPED;
3213 }
3214 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003215 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3216 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003217 curproxy->state = PR_STNEW;
3218 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003219 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3220 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003221 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003222
3223 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003224 if (strcmp(args[cur_arg], "all") == 0) {
3225 set = 0;
3226 break;
3227 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003228 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003229 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003230 err_code |= ERR_ALERT | ERR_FATAL;
3231 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003232 }
3233 cur_arg++;
3234 }
3235 curproxy->bind_proc = set;
3236 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003237 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003238 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003239 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003240 err_code |= ERR_ALERT | ERR_FATAL;
3241 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003242 }
3243
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003244 err = invalid_char(args[1]);
3245 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003246 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3247 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003248 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003249 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003250 }
3251
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003252 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003253 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3254 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003255 err_code |= ERR_ALERT | ERR_FATAL;
3256 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003257 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003258 }
3259 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3260
3261 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3262 err_code |= ERR_WARN;
3263
3264 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003265 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3266 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003267 err_code |= ERR_ALERT | ERR_FATAL;
3268 goto out;
3269 }
3270 free(curproxy->dyncookie_key);
3271 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003272 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003273 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3274 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003275
Willy Tarreau977b8e42006-12-29 14:19:17 +01003276 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003277 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003278
Willy Tarreaubaaee002006-06-26 02:48:02 +02003279 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003280 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3281 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003282 err_code |= ERR_ALERT | ERR_FATAL;
3283 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003284 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003285
Willy Tarreau67402132012-05-31 20:40:20 +02003286 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003287 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003288 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003289 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003290 curproxy->cookie_name = strdup(args[1]);
3291 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003292
Willy Tarreaubaaee002006-06-26 02:48:02 +02003293 cur_arg = 2;
3294 while (*(args[cur_arg])) {
3295 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003296 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003297 }
3298 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003299 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003300 }
3301 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003302 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003303 }
3304 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003305 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003306 }
3307 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003308 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003309 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003310 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003311 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003312 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003313 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003314 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003315 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003316 else if (!strcmp(args[cur_arg], "httponly")) {
3317 curproxy->ck_opts |= PR_CK_HTTPONLY;
3318 }
3319 else if (!strcmp(args[cur_arg], "secure")) {
3320 curproxy->ck_opts |= PR_CK_SECURE;
3321 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003322 else if (!strcmp(args[cur_arg], "domain")) {
3323 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003324 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3325 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003326 err_code |= ERR_ALERT | ERR_FATAL;
3327 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003328 }
3329
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003330 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003331 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003332 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3333 " dots nor does not start with a dot."
3334 " RFC forbids it, this configuration may not work properly.\n",
3335 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003336 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003337 }
3338
3339 err = invalid_domainchar(args[cur_arg + 1]);
3340 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003341 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3342 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003343 err_code |= ERR_ALERT | ERR_FATAL;
3344 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003345 }
3346
Willy Tarreau68a897b2009-12-03 23:28:34 +01003347 if (!curproxy->cookie_domain) {
3348 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3349 } else {
3350 /* one domain was already specified, add another one by
3351 * building the string which will be returned along with
3352 * the cookie.
3353 */
3354 char *new_ptr;
3355 int new_len = strlen(curproxy->cookie_domain) +
3356 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3357 new_ptr = malloc(new_len);
3358 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3359 free(curproxy->cookie_domain);
3360 curproxy->cookie_domain = new_ptr;
3361 }
Willy Tarreau31936852010-10-06 16:59:56 +02003362 cur_arg++;
3363 }
3364 else if (!strcmp(args[cur_arg], "maxidle")) {
3365 unsigned int maxidle;
3366 const char *res;
3367
3368 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003369 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3370 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003371 err_code |= ERR_ALERT | ERR_FATAL;
3372 goto out;
3373 }
3374
3375 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3376 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003377 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3378 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003379 err_code |= ERR_ALERT | ERR_FATAL;
3380 goto out;
3381 }
3382 curproxy->cookie_maxidle = maxidle;
3383 cur_arg++;
3384 }
3385 else if (!strcmp(args[cur_arg], "maxlife")) {
3386 unsigned int maxlife;
3387 const char *res;
3388
3389 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003390 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3391 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003392 err_code |= ERR_ALERT | ERR_FATAL;
3393 goto out;
3394 }
3395
3396 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3397 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003398 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3399 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003400 err_code |= ERR_ALERT | ERR_FATAL;
3401 goto out;
3402 }
3403 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003404 cur_arg++;
3405 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003406 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003407
3408 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3409 err_code |= ERR_WARN;
3410 curproxy->ck_opts |= PR_CK_DYNAMIC;
3411 }
3412
Willy Tarreaubaaee002006-06-26 02:48:02 +02003413 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003414 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3415 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003416 err_code |= ERR_ALERT | ERR_FATAL;
3417 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003418 }
3419 cur_arg++;
3420 }
Willy Tarreau67402132012-05-31 20:40:20 +02003421 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003422 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3423 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003424 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003425 }
3426
Willy Tarreau67402132012-05-31 20:40:20 +02003427 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003428 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3429 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003430 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003431 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003432
Willy Tarreau67402132012-05-31 20:40:20 +02003433 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003434 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3435 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003436 err_code |= ERR_ALERT | ERR_FATAL;
3437 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003438 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003439 else if (!strcmp(args[0], "email-alert")) {
3440 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003441 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3442 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003443 err_code |= ERR_ALERT | ERR_FATAL;
3444 goto out;
3445 }
3446
3447 if (!strcmp(args[1], "from")) {
3448 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003449 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3450 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003451 err_code |= ERR_ALERT | ERR_FATAL;
3452 goto out;
3453 }
3454 free(curproxy->email_alert.from);
3455 curproxy->email_alert.from = strdup(args[2]);
3456 }
3457 else if (!strcmp(args[1], "mailers")) {
3458 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003459 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3460 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003461 err_code |= ERR_ALERT | ERR_FATAL;
3462 goto out;
3463 }
3464 free(curproxy->email_alert.mailers.name);
3465 curproxy->email_alert.mailers.name = strdup(args[2]);
3466 }
3467 else if (!strcmp(args[1], "myhostname")) {
3468 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003469 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3470 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003471 err_code |= ERR_ALERT | ERR_FATAL;
3472 goto out;
3473 }
3474 free(curproxy->email_alert.myhostname);
3475 curproxy->email_alert.myhostname = strdup(args[2]);
3476 }
Simon Horman64e34162015-02-06 11:11:57 +09003477 else if (!strcmp(args[1], "level")) {
3478 curproxy->email_alert.level = get_log_level(args[2]);
3479 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003480 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3481 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003482 err_code |= ERR_ALERT | ERR_FATAL;
3483 goto out;
3484 }
3485 }
Simon Horman9dc49962015-01-30 11:22:59 +09003486 else if (!strcmp(args[1], "to")) {
3487 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003488 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3489 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003490 err_code |= ERR_ALERT | ERR_FATAL;
3491 goto out;
3492 }
3493 free(curproxy->email_alert.to);
3494 curproxy->email_alert.to = strdup(args[2]);
3495 }
3496 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003497 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3498 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003499 err_code |= ERR_ALERT | ERR_FATAL;
3500 goto out;
3501 }
Simon Horman64e34162015-02-06 11:11:57 +09003502 /* Indicate that the email_alert is at least partially configured */
3503 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003504 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003505 else if (!strcmp(args[0], "external-check")) {
3506 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003507 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3508 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003509 err_code |= ERR_ALERT | ERR_FATAL;
3510 goto out;
3511 }
3512
3513 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003514 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003515 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003516 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003517 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3518 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003519 err_code |= ERR_ALERT | ERR_FATAL;
3520 goto out;
3521 }
3522 free(curproxy->check_command);
3523 curproxy->check_command = strdup(args[2]);
3524 }
3525 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003526 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003527 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003528 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003529 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3530 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003531 err_code |= ERR_ALERT | ERR_FATAL;
3532 goto out;
3533 }
3534 free(curproxy->check_path);
3535 curproxy->check_path = strdup(args[2]);
3536 }
3537 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003538 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3539 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003540 err_code |= ERR_ALERT | ERR_FATAL;
3541 goto out;
3542 }
3543 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003544 else if (!strcmp(args[0], "persist")) { /* persist */
3545 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003546 ha_alert("parsing [%s:%d] : missing persist method.\n",
3547 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003548 err_code |= ERR_ALERT | ERR_FATAL;
3549 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003550 }
3551
3552 if (!strncmp(args[1], "rdp-cookie", 10)) {
3553 curproxy->options2 |= PR_O2_RDPC_PRST;
3554
Emeric Brunb982a3d2010-01-04 15:45:53 +01003555 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003556 const char *beg, *end;
3557
3558 beg = args[1] + 11;
3559 end = strchr(beg, ')');
3560
William Lallemanddf1425a2015-04-28 20:17:49 +02003561 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3562 goto out;
3563
Emeric Brun647caf12009-06-30 17:57:00 +02003564 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003565 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3566 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003567 err_code |= ERR_ALERT | ERR_FATAL;
3568 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003569 }
3570
3571 free(curproxy->rdp_cookie_name);
3572 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3573 curproxy->rdp_cookie_len = end-beg;
3574 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003575 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003576 free(curproxy->rdp_cookie_name);
3577 curproxy->rdp_cookie_name = strdup("msts");
3578 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3579 }
3580 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003581 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3582 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003583 err_code |= ERR_ALERT | ERR_FATAL;
3584 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003585 }
3586 }
3587 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003588 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3589 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003590 err_code |= ERR_ALERT | ERR_FATAL;
3591 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003592 }
3593 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003594 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003595 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 +02003596 err_code |= ERR_ALERT | ERR_FATAL;
3597 goto out;
3598 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003599 else if (!strcmp(args[0], "load-server-state-from-file")) {
3600 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3601 err_code |= ERR_WARN;
3602 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3603 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3604 }
3605 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3606 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3607 }
3608 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3609 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3610 }
3611 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003612 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3613 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003614 err_code |= ERR_ALERT | ERR_FATAL;
3615 goto out;
3616 }
3617 }
3618 else if (!strcmp(args[0], "server-state-file-name")) {
3619 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3620 err_code |= ERR_WARN;
3621 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003622 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3623 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003624 err_code |= ERR_ALERT | ERR_FATAL;
3625 goto out;
3626 }
3627 else if (!strcmp(args[1], "use-backend-name"))
3628 curproxy->server_state_file_name = strdup(curproxy->id);
3629 else
3630 curproxy->server_state_file_name = strdup(args[1]);
3631 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003632 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003633 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003634 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003635
Willy Tarreaubaaee002006-06-26 02:48:02 +02003636 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003637 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003638 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 +01003639 err_code |= ERR_ALERT | ERR_FATAL;
3640 goto out;
3641 }
3642
William Lallemand1a748ae2015-05-19 16:37:23 +02003643 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3644 goto out;
3645
Willy Tarreaubaaee002006-06-26 02:48:02 +02003646 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003647 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3648 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003649 err_code |= ERR_ALERT | ERR_FATAL;
3650 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003651 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003652 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003653 curproxy->capture_name = strdup(args[2]);
3654 curproxy->capture_namelen = strlen(curproxy->capture_name);
3655 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003656 curproxy->to_log |= LW_COOKIE;
3657 }
3658 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3659 struct cap_hdr *hdr;
3660
3661 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003662 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 +02003663 err_code |= ERR_ALERT | ERR_FATAL;
3664 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003665 }
3666
William Lallemand1a748ae2015-05-19 16:37:23 +02003667 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3668 goto out;
3669
Willy Tarreaubaaee002006-06-26 02:48:02 +02003670 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003671 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3672 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003673 err_code |= ERR_ALERT | ERR_FATAL;
3674 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003675 }
3676
Vincent Bernat02779b62016-04-03 13:48:43 +02003677 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003678 hdr->next = curproxy->req_cap;
3679 hdr->name = strdup(args[3]);
3680 hdr->namelen = strlen(args[3]);
3681 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003682 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003683 hdr->index = curproxy->nb_req_cap++;
3684 curproxy->req_cap = hdr;
3685 curproxy->to_log |= LW_REQHDR;
3686 }
3687 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3688 struct cap_hdr *hdr;
3689
3690 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003691 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 +02003692 err_code |= ERR_ALERT | ERR_FATAL;
3693 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003694 }
3695
William Lallemand1a748ae2015-05-19 16:37:23 +02003696 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3697 goto out;
3698
Willy Tarreaubaaee002006-06-26 02:48:02 +02003699 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003700 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3701 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003702 err_code |= ERR_ALERT | ERR_FATAL;
3703 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003704 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003705 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003706 hdr->next = curproxy->rsp_cap;
3707 hdr->name = strdup(args[3]);
3708 hdr->namelen = strlen(args[3]);
3709 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003710 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003711 hdr->index = curproxy->nb_rsp_cap++;
3712 curproxy->rsp_cap = hdr;
3713 curproxy->to_log |= LW_RSPHDR;
3714 }
3715 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003716 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3717 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003718 err_code |= ERR_ALERT | ERR_FATAL;
3719 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003720 }
3721 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003722 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003723 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003724 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003725
William Lallemanddf1425a2015-04-28 20:17:49 +02003726 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3727 goto out;
3728
Willy Tarreaubaaee002006-06-26 02:48:02 +02003729 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003730 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3731 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003732 err_code |= ERR_ALERT | ERR_FATAL;
3733 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003734 }
3735 curproxy->conn_retries = atol(args[1]);
3736 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003737 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003738 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003739
3740 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003741 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003742 err_code |= ERR_ALERT | ERR_FATAL;
3743 goto out;
3744 }
3745
Willy Tarreau20b0de52012-12-24 15:45:22 +01003746 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003747 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003748 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3749 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3750 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3751 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003752 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3753 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003754 err_code |= ERR_WARN;
3755 }
3756
Willy Tarreauff011f22011-01-06 17:51:27 +01003757 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003758
Willy Tarreauff011f22011-01-06 17:51:27 +01003759 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003760 err_code |= ERR_ALERT | ERR_ABORT;
3761 goto out;
3762 }
3763
Willy Tarreau5002f572014-04-23 01:32:02 +02003764 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003765 err_code |= warnif_cond_conflicts(rule->cond,
3766 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3767 file, linenum);
3768
Willy Tarreauff011f22011-01-06 17:51:27 +01003769 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003770 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003771 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003772 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003773
3774 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003775 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003776 err_code |= ERR_ALERT | ERR_FATAL;
3777 goto out;
3778 }
3779
3780 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003781 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003782 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3783 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003784 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3785 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003786 err_code |= ERR_WARN;
3787 }
3788
3789 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3790
3791 if (!rule) {
3792 err_code |= ERR_ALERT | ERR_ABORT;
3793 goto out;
3794 }
3795
3796 err_code |= warnif_cond_conflicts(rule->cond,
3797 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3798 file, linenum);
3799
3800 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3801 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003802 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3803 /* set the header name and length into the proxy structure */
3804 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3805 err_code |= ERR_WARN;
3806
3807 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003808 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3809 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003810 err_code |= ERR_ALERT | ERR_FATAL;
3811 goto out;
3812 }
3813
3814 /* set the desired header name */
3815 free(curproxy->server_id_hdr_name);
3816 curproxy->server_id_hdr_name = strdup(args[1]);
3817 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3818 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003819 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003820 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003821
Willy Tarreaub099aca2008-10-12 17:26:37 +02003822 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003823 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003824 err_code |= ERR_ALERT | ERR_FATAL;
3825 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003826 }
3827
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003828 /* emulate "block" using "http-request block". Since these rules are supposed to
3829 * be processed before all http-request rules, we put them into their own list
3830 * and will insert them at the end.
3831 */
3832 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3833 if (!rule) {
3834 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003835 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003836 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003837 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3838 err_code |= warnif_cond_conflicts(rule->cond,
3839 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3840 file, linenum);
3841 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003842
3843 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003844 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 +02003845
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003846 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003847 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003848 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003849
Cyril Bonté99ed3272010-01-24 23:29:44 +01003850 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003851 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003852 err_code |= ERR_ALERT | ERR_FATAL;
3853 goto out;
3854 }
3855
Willy Tarreaube4653b2015-05-28 15:26:58 +02003856 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003857 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3858 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003859 err_code |= ERR_ALERT | ERR_FATAL;
3860 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003861 }
3862
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003863 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003864 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003865 err_code |= warnif_cond_conflicts(rule->cond,
3866 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3867 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003868 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003869 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003870 struct switching_rule *rule;
3871
Willy Tarreaub099aca2008-10-12 17:26:37 +02003872 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003873 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003874 err_code |= ERR_ALERT | ERR_FATAL;
3875 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003876 }
3877
Willy Tarreau55ea7572007-06-17 19:56:27 +02003878 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003879 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003880
3881 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003882 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003883 err_code |= ERR_ALERT | ERR_FATAL;
3884 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003885 }
3886
Willy Tarreauf51658d2014-04-23 01:21:56 +02003887 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003888 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003889 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3890 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02003891 err_code |= ERR_ALERT | ERR_FATAL;
3892 goto out;
3893 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003894
Willy Tarreauf51658d2014-04-23 01:21:56 +02003895 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02003896 }
Willy Tarreau4f862642017-02-28 09:34:39 +01003897 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003898 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
3899 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01003900 err_code |= ERR_ALERT | ERR_FATAL;
3901 goto out;
3902 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003903
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003904 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01003905 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003906 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01003907 goto out;
3908 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003909 rule->cond = cond;
3910 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01003911 rule->line = linenum;
3912 rule->file = strdup(file);
3913 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003914 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01003915 goto out;
3916 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003917 LIST_INIT(&rule->list);
3918 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
3919 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003920 else if (strcmp(args[0], "use-server") == 0) {
3921 struct server_rule *rule;
3922
3923 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003924 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003925 err_code |= ERR_ALERT | ERR_FATAL;
3926 goto out;
3927 }
3928
3929 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3930 err_code |= ERR_WARN;
3931
3932 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003933 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003934 err_code |= ERR_ALERT | ERR_FATAL;
3935 goto out;
3936 }
3937
3938 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003939 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
3940 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003941 err_code |= ERR_ALERT | ERR_FATAL;
3942 goto out;
3943 }
3944
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003945 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003946 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3947 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003948 err_code |= ERR_ALERT | ERR_FATAL;
3949 goto out;
3950 }
3951
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003952 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003953
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003954 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003955 rule->cond = cond;
3956 rule->srv.name = strdup(args[1]);
3957 LIST_INIT(&rule->list);
3958 LIST_ADDQ(&curproxy->server_rules, &rule->list);
3959 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
3960 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02003961 else if ((!strcmp(args[0], "force-persist")) ||
3962 (!strcmp(args[0], "ignore-persist"))) {
3963 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01003964
3965 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003966 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01003967 err_code |= ERR_ALERT | ERR_FATAL;
3968 goto out;
3969 }
3970
Cyril Bonté4288c5a2018-03-12 22:02:59 +01003971 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01003972 err_code |= ERR_WARN;
3973
Willy Tarreauef6494c2010-01-28 17:12:36 +01003974 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003975 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
3976 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01003977 err_code |= ERR_ALERT | ERR_FATAL;
3978 goto out;
3979 }
3980
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003981 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003982 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
3983 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01003984 err_code |= ERR_ALERT | ERR_FATAL;
3985 goto out;
3986 }
3987
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003988 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
3989 * where force-persist is applied.
3990 */
3991 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01003992
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003993 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01003994 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02003995 if (!strcmp(args[0], "force-persist")) {
3996 rule->type = PERSIST_TYPE_FORCE;
3997 } else {
3998 rule->type = PERSIST_TYPE_IGNORE;
3999 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004000 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004001 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004002 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004003 else if (!strcmp(args[0], "stick-table")) {
4004 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004005 struct proxy *other;
4006
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004007 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004008 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004009 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4010 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004011 err_code |= ERR_ALERT | ERR_FATAL;
4012 goto out;
4013 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004014
Emeric Brun32da3c42010-09-23 18:39:19 +02004015 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004016 curproxy->table.type = (unsigned int)-1;
4017 while (*args[myidx]) {
4018 const char *err;
4019
4020 if (strcmp(args[myidx], "size") == 0) {
4021 myidx++;
4022 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004023 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4024 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004025 err_code |= ERR_ALERT | ERR_FATAL;
4026 goto out;
4027 }
4028 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004029 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4030 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004031 err_code |= ERR_ALERT | ERR_FATAL;
4032 goto out;
4033 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004034 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004035 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004036 else if (strcmp(args[myidx], "peers") == 0) {
4037 myidx++;
Godbach50523162013-12-11 19:48:57 +08004038 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004039 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4040 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004041 err_code |= ERR_ALERT | ERR_FATAL;
4042 goto out;
Godbach50523162013-12-11 19:48:57 +08004043 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004044 curproxy->table.peers.name = strdup(args[myidx++]);
4045 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004046 else if (strcmp(args[myidx], "expire") == 0) {
4047 myidx++;
4048 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004049 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4050 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004051 err_code |= ERR_ALERT | ERR_FATAL;
4052 goto out;
4053 }
4054 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4055 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004056 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4057 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004058 err_code |= ERR_ALERT | ERR_FATAL;
4059 goto out;
4060 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004061 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004062 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4063 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004064 err_code |= ERR_ALERT | ERR_FATAL;
4065 goto out;
4066 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004067 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004068 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004069 }
4070 else if (strcmp(args[myidx], "nopurge") == 0) {
4071 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004072 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004073 }
4074 else if (strcmp(args[myidx], "type") == 0) {
4075 myidx++;
4076 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004077 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4078 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004079 err_code |= ERR_ALERT | ERR_FATAL;
4080 goto out;
4081 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004082 /* myidx already points to next arg */
4083 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004084 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004085 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004086 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004087
4088 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004089 nw = args[myidx];
4090 while (*nw) {
4091 /* the "store" keyword supports a comma-separated list */
4092 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004093 sa = NULL; /* store arg */
4094 while (*nw && *nw != ',') {
4095 if (*nw == '(') {
4096 *nw = 0;
4097 sa = ++nw;
4098 while (*nw != ')') {
4099 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004100 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4101 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004102 err_code |= ERR_ALERT | ERR_FATAL;
4103 goto out;
4104 }
4105 nw++;
4106 }
4107 *nw = '\0';
4108 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004109 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004110 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004111 if (*nw)
4112 *nw++ = '\0';
4113 type = stktable_get_data_type(cw);
4114 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004115 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4116 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004117 err_code |= ERR_ALERT | ERR_FATAL;
4118 goto out;
4119 }
Willy Tarreauac782882010-06-20 10:41:54 +02004120
4121 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4122 switch (err) {
4123 case PE_NONE: break;
4124 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004125 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4126 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004127 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004128 break;
4129
4130 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004131 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4132 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004133 err_code |= ERR_ALERT | ERR_FATAL;
4134 goto out;
4135
4136 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004137 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4138 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004139 err_code |= ERR_ALERT | ERR_FATAL;
4140 goto out;
4141
4142 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004143 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4144 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004145 err_code |= ERR_ALERT | ERR_FATAL;
4146 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004147 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004148 }
4149 myidx++;
4150 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004151 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004152 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4153 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004154 err_code |= ERR_ALERT | ERR_FATAL;
4155 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004156 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004157 }
4158
4159 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004160 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4161 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004162 err_code |= ERR_ALERT | ERR_FATAL;
4163 goto out;
4164 }
4165
4166 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004167 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4168 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004169 err_code |= ERR_ALERT | ERR_FATAL;
4170 goto out;
4171 }
4172 }
4173 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004174 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004175 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004176 int myidx = 0;
4177 const char *name = NULL;
4178 int flags;
4179
4180 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004181 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004182 err_code |= ERR_ALERT | ERR_FATAL;
4183 goto out;
4184 }
4185
4186 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4187 err_code |= ERR_WARN;
4188 goto out;
4189 }
4190
4191 myidx++;
4192 if ((strcmp(args[myidx], "store") == 0) ||
4193 (strcmp(args[myidx], "store-request") == 0)) {
4194 myidx++;
4195 flags = STK_IS_STORE;
4196 }
4197 else if (strcmp(args[myidx], "store-response") == 0) {
4198 myidx++;
4199 flags = STK_IS_STORE | STK_ON_RSP;
4200 }
4201 else if (strcmp(args[myidx], "match") == 0) {
4202 myidx++;
4203 flags = STK_IS_MATCH;
4204 }
4205 else if (strcmp(args[myidx], "on") == 0) {
4206 myidx++;
4207 flags = STK_IS_MATCH | STK_IS_STORE;
4208 }
4209 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004210 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004211 err_code |= ERR_ALERT | ERR_FATAL;
4212 goto out;
4213 }
4214
4215 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004216 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004217 err_code |= ERR_ALERT | ERR_FATAL;
4218 goto out;
4219 }
4220
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004221 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004222 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004223 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004224 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004225 err_code |= ERR_ALERT | ERR_FATAL;
4226 goto out;
4227 }
4228
4229 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004230 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004231 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4232 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004233 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004234 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004235 goto out;
4236 }
4237 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004238 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004239 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4240 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004241 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004242 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004243 goto out;
4244 }
4245 }
4246
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004247 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004248 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004249
Emeric Brunb982a3d2010-01-04 15:45:53 +01004250 if (strcmp(args[myidx], "table") == 0) {
4251 myidx++;
4252 name = args[myidx++];
4253 }
4254
Willy Tarreauef6494c2010-01-28 17:12:36 +01004255 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004256 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004257 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4258 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004259 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004260 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004261 goto out;
4262 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004263 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004264 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004265 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4266 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004267 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004268 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004269 goto out;
4270 }
Emeric Brun97679e72010-09-23 17:56:44 +02004271 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004272 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004273 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004274 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004275
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004276 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004277 rule->cond = cond;
4278 rule->expr = expr;
4279 rule->flags = flags;
4280 rule->table.name = name ? strdup(name) : NULL;
4281 LIST_INIT(&rule->list);
4282 if (flags & STK_ON_RSP)
4283 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4284 else
4285 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4286 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004287 else if (!strcmp(args[0], "stats")) {
4288 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4289 curproxy->uri_auth = NULL; /* we must detach from the default config */
4290
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004291 if (!*args[1]) {
4292 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004293 } else if (!strcmp(args[1], "admin")) {
4294 struct stats_admin_rule *rule;
4295
4296 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004297 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 +02004298 err_code |= ERR_ALERT | ERR_FATAL;
4299 goto out;
4300 }
4301
4302 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004303 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004304 err_code |= ERR_ALERT | ERR_ABORT;
4305 goto out;
4306 }
4307
4308 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004309 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4310 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004311 err_code |= ERR_ALERT | ERR_FATAL;
4312 goto out;
4313 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004314 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004315 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4316 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004317 err_code |= ERR_ALERT | ERR_FATAL;
4318 goto out;
4319 }
4320
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004321 err_code |= warnif_cond_conflicts(cond,
4322 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4323 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004324
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004325 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004326 rule->cond = cond;
4327 LIST_INIT(&rule->list);
4328 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004329 } else if (!strcmp(args[1], "uri")) {
4330 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004331 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004332 err_code |= ERR_ALERT | ERR_FATAL;
4333 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004334 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004335 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004336 err_code |= ERR_ALERT | ERR_ABORT;
4337 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004338 }
4339 } else if (!strcmp(args[1], "realm")) {
4340 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004341 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004342 err_code |= ERR_ALERT | ERR_FATAL;
4343 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004344 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004345 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004346 err_code |= ERR_ALERT | ERR_ABORT;
4347 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004348 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004349 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004350 unsigned interval;
4351
4352 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4353 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004354 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4355 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004356 err_code |= ERR_ALERT | ERR_FATAL;
4357 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004358 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004359 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004360 err_code |= ERR_ALERT | ERR_ABORT;
4361 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004362 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004363 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004364 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004365
4366 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004367 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004368 err_code |= ERR_ALERT | ERR_FATAL;
4369 goto out;
4370 }
4371
4372 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004373 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004374 err_code |= ERR_ALERT | ERR_ABORT;
4375 goto out;
4376 }
4377
Willy Tarreauff011f22011-01-06 17:51:27 +01004378 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004379 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004380 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4381 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004382 err_code |= ERR_WARN;
4383 }
4384
Willy Tarreauff011f22011-01-06 17:51:27 +01004385 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004386
Willy Tarreauff011f22011-01-06 17:51:27 +01004387 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004388 err_code |= ERR_ALERT | ERR_ABORT;
4389 goto out;
4390 }
4391
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004392 err_code |= warnif_cond_conflicts(rule->cond,
4393 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4394 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004395 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004396
Willy Tarreaubaaee002006-06-26 02:48:02 +02004397 } else if (!strcmp(args[1], "auth")) {
4398 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004399 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004400 err_code |= ERR_ALERT | ERR_FATAL;
4401 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004402 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004403 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004404 err_code |= ERR_ALERT | ERR_ABORT;
4405 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004406 }
4407 } else if (!strcmp(args[1], "scope")) {
4408 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004409 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004410 err_code |= ERR_ALERT | ERR_FATAL;
4411 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004412 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004413 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004414 err_code |= ERR_ALERT | ERR_ABORT;
4415 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004416 }
4417 } else if (!strcmp(args[1], "enable")) {
4418 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004419 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004420 err_code |= ERR_ALERT | ERR_ABORT;
4421 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004422 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004423 } else if (!strcmp(args[1], "hide-version")) {
4424 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004425 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004426 err_code |= ERR_ALERT | ERR_ABORT;
4427 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004428 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004429 } else if (!strcmp(args[1], "show-legends")) {
4430 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004431 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004432 err_code |= ERR_ALERT | ERR_ABORT;
4433 goto out;
4434 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004435 } else if (!strcmp(args[1], "show-node")) {
4436
4437 if (*args[2]) {
4438 int i;
4439 char c;
4440
4441 for (i=0; args[2][i]; i++) {
4442 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004443 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4444 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004445 break;
4446 }
4447
4448 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004449 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4450 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4451 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004452 err_code |= ERR_ALERT | ERR_FATAL;
4453 goto out;
4454 }
4455 }
4456
4457 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004458 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004459 err_code |= ERR_ALERT | ERR_ABORT;
4460 goto out;
4461 }
4462 } else if (!strcmp(args[1], "show-desc")) {
4463 char *desc = NULL;
4464
4465 if (*args[2]) {
4466 int i, len=0;
4467 char *d;
4468
Willy Tarreau348acfe2014-04-14 15:00:39 +02004469 for (i = 2; *args[i]; i++)
4470 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004471
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004472 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004473
Willy Tarreau348acfe2014-04-14 15:00:39 +02004474 d += snprintf(d, desc + len - d, "%s", args[2]);
4475 for (i = 3; *args[i]; i++)
4476 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004477 }
4478
4479 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004480 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4481 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004482 else {
4483 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4484 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004485 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004486 err_code |= ERR_ALERT | ERR_ABORT;
4487 goto out;
4488 }
4489 free(desc);
4490 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004491 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004492stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004493 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4494 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004495 err_code |= ERR_ALERT | ERR_FATAL;
4496 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004497 }
4498 }
4499 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004500 int optnum;
4501
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004502 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004503 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4504 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004505 err_code |= ERR_ALERT | ERR_FATAL;
4506 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004507 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004508
4509 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4510 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004511 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004512 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4513 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004514 err_code |= ERR_ALERT | ERR_FATAL;
4515 goto out;
4516 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004517 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4518 goto out;
4519
Willy Tarreau93893792009-07-23 13:19:11 +02004520 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4521 err_code |= ERR_WARN;
4522 goto out;
4523 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004524
Willy Tarreau3842f002009-06-14 11:39:52 +02004525 curproxy->no_options &= ~cfg_opts[optnum].val;
4526 curproxy->options &= ~cfg_opts[optnum].val;
4527
4528 switch (kwm) {
4529 case KWM_STD:
4530 curproxy->options |= cfg_opts[optnum].val;
4531 break;
4532 case KWM_NO:
4533 curproxy->no_options |= cfg_opts[optnum].val;
4534 break;
4535 case KWM_DEF: /* already cleared */
4536 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004537 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004538
Willy Tarreau93893792009-07-23 13:19:11 +02004539 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004540 }
4541 }
4542
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004543 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4544 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004545 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004546 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4547 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004548 err_code |= ERR_ALERT | ERR_FATAL;
4549 goto out;
4550 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004551 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4552 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004553 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4554 err_code |= ERR_WARN;
4555 goto out;
4556 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004557
Willy Tarreau3842f002009-06-14 11:39:52 +02004558 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4559 curproxy->options2 &= ~cfg_opts2[optnum].val;
4560
4561 switch (kwm) {
4562 case KWM_STD:
4563 curproxy->options2 |= cfg_opts2[optnum].val;
4564 break;
4565 case KWM_NO:
4566 curproxy->no_options2 |= cfg_opts2[optnum].val;
4567 break;
4568 case KWM_DEF: /* already cleared */
4569 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004570 }
Willy Tarreau93893792009-07-23 13:19:11 +02004571 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004572 }
4573 }
4574
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004575 /* HTTP options override each other. They can be cancelled using
4576 * "no option xxx" which only switches to default mode if the mode
4577 * was this one (useful for cancelling options set in defaults
4578 * sections).
4579 */
4580 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004581 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4582 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004583 if (kwm == KWM_STD) {
4584 curproxy->options &= ~PR_O_HTTP_MODE;
4585 curproxy->options |= PR_O_HTTP_PCL;
4586 goto out;
4587 }
4588 else if (kwm == KWM_NO) {
4589 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4590 curproxy->options &= ~PR_O_HTTP_MODE;
4591 goto out;
4592 }
4593 }
4594 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004595 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4596 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004597 if (kwm == KWM_STD) {
4598 curproxy->options &= ~PR_O_HTTP_MODE;
4599 curproxy->options |= PR_O_HTTP_FCL;
4600 goto out;
4601 }
4602 else if (kwm == KWM_NO) {
4603 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4604 curproxy->options &= ~PR_O_HTTP_MODE;
4605 goto out;
4606 }
4607 }
4608 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004609 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4610 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004611 if (kwm == KWM_STD) {
4612 curproxy->options &= ~PR_O_HTTP_MODE;
4613 curproxy->options |= PR_O_HTTP_SCL;
4614 goto out;
4615 }
4616 else if (kwm == KWM_NO) {
4617 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4618 curproxy->options &= ~PR_O_HTTP_MODE;
4619 goto out;
4620 }
4621 }
4622 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004623 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4624 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004625 if (kwm == KWM_STD) {
4626 curproxy->options &= ~PR_O_HTTP_MODE;
4627 curproxy->options |= PR_O_HTTP_KAL;
4628 goto out;
4629 }
4630 else if (kwm == KWM_NO) {
4631 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4632 curproxy->options &= ~PR_O_HTTP_MODE;
4633 goto out;
4634 }
4635 }
4636 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004637 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4638 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004639 if (kwm == KWM_STD) {
4640 curproxy->options &= ~PR_O_HTTP_MODE;
4641 curproxy->options |= PR_O_HTTP_TUN;
4642 goto out;
4643 }
4644 else if (kwm == KWM_NO) {
4645 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4646 curproxy->options &= ~PR_O_HTTP_MODE;
4647 goto out;
4648 }
4649 }
4650
Joseph Lynch726ab712015-05-11 23:25:34 -07004651 /* Redispatch can take an integer argument that control when the
4652 * resispatch occurs. All values are relative to the retries option.
4653 * This can be cancelled using "no option xxx".
4654 */
4655 if (strcmp(args[1], "redispatch") == 0) {
4656 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4657 err_code |= ERR_WARN;
4658 goto out;
4659 }
4660
4661 curproxy->no_options &= ~PR_O_REDISP;
4662 curproxy->options &= ~PR_O_REDISP;
4663
4664 switch (kwm) {
4665 case KWM_STD:
4666 curproxy->options |= PR_O_REDISP;
4667 curproxy->redispatch_after = -1;
4668 if(*args[2]) {
4669 curproxy->redispatch_after = atol(args[2]);
4670 }
4671 break;
4672 case KWM_NO:
4673 curproxy->no_options |= PR_O_REDISP;
4674 curproxy->redispatch_after = 0;
4675 break;
4676 case KWM_DEF: /* already cleared */
4677 break;
4678 }
4679 goto out;
4680 }
4681
Willy Tarreau3842f002009-06-14 11:39:52 +02004682 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004683 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4684 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004685 err_code |= ERR_ALERT | ERR_FATAL;
4686 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004687 }
4688
Emeric Brun3a058f32009-06-30 18:26:00 +02004689 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004690 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004691 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004692 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004693 if (*(args[2]) != '\0') {
4694 if (!strcmp(args[2], "clf")) {
4695 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004696 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004697 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004698 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004699 err_code |= ERR_ALERT | ERR_FATAL;
4700 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004701 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004702 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4703 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004704 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004705 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4706 char *oldlogformat = "log-format";
4707 char *clflogformat = "";
4708
4709 if (curproxy->conf.logformat_string == default_http_log_format)
4710 oldlogformat = "option httplog";
4711 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4712 oldlogformat = "option tcplog";
4713 else if (curproxy->conf.logformat_string == clf_http_log_format)
4714 oldlogformat = "option httplog clf";
4715 if (logformat == clf_http_log_format)
4716 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004717 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4718 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004719 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004720 if (curproxy->conf.logformat_string != default_http_log_format &&
4721 curproxy->conf.logformat_string != default_tcp_log_format &&
4722 curproxy->conf.logformat_string != clf_http_log_format)
4723 free(curproxy->conf.logformat_string);
4724 curproxy->conf.logformat_string = logformat;
4725
4726 free(curproxy->conf.lfs_file);
4727 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4728 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004729
4730 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4731 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4732 file, linenum, curproxy->id);
4733 err_code |= ERR_WARN;
4734 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004735 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004736 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004737 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4738 char *oldlogformat = "log-format";
4739
4740 if (curproxy->conf.logformat_string == default_http_log_format)
4741 oldlogformat = "option httplog";
4742 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4743 oldlogformat = "option tcplog";
4744 else if (curproxy->conf.logformat_string == clf_http_log_format)
4745 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004746 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4747 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004748 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004749 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004750 if (curproxy->conf.logformat_string != default_http_log_format &&
4751 curproxy->conf.logformat_string != default_tcp_log_format &&
4752 curproxy->conf.logformat_string != clf_http_log_format)
4753 free(curproxy->conf.logformat_string);
4754 curproxy->conf.logformat_string = default_tcp_log_format;
4755
4756 free(curproxy->conf.lfs_file);
4757 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4758 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004759
4760 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4761 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004762
4763 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4764 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4765 file, linenum, curproxy->id);
4766 err_code |= ERR_WARN;
4767 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004768 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004769 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004770 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004771 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004772 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004773
William Lallemanddf1425a2015-04-28 20:17:49 +02004774 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4775 goto out;
4776
Willy Tarreau13943ab2006-12-31 00:24:10 +01004777 if (curproxy->cap & PR_CAP_FE)
4778 curproxy->options |= PR_O_TCP_CLI_KA;
4779 if (curproxy->cap & PR_CAP_BE)
4780 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004781 }
4782 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004783 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004784 err_code |= ERR_WARN;
4785
Willy Tarreaubaaee002006-06-26 02:48:02 +02004786 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004787 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004788 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004789 curproxy->options2 &= ~PR_O2_CHK_ANY;
4790 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004791 if (!*args[2]) { /* no argument */
4792 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4793 curproxy->check_len = strlen(DEF_CHECK_REQ);
4794 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004795 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004796 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004797 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004798 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004799 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004800 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004801 if (*args[4])
4802 reqlen += strlen(args[4]);
4803 else
4804 reqlen += strlen("HTTP/1.0");
4805
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004806 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004807 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004808 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004809 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004810 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4811 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004812 }
4813 else if (!strcmp(args[1], "ssl-hello-chk")) {
4814 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004815 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004816 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004817
Willy Tarreaua534fea2008-08-03 12:19:50 +02004818 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004819 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004820 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004821 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004822
4823 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4824 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004825 }
Willy Tarreau23677902007-05-08 23:50:35 +02004826 else if (!strcmp(args[1], "smtpchk")) {
4827 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004828 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004829 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004830 curproxy->options2 &= ~PR_O2_CHK_ANY;
4831 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004832
4833 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4834 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4835 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4836 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4837 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4838 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004839 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004840 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4841 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4842 } else {
4843 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4844 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4845 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4846 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4847 }
4848 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004849 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4850 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004851 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004852 else if (!strcmp(args[1], "pgsql-check")) {
4853 /* use PostgreSQL request to check servers' health */
4854 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4855 err_code |= ERR_WARN;
4856
4857 free(curproxy->check_req);
4858 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004859 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004860 curproxy->options2 |= PR_O2_PGSQL_CHK;
4861
4862 if (*(args[2])) {
4863 int cur_arg = 2;
4864
4865 while (*(args[cur_arg])) {
4866 if (strcmp(args[cur_arg], "user") == 0) {
4867 char * packet;
4868 uint32_t packet_len;
4869 uint32_t pv;
4870
4871 /* suboption header - needs additional argument for it */
4872 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004873 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4874 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004875 err_code |= ERR_ALERT | ERR_FATAL;
4876 goto out;
4877 }
4878
4879 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4880 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4881 pv = htonl(0x30000); /* protocol version 3.0 */
4882
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004883 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004884
4885 memcpy(packet + 4, &pv, 4);
4886
4887 /* copy "user" */
4888 memcpy(packet + 8, "user", 4);
4889
4890 /* copy username */
4891 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
4892
4893 free(curproxy->check_req);
4894 curproxy->check_req = packet;
4895 curproxy->check_len = packet_len;
4896
4897 packet_len = htonl(packet_len);
4898 memcpy(packet, &packet_len, 4);
4899 cur_arg += 2;
4900 } else {
4901 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004902 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
4903 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004904 err_code |= ERR_ALERT | ERR_FATAL;
4905 goto out;
4906 }
4907 } /* end while loop */
4908 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004909 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4910 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004911 }
4912
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004913 else if (!strcmp(args[1], "redis-check")) {
4914 /* use REDIS PING request to check servers' health */
4915 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4916 err_code |= ERR_WARN;
4917
4918 free(curproxy->check_req);
4919 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004920 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004921 curproxy->options2 |= PR_O2_REDIS_CHK;
4922
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004923 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004924 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
4925 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02004926
4927 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4928 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004929 }
4930
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004931 else if (!strcmp(args[1], "mysql-check")) {
4932 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004933 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4934 err_code |= ERR_WARN;
4935
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004936 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004937 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004938 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004939 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004940
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004941 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004942 * const char mysql40_client_auth_pkt[] = {
4943 * "\x0e\x00\x00" // packet length
4944 * "\x01" // packet number
4945 * "\x00\x00" // client capabilities
4946 * "\x00\x00\x01" // max packet
4947 * "haproxy\x00" // username (null terminated string)
4948 * "\x00" // filler (always 0x00)
4949 * "\x01\x00\x00" // packet length
4950 * "\x00" // packet number
4951 * "\x01" // COM_QUIT command
4952 * };
4953 */
4954
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004955 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
4956 * const char mysql41_client_auth_pkt[] = {
4957 * "\x0e\x00\x00\" // packet length
4958 * "\x01" // packet number
4959 * "\x00\x00\x00\x00" // client capabilities
4960 * "\x00\x00\x00\x01" // max packet
4961 * "\x21" // character set (UTF-8)
4962 * char[23] // All zeroes
4963 * "haproxy\x00" // username (null terminated string)
4964 * "\x00" // filler (always 0x00)
4965 * "\x01\x00\x00" // packet length
4966 * "\x00" // packet number
4967 * "\x01" // COM_QUIT command
4968 * };
4969 */
4970
4971
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004972 if (*(args[2])) {
4973 int cur_arg = 2;
4974
4975 while (*(args[cur_arg])) {
4976 if (strcmp(args[cur_arg], "user") == 0) {
4977 char *mysqluser;
4978 int packetlen, reqlen, userlen;
4979
4980 /* suboption header - needs additional argument for it */
4981 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004982 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4983 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004984 err_code |= ERR_ALERT | ERR_FATAL;
4985 goto out;
4986 }
4987 mysqluser = args[cur_arg + 1];
4988 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004989
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004990 if (*(args[cur_arg+2])) {
4991 if (!strcmp(args[cur_arg+2], "post-41")) {
4992 packetlen = userlen + 7 + 27;
4993 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004994
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004995 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004996 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004997 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004998
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004999 snprintf(curproxy->check_req, 4, "%c%c%c",
5000 ((unsigned char) packetlen & 0xff),
5001 ((unsigned char) (packetlen >> 8) & 0xff),
5002 ((unsigned char) (packetlen >> 16) & 0xff));
5003
5004 curproxy->check_req[3] = 1;
5005 curproxy->check_req[5] = 130;
5006 curproxy->check_req[11] = 1;
5007 curproxy->check_req[12] = 33;
5008 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5009 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5010 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5011 cur_arg += 3;
5012 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005013 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 +02005014 err_code |= ERR_ALERT | ERR_FATAL;
5015 goto out;
5016 }
5017 } else {
5018 packetlen = userlen + 7;
5019 reqlen = packetlen + 9;
5020
5021 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005022 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005023 curproxy->check_len = reqlen;
5024
5025 snprintf(curproxy->check_req, 4, "%c%c%c",
5026 ((unsigned char) packetlen & 0xff),
5027 ((unsigned char) (packetlen >> 8) & 0xff),
5028 ((unsigned char) (packetlen >> 16) & 0xff));
5029
5030 curproxy->check_req[3] = 1;
5031 curproxy->check_req[5] = 128;
5032 curproxy->check_req[8] = 1;
5033 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5034 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5035 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5036 cur_arg += 2;
5037 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005038 } else {
5039 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005040 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5041 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005042 err_code |= ERR_ALERT | ERR_FATAL;
5043 goto out;
5044 }
5045 } /* end while loop */
5046 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005047 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005048 else if (!strcmp(args[1], "ldap-check")) {
5049 /* use LDAP request to check servers' health */
5050 free(curproxy->check_req);
5051 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005052 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005053 curproxy->options2 |= PR_O2_LDAP_CHK;
5054
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005055 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005056 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5057 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005058 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5059 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005060 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005061 else if (!strcmp(args[1], "spop-check")) {
5062 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005063 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5064 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005065 err_code |= ERR_ALERT | ERR_FATAL;
5066 goto out;
5067 }
5068 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005069 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5070 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005071 err_code |= ERR_ALERT | ERR_FATAL;
5072 goto out;
5073 }
5074
5075 /* use SPOE request to check servers' health */
5076 free(curproxy->check_req);
5077 curproxy->check_req = NULL;
5078 curproxy->options2 &= ~PR_O2_CHK_ANY;
5079 curproxy->options2 |= PR_O2_SPOP_CHK;
5080
Christopher Faulet8ef75252017-02-20 22:56:03 +01005081 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005082 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005083 err_code |= ERR_ALERT | ERR_FATAL;
5084 goto out;
5085 }
5086 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5087 goto out;
5088 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005089 else if (!strcmp(args[1], "tcp-check")) {
5090 /* use raw TCPCHK send/expect to check servers' health */
5091 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5092 err_code |= ERR_WARN;
5093
5094 free(curproxy->check_req);
5095 curproxy->check_req = NULL;
5096 curproxy->options2 &= ~PR_O2_CHK_ANY;
5097 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005098 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5099 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005100 }
Simon Horman98637e52014-06-20 12:30:16 +09005101 else if (!strcmp(args[1], "external-check")) {
5102 /* excute an external command to check servers' health */
5103 free(curproxy->check_req);
5104 curproxy->check_req = NULL;
5105 curproxy->options2 &= ~PR_O2_CHK_ANY;
5106 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005107 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5108 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005109 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005110 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005111 int cur_arg;
5112
5113 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5114 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005115 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005116
Willy Tarreau87cf5142011-08-19 22:57:24 +02005117 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005118
5119 free(curproxy->fwdfor_hdr_name);
5120 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5121 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5122
5123 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5124 cur_arg = 2;
5125 while (*(args[cur_arg])) {
5126 if (!strcmp(args[cur_arg], "except")) {
5127 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005128 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005129 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5130 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005131 err_code |= ERR_ALERT | ERR_FATAL;
5132 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005133 }
5134 /* flush useless bits */
5135 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005136 cur_arg += 2;
5137 } else if (!strcmp(args[cur_arg], "header")) {
5138 /* suboption header - needs additional argument for it */
5139 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005140 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5141 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005142 err_code |= ERR_ALERT | ERR_FATAL;
5143 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005144 }
5145 free(curproxy->fwdfor_hdr_name);
5146 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5147 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5148 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005149 } else if (!strcmp(args[cur_arg], "if-none")) {
5150 curproxy->options &= ~PR_O_FF_ALWAYS;
5151 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005152 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005153 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005154 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5155 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005156 err_code |= ERR_ALERT | ERR_FATAL;
5157 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005158 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005159 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005160 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005161 else if (!strcmp(args[1], "originalto")) {
5162 int cur_arg;
5163
5164 /* insert x-original-to field, but not for the IP address listed as an except.
5165 * set default options (ie: bitfield, header name, etc)
5166 */
5167
5168 curproxy->options |= PR_O_ORGTO;
5169
5170 free(curproxy->orgto_hdr_name);
5171 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5172 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5173
Willy Tarreau87cf5142011-08-19 22:57:24 +02005174 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005175 cur_arg = 2;
5176 while (*(args[cur_arg])) {
5177 if (!strcmp(args[cur_arg], "except")) {
5178 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005179 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 +01005180 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5181 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005182 err_code |= ERR_ALERT | ERR_FATAL;
5183 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005184 }
5185 /* flush useless bits */
5186 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5187 cur_arg += 2;
5188 } else if (!strcmp(args[cur_arg], "header")) {
5189 /* suboption header - needs additional argument for it */
5190 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005191 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5192 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005193 err_code |= ERR_ALERT | ERR_FATAL;
5194 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005195 }
5196 free(curproxy->orgto_hdr_name);
5197 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5198 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5199 cur_arg += 2;
5200 } else {
5201 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005202 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5203 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005204 err_code |= ERR_ALERT | ERR_FATAL;
5205 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005206 }
5207 } /* end while loop */
5208 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005209 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005210 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005211 err_code |= ERR_ALERT | ERR_FATAL;
5212 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005213 }
Willy Tarreau93893792009-07-23 13:19:11 +02005214 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005215 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005216 else if (!strcmp(args[0], "default_backend")) {
5217 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005218 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005219
5220 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005221 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005222 err_code |= ERR_ALERT | ERR_FATAL;
5223 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005224 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005225 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005226 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005227
5228 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5229 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005230 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005231 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005232 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005233 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005234
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005235 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005236 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5237 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005238 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005239 /* enable reconnections to dispatch */
5240 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005241
5242 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5243 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005244 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005245 else if (!strcmp(args[0], "http-reuse")) {
5246 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5247 err_code |= ERR_WARN;
5248
5249 if (strcmp(args[1], "never") == 0) {
5250 /* enable a graceful server shutdown on an HTTP 404 response */
5251 curproxy->options &= ~PR_O_REUSE_MASK;
5252 curproxy->options |= PR_O_REUSE_NEVR;
5253 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5254 goto out;
5255 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005256 else if (strcmp(args[1], "safe") == 0) {
5257 /* enable a graceful server shutdown on an HTTP 404 response */
5258 curproxy->options &= ~PR_O_REUSE_MASK;
5259 curproxy->options |= PR_O_REUSE_SAFE;
5260 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5261 goto out;
5262 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005263 else if (strcmp(args[1], "aggressive") == 0) {
5264 curproxy->options &= ~PR_O_REUSE_MASK;
5265 curproxy->options |= PR_O_REUSE_AGGR;
5266 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5267 goto out;
5268 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005269 else if (strcmp(args[1], "always") == 0) {
5270 /* enable a graceful server shutdown on an HTTP 404 response */
5271 curproxy->options &= ~PR_O_REUSE_MASK;
5272 curproxy->options |= PR_O_REUSE_ALWS;
5273 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5274 goto out;
5275 }
5276 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005277 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005278 err_code |= ERR_ALERT | ERR_FATAL;
5279 goto out;
5280 }
5281 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005282 else if (!strcmp(args[0], "http-check")) {
5283 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005284 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005285
5286 if (strcmp(args[1], "disable-on-404") == 0) {
5287 /* enable a graceful server shutdown on an HTTP 404 response */
5288 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005289 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5290 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005291 }
Willy Tarreauef781042010-01-27 11:53:01 +01005292 else if (strcmp(args[1], "send-state") == 0) {
5293 /* enable emission of the apparent state of a server in HTTP checks */
5294 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005295 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5296 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005297 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005298 else if (strcmp(args[1], "expect") == 0) {
5299 const char *ptr_arg;
5300 int cur_arg;
5301
5302 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005303 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005304 err_code |= ERR_ALERT | ERR_FATAL;
5305 goto out;
5306 }
5307
5308 cur_arg = 2;
5309 /* consider exclamation marks, sole or at the beginning of a word */
5310 while (*(ptr_arg = args[cur_arg])) {
5311 while (*ptr_arg == '!') {
5312 curproxy->options2 ^= PR_O2_EXP_INV;
5313 ptr_arg++;
5314 }
5315 if (*ptr_arg)
5316 break;
5317 cur_arg++;
5318 }
5319 /* now ptr_arg points to the beginning of a word past any possible
5320 * exclamation mark, and cur_arg is the argument which holds this word.
5321 */
5322 if (strcmp(ptr_arg, "status") == 0) {
5323 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005324 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5325 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005326 err_code |= ERR_ALERT | ERR_FATAL;
5327 goto out;
5328 }
5329 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005330 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005331 curproxy->expect_str = strdup(args[cur_arg + 1]);
5332 }
5333 else if (strcmp(ptr_arg, "string") == 0) {
5334 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005335 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5336 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005337 err_code |= ERR_ALERT | ERR_FATAL;
5338 goto out;
5339 }
5340 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005341 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005342 curproxy->expect_str = strdup(args[cur_arg + 1]);
5343 }
5344 else if (strcmp(ptr_arg, "rstatus") == 0) {
5345 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005346 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5347 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005348 err_code |= ERR_ALERT | ERR_FATAL;
5349 goto out;
5350 }
5351 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005352 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005353 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005354 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005355 free(curproxy->expect_regex);
5356 curproxy->expect_regex = NULL;
5357 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005358 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005359 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5360 error = NULL;
5361 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005362 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5363 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005364 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005365 err_code |= ERR_ALERT | ERR_FATAL;
5366 goto out;
5367 }
5368 }
5369 else if (strcmp(ptr_arg, "rstring") == 0) {
5370 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005371 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5372 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005373 err_code |= ERR_ALERT | ERR_FATAL;
5374 goto out;
5375 }
5376 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005377 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005378 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005379 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005380 free(curproxy->expect_regex);
5381 curproxy->expect_regex = NULL;
5382 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005383 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005384 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5385 error = NULL;
5386 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005387 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5388 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005389 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005390 err_code |= ERR_ALERT | ERR_FATAL;
5391 goto out;
5392 }
5393 }
5394 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005395 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5396 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005397 err_code |= ERR_ALERT | ERR_FATAL;
5398 goto out;
5399 }
5400 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005401 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005402 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 +02005403 err_code |= ERR_ALERT | ERR_FATAL;
5404 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005405 }
5406 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005407 else if (!strcmp(args[0], "tcp-check")) {
5408 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5409 err_code |= ERR_WARN;
5410
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005411 if (strcmp(args[1], "comment") == 0) {
5412 int cur_arg;
5413 struct tcpcheck_rule *tcpcheck;
5414
5415 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005416 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005417 tcpcheck->action = TCPCHK_ACT_COMMENT;
5418
5419 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005420 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5421 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005422 err_code |= ERR_ALERT | ERR_FATAL;
5423 goto out;
5424 }
5425
5426 tcpcheck->comment = strdup(args[cur_arg + 1]);
5427
5428 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005429 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5430 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005431 }
5432 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005433 const char *ptr_arg;
5434 int cur_arg;
5435 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005436
5437 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005438 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5439 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5440 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5441 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5442 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005443
Willy Tarreau5581c272015-05-13 12:24:53 +02005444 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5445 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005446 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5447 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005448 err_code |= ERR_ALERT | ERR_FATAL;
5449 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005450 }
5451
5452 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005453 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005454 tcpcheck->action = TCPCHK_ACT_CONNECT;
5455
5456 /* parsing each parameters to fill up the rule */
5457 while (*(ptr_arg = args[cur_arg])) {
5458 /* tcp port */
5459 if (strcmp(args[cur_arg], "port") == 0) {
5460 if ( (atol(args[cur_arg + 1]) > 65535) ||
5461 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005462 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5463 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005464 err_code |= ERR_ALERT | ERR_FATAL;
5465 goto out;
5466 }
5467 tcpcheck->port = atol(args[cur_arg + 1]);
5468 cur_arg += 2;
5469 }
5470 /* send proxy protocol */
5471 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5472 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5473 cur_arg++;
5474 }
5475#ifdef USE_OPENSSL
5476 else if (strcmp(args[cur_arg], "ssl") == 0) {
5477 curproxy->options |= PR_O_TCPCHK_SSL;
5478 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5479 cur_arg++;
5480 }
5481#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005482 /* comment for this tcpcheck line */
5483 else if (strcmp(args[cur_arg], "comment") == 0) {
5484 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005485 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5486 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005487 err_code |= ERR_ALERT | ERR_FATAL;
5488 goto out;
5489 }
5490 tcpcheck->comment = strdup(args[cur_arg + 1]);
5491 cur_arg += 2;
5492 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005493 else {
5494#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005495 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 +01005496#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005497 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 +01005498#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005499 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005500 err_code |= ERR_ALERT | ERR_FATAL;
5501 goto out;
5502 }
5503
5504 }
5505
5506 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5507 }
5508 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005509 if (! *(args[2]) ) {
5510 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005511 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5512 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005513 err_code |= ERR_ALERT | ERR_FATAL;
5514 goto out;
5515 } else {
5516 struct tcpcheck_rule *tcpcheck;
5517
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005518 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005519
5520 tcpcheck->action = TCPCHK_ACT_SEND;
5521 tcpcheck->string_len = strlen(args[2]);
5522 tcpcheck->string = strdup(args[2]);
5523 tcpcheck->expect_regex = NULL;
5524
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005525 /* comment for this tcpcheck line */
5526 if (strcmp(args[3], "comment") == 0) {
5527 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005528 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5529 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005530 err_code |= ERR_ALERT | ERR_FATAL;
5531 goto out;
5532 }
5533 tcpcheck->comment = strdup(args[4]);
5534 }
5535
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005536 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5537 }
5538 }
5539 else if (strcmp(args[1], "send-binary") == 0) {
5540 if (! *(args[2]) ) {
5541 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005542 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5543 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005544 err_code |= ERR_ALERT | ERR_FATAL;
5545 goto out;
5546 } else {
5547 struct tcpcheck_rule *tcpcheck;
5548 char *err = NULL;
5549
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005550 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005551
5552 tcpcheck->action = TCPCHK_ACT_SEND;
5553 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005554 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5555 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005556 err_code |= ERR_ALERT | ERR_FATAL;
5557 goto out;
5558 }
5559 tcpcheck->expect_regex = NULL;
5560
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005561 /* comment for this tcpcheck line */
5562 if (strcmp(args[3], "comment") == 0) {
5563 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005564 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5565 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005566 err_code |= ERR_ALERT | ERR_FATAL;
5567 goto out;
5568 }
5569 tcpcheck->comment = strdup(args[4]);
5570 }
5571
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005572 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5573 }
5574 }
5575 else if (strcmp(args[1], "expect") == 0) {
5576 const char *ptr_arg;
5577 int cur_arg;
5578 int inverse = 0;
5579
5580 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005581 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005582 err_code |= ERR_ALERT | ERR_FATAL;
5583 goto out;
5584 }
5585
5586 cur_arg = 2;
5587 /* consider exclamation marks, sole or at the beginning of a word */
5588 while (*(ptr_arg = args[cur_arg])) {
5589 while (*ptr_arg == '!') {
5590 inverse = !inverse;
5591 ptr_arg++;
5592 }
5593 if (*ptr_arg)
5594 break;
5595 cur_arg++;
5596 }
5597 /* now ptr_arg points to the beginning of a word past any possible
5598 * exclamation mark, and cur_arg is the argument which holds this word.
5599 */
5600 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005601 struct tcpcheck_rule *tcpcheck;
5602 char *err = NULL;
5603
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005604 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005605 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5606 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005607 err_code |= ERR_ALERT | ERR_FATAL;
5608 goto out;
5609 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005610
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005611 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005612
5613 tcpcheck->action = TCPCHK_ACT_EXPECT;
5614 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005615 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5616 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005617 err_code |= ERR_ALERT | ERR_FATAL;
5618 goto out;
5619 }
5620 tcpcheck->expect_regex = NULL;
5621 tcpcheck->inverse = inverse;
5622
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005623 /* tcpcheck comment */
5624 cur_arg += 2;
5625 if (strcmp(args[cur_arg], "comment") == 0) {
5626 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005627 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5628 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005629 err_code |= ERR_ALERT | ERR_FATAL;
5630 goto out;
5631 }
5632 tcpcheck->comment = strdup(args[cur_arg + 1]);
5633 }
5634
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005635 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5636 }
5637 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005638 struct tcpcheck_rule *tcpcheck;
5639
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005640 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005641 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5642 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005643 err_code |= ERR_ALERT | ERR_FATAL;
5644 goto out;
5645 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005646
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005647 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005648
5649 tcpcheck->action = TCPCHK_ACT_EXPECT;
5650 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5651 tcpcheck->string = strdup(args[cur_arg + 1]);
5652 tcpcheck->expect_regex = NULL;
5653 tcpcheck->inverse = inverse;
5654
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005655 /* tcpcheck comment */
5656 cur_arg += 2;
5657 if (strcmp(args[cur_arg], "comment") == 0) {
5658 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005659 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5660 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005661 err_code |= ERR_ALERT | ERR_FATAL;
5662 goto out;
5663 }
5664 tcpcheck->comment = strdup(args[cur_arg + 1]);
5665 }
5666
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005667 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5668 }
5669 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005670 struct tcpcheck_rule *tcpcheck;
5671
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005672 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005673 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5674 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005675 err_code |= ERR_ALERT | ERR_FATAL;
5676 goto out;
5677 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005678
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005679 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005680
5681 tcpcheck->action = TCPCHK_ACT_EXPECT;
5682 tcpcheck->string_len = 0;
5683 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005684 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5685 error = NULL;
5686 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005687 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5688 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005689 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005690 err_code |= ERR_ALERT | ERR_FATAL;
5691 goto out;
5692 }
5693 tcpcheck->inverse = inverse;
5694
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005695 /* tcpcheck comment */
5696 cur_arg += 2;
5697 if (strcmp(args[cur_arg], "comment") == 0) {
5698 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005699 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5700 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005701 err_code |= ERR_ALERT | ERR_FATAL;
5702 goto out;
5703 }
5704 tcpcheck->comment = strdup(args[cur_arg + 1]);
5705 }
5706
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005707 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5708 }
5709 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005710 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5711 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005712 err_code |= ERR_ALERT | ERR_FATAL;
5713 goto out;
5714 }
5715 }
5716 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005717 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 +02005718 err_code |= ERR_ALERT | ERR_FATAL;
5719 goto out;
5720 }
5721 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005722 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005723 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005724 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005725 err_code |= ERR_ALERT | ERR_FATAL;
5726 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005727 }
5728
Willy Tarreaub80c2302007-11-30 20:51:32 +01005729 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005730 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005731
5732 if (strcmp(args[1], "fail") == 0) {
5733 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005734 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005735 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5736 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005737 err_code |= ERR_ALERT | ERR_FATAL;
5738 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005739 }
5740
Willy Tarreau721d8e02017-12-01 18:25:08 +01005741 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005742 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005743 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5744 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005745 err_code |= ERR_ALERT | ERR_FATAL;
5746 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005747 }
5748 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5749 }
5750 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005751 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005752 err_code |= ERR_ALERT | ERR_FATAL;
5753 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005754 }
5755 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005756#ifdef TPROXY
5757 else if (!strcmp(args[0], "transparent")) {
5758 /* enable transparent proxy connections */
5759 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005760 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5761 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005762 }
5763#endif
5764 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005765 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005766 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005767
Willy Tarreaubaaee002006-06-26 02:48:02 +02005768 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005769 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005770 err_code |= ERR_ALERT | ERR_FATAL;
5771 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005772 }
5773 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005774 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5775 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005776 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005777 else if (!strcmp(args[0], "backlog")) { /* backlog */
5778 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005779 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005780
5781 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005782 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005783 err_code |= ERR_ALERT | ERR_FATAL;
5784 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005785 }
5786 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005787 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5788 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005789 }
Willy Tarreau86034312006-12-29 00:10:33 +01005790 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005791 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005792 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005793
Willy Tarreau86034312006-12-29 00:10:33 +01005794 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005795 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005796 err_code |= ERR_ALERT | ERR_FATAL;
5797 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005798 }
5799 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005800 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5801 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005802 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005803 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5804 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005805 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005806 err_code |= ERR_ALERT | ERR_FATAL;
5807 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005808 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005809 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5810 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005811 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5812 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005813 err_code |= ERR_ALERT | ERR_FATAL;
5814 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005815 }
5816 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005817 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5818 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005819 }
5820 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005821 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005822 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005823 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005824
Willy Tarreaubaaee002006-06-26 02:48:02 +02005825 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005826 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005827 err_code |= ERR_ALERT | ERR_FATAL;
5828 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005829 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005830 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005831 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005832
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005833 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005834 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005835 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005836 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005837 goto out;
5838 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005839
5840 proto = protocol_by_family(sk->ss_family);
5841 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005842 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5843 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005844 err_code |= ERR_ALERT | ERR_FATAL;
5845 goto out;
5846 }
5847
5848 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005849 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5850 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005851 err_code |= ERR_ALERT | ERR_FATAL;
5852 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005853 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005854
5855 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005856 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5857 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005858 err_code |= ERR_ALERT | ERR_FATAL;
5859 goto out;
5860 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005861
William Lallemanddf1425a2015-04-28 20:17:49 +02005862 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5863 goto out;
5864
Willy Tarreaud5191e72010-02-09 20:50:45 +01005865 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005866 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005867 }
5868 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005869 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005870 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005871
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005872 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005873 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005874 err_code |= ERR_ALERT | ERR_FATAL;
5875 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005876 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005877 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005878 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005879 /**
5880 * The syntax for hash-type config element is
5881 * hash-type {map-based|consistent} [[<algo>] avalanche]
5882 *
5883 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5884 */
5885 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005886
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005887 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5888 err_code |= ERR_WARN;
5889
5890 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005891 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
5892 }
5893 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005894 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
5895 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005896 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005897 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 -05005898 err_code |= ERR_ALERT | ERR_FATAL;
5899 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01005900 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005901 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005902 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005903 err_code |= ERR_ALERT | ERR_FATAL;
5904 goto out;
5905 }
Bhaskar98634f02013-10-29 23:30:51 -04005906
5907 /* set the hash function to use */
5908 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005909 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04005910 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005911
5912 /* if consistent with no argument, then avalanche modifier is also applied */
5913 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
5914 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04005915 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005916 /* set the hash function */
5917 if (!strcmp(args[2], "sdbm")) {
5918 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
5919 }
5920 else if (!strcmp(args[2], "djb2")) {
5921 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01005922 }
5923 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01005924 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005925 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01005926 else if (!strcmp(args[2], "crc32")) {
5927 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
5928 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005929 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005930 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 -05005931 err_code |= ERR_ALERT | ERR_FATAL;
5932 goto out;
5933 }
5934
5935 /* set the hash modifier */
5936 if (!strcmp(args[3], "avalanche")) {
5937 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
5938 }
5939 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005940 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 -05005941 err_code |= ERR_ALERT | ERR_FATAL;
5942 goto out;
5943 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01005944 }
William Lallemanda73203e2012-03-12 12:48:57 +01005945 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04005946 else if (strcmp(args[0], "hash-balance-factor") == 0) {
5947 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005948 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04005949 err_code |= ERR_ALERT | ERR_FATAL;
5950 goto out;
5951 }
5952 curproxy->lbprm.chash.balance_factor = atol(args[1]);
5953 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005954 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 -04005955 err_code |= ERR_ALERT | ERR_FATAL;
5956 goto out;
5957 }
5958 }
William Lallemanda73203e2012-03-12 12:48:57 +01005959 else if (strcmp(args[0], "unique-id-format") == 0) {
5960 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005961 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01005962 err_code |= ERR_ALERT | ERR_FATAL;
5963 goto out;
5964 }
William Lallemand3203ff42012-11-11 17:30:56 +01005965 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005966 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 +01005967 err_code |= ERR_ALERT | ERR_FATAL;
5968 goto out;
5969 }
Willy Tarreau62a61232013-04-12 18:13:46 +02005970 free(curproxy->conf.uniqueid_format_string);
5971 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02005972
Willy Tarreau62a61232013-04-12 18:13:46 +02005973 free(curproxy->conf.uif_file);
5974 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
5975 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01005976 }
William Lallemanda73203e2012-03-12 12:48:57 +01005977
5978 else if (strcmp(args[0], "unique-id-header") == 0) {
5979 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005980 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01005981 err_code |= ERR_ALERT | ERR_FATAL;
5982 goto out;
5983 }
5984 free(curproxy->header_unique_id);
5985 curproxy->header_unique_id = strdup(args[1]);
5986 }
5987
William Lallemand723b73a2012-02-08 16:37:49 +01005988 else if (strcmp(args[0], "log-format") == 0) {
5989 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005990 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01005991 err_code |= ERR_ALERT | ERR_FATAL;
5992 goto out;
5993 }
William Lallemand3203ff42012-11-11 17:30:56 +01005994 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005995 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 +01005996 err_code |= ERR_ALERT | ERR_FATAL;
5997 goto out;
5998 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02005999 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6000 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006001
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006002 if (curproxy->conf.logformat_string == default_http_log_format)
6003 oldlogformat = "option httplog";
6004 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6005 oldlogformat = "option tcplog";
6006 else if (curproxy->conf.logformat_string == clf_http_log_format)
6007 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006008 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6009 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006010 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006011 if (curproxy->conf.logformat_string != default_http_log_format &&
6012 curproxy->conf.logformat_string != default_tcp_log_format &&
6013 curproxy->conf.logformat_string != clf_http_log_format)
6014 free(curproxy->conf.logformat_string);
6015 curproxy->conf.logformat_string = strdup(args[1]);
6016
6017 free(curproxy->conf.lfs_file);
6018 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6019 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006020
6021 /* get a chance to improve log-format error reporting by
6022 * reporting the correct line-number when possible.
6023 */
6024 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006025 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6026 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006027 err_code |= ERR_WARN;
6028 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006029 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006030 else if (!strcmp(args[0], "log-format-sd")) {
6031 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006032 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006033 err_code |= ERR_ALERT | ERR_FATAL;
6034 goto out;
6035 }
6036 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006037 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 +02006038 err_code |= ERR_ALERT | ERR_FATAL;
6039 goto out;
6040 }
6041
6042 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6043 free(curproxy->conf.logformat_sd_string);
6044 curproxy->conf.logformat_sd_string = strdup(args[1]);
6045
6046 free(curproxy->conf.lfsd_file);
6047 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6048 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6049
6050 /* get a chance to improve log-format-sd error reporting by
6051 * reporting the correct line-number when possible.
6052 */
6053 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006054 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6055 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006056 err_code |= ERR_WARN;
6057 }
6058 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006059 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6060 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006061 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 +01006062 err_code |= ERR_ALERT | ERR_FATAL;
6063 goto out;
6064 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006065 chunk_destroy(&curproxy->log_tag);
6066 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006067 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006068 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6069 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6070 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006071 err_code |= ERR_ALERT | ERR_FATAL;
6072 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006073 }
6074 }
6075 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006076 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006077 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006078 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006079 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006080
Willy Tarreau977b8e42006-12-29 14:19:17 +01006081 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006082 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006083
Willy Tarreaubaaee002006-06-26 02:48:02 +02006084 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006085 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6086 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006087 err_code |= ERR_ALERT | ERR_FATAL;
6088 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006089 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006090
6091 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006092 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6093 free(curproxy->conn_src.iface_name);
6094 curproxy->conn_src.iface_name = NULL;
6095 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006096
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006097 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006098 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006099 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6100 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006101 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006102 goto out;
6103 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006104
6105 proto = protocol_by_family(sk->ss_family);
6106 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006107 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6108 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006109 err_code |= ERR_ALERT | ERR_FATAL;
6110 goto out;
6111 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006112
6113 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006114 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6115 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006116 err_code |= ERR_ALERT | ERR_FATAL;
6117 goto out;
6118 }
6119
Willy Tarreauef9a3602012-12-08 22:29:20 +01006120 curproxy->conn_src.source_addr = *sk;
6121 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006122
6123 cur_arg = 2;
6124 while (*(args[cur_arg])) {
6125 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006126#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006127 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006128 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6129 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006130 err_code |= ERR_ALERT | ERR_FATAL;
6131 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006132 }
6133
6134 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006135 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6136 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006137 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006138 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6139 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006140 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6141 char *name, *end;
6142
6143 name = args[cur_arg+1] + 7;
6144 while (isspace(*name))
6145 name++;
6146
6147 end = name;
6148 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6149 end++;
6150
Willy Tarreauef9a3602012-12-08 22:29:20 +01006151 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6152 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6153 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6154 curproxy->conn_src.bind_hdr_len = end - name;
6155 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6156 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6157 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006158
6159 /* now look for an occurrence number */
6160 while (isspace(*end))
6161 end++;
6162 if (*end == ',') {
6163 end++;
6164 name = end;
6165 if (*end == '-')
6166 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006167 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006168 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006169 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006170 }
6171
Willy Tarreauef9a3602012-12-08 22:29:20 +01006172 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006173 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6174 " occurrences values smaller than %d.\n",
6175 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006176 err_code |= ERR_ALERT | ERR_FATAL;
6177 goto out;
6178 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006179 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006180 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006181
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006182 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006183 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006184 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6185 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006186 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006187 goto out;
6188 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006189
6190 proto = protocol_by_family(sk->ss_family);
6191 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006192 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6193 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006194 err_code |= ERR_ALERT | ERR_FATAL;
6195 goto out;
6196 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006197
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006198 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006199 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6200 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006201 err_code |= ERR_ALERT | ERR_FATAL;
6202 goto out;
6203 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006204 curproxy->conn_src.tproxy_addr = *sk;
6205 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006206 }
6207 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006208#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006209 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6210 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006211 err_code |= ERR_ALERT | ERR_FATAL;
6212 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006213#endif
6214 cur_arg += 2;
6215 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006216 }
6217
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006218 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6219#ifdef SO_BINDTODEVICE
6220 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006221 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6222 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006223 err_code |= ERR_ALERT | ERR_FATAL;
6224 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006225 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006226 free(curproxy->conn_src.iface_name);
6227 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6228 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006229 global.last_checks |= LSTCHK_NETADM;
6230#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006231 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6232 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006233 err_code |= ERR_ALERT | ERR_FATAL;
6234 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006235#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006236 cur_arg += 2;
6237 continue;
6238 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006239 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6240 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006241 err_code |= ERR_ALERT | ERR_FATAL;
6242 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006243 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006244 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006245 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006246 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6247 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006248 err_code |= ERR_ALERT | ERR_FATAL;
6249 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006250 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006251 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006252 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006253 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6254 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006255 err_code |= ERR_ALERT | ERR_FATAL;
6256 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006257 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006258
6259 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006260 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006261 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006262 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006263 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006264 }
6265 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006266 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006267 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006268 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006269 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006270 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006271 }
6272 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006273 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006274 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006275 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006276 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006277 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006278 }
6279 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006280 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006281 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006282 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006283 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006284 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006285 }
6286 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006287 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006288 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006289 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006290 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006291 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006292 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006293 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006294 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006295 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006296 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006297 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006298 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006299 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006300 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006301 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006302 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6303 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006304 err_code |= ERR_ALERT | ERR_FATAL;
6305 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006306 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006307
6308 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006309 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006310 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006311 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006312 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006313 }
6314 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006315 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006316 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006317 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006318 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006319 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006320 }
6321 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006322 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006323 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006324 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006325 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006326 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006327 }
6328 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006329 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006330 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006331 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006332 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006333 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006334 }
6335 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006336 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006337 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006338 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006339 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006340 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006341 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006342 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006343 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006344 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006345 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006346 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006347 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006348 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006349 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006350 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006351
Willy Tarreaubaaee002006-06-26 02:48:02 +02006352 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006353 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006354 err_code |= ERR_ALERT | ERR_FATAL;
6355 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006356 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006357 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006358 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006359
Willy Tarreaubaaee002006-06-26 02:48:02 +02006360 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006361 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006362 err_code |= ERR_ALERT | ERR_FATAL;
6363 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006364 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006365
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006366 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006367 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006368 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6369 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006370 err_code |= ERR_ALERT | ERR_FATAL;
6371 goto out;
6372 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006373 err_code |= warnif_cond_conflicts(cond,
6374 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6375 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006376 }
6377 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006378 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6379 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006380 err_code |= ERR_ALERT | ERR_FATAL;
6381 goto out;
6382 }
6383
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006384 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006385 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006386 wl->s = strdup(args[1]);
6387 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006388 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006389 }
6390 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006391 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006392 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6393 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006394 err_code |= ERR_ALERT | ERR_FATAL;
6395 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006396 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006397
Willy Tarreauade5ec42010-01-28 19:33:49 +01006398 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006399 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006400 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006401 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006402 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006403 }
6404 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006405 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006406 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006407 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006408 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006409 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006410 }
6411 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006412 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006413 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006414 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006415 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006416 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006417 }
6418 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006419 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006420 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6421 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006422 err_code |= ERR_ALERT | ERR_FATAL;
6423 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006424 }
6425
Willy Tarreauade5ec42010-01-28 19:33:49 +01006426 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006427 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006428 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006429 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006430 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006431 }
6432 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006433 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006434 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006435 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006436 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006437 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006438 }
6439 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006440 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006441 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006442 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006443 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006444 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006445 }
6446 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006447 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006448
Willy Tarreaubaaee002006-06-26 02:48:02 +02006449 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006450 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006451 err_code |= ERR_ALERT | ERR_FATAL;
6452 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006453 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006454 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006455 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006456
Willy Tarreaubaaee002006-06-26 02:48:02 +02006457 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006458 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006459 err_code |= ERR_ALERT | ERR_FATAL;
6460 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006461 }
6462
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006463 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006464 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006465 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6466 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006467 err_code |= ERR_ALERT | ERR_FATAL;
6468 goto out;
6469 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006470 err_code |= warnif_cond_conflicts(cond,
6471 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6472 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006473 }
6474 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006475 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6476 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006477 err_code |= ERR_ALERT | ERR_FATAL;
6478 goto out;
6479 }
6480
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006481 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006482 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006483 wl->s = strdup(args[1]);
6484 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006485 }
6486 else if (!strcmp(args[0], "errorloc") ||
6487 !strcmp(args[0], "errorloc302") ||
6488 !strcmp(args[0], "errorloc303")) { /* error location */
6489 int errnum, errlen;
6490 char *err;
6491
Willy Tarreau977b8e42006-12-29 14:19:17 +01006492 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006493 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006494
Willy Tarreaubaaee002006-06-26 02:48:02 +02006495 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006496 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 +02006497 err_code |= ERR_ALERT | ERR_FATAL;
6498 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006499 }
6500
6501 errnum = atol(args[1]);
6502 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006503 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6504 err = malloc(errlen);
6505 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006506 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006507 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6508 err = malloc(errlen);
6509 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006510 }
6511
Willy Tarreau0f772532006-12-23 20:51:41 +01006512 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6513 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006514 chunk_destroy(&curproxy->errmsg[rc]);
6515 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006516 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006517 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006518 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006519
6520 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006521 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6522 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006523 free(err);
6524 }
6525 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006526 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6527 int errnum, errlen, fd;
6528 char *err;
6529 struct stat stat;
6530
6531 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006532 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006533
6534 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006535 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 +02006536 err_code |= ERR_ALERT | ERR_FATAL;
6537 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006538 }
6539
6540 fd = open(args[2], O_RDONLY);
6541 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006542 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6543 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006544 if (fd >= 0)
6545 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006546 err_code |= ERR_ALERT | ERR_FATAL;
6547 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006548 }
6549
Willy Tarreau27a674e2009-08-17 07:23:33 +02006550 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006551 errlen = stat.st_size;
6552 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006553 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6554 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006555 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006556 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006557 }
6558
6559 err = malloc(errlen); /* malloc() must succeed during parsing */
6560 errnum = read(fd, err, errlen);
6561 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006562 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6563 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006564 close(fd);
6565 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006566 err_code |= ERR_ALERT | ERR_FATAL;
6567 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006568 }
6569 close(fd);
6570
6571 errnum = atol(args[1]);
6572 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6573 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006574 chunk_destroy(&curproxy->errmsg[rc]);
6575 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006576 break;
6577 }
6578 }
6579
6580 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006581 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6582 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006583 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006584 free(err);
6585 }
6586 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006587 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006588 struct cfg_kw_list *kwl;
6589 int index;
6590
6591 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6592 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6593 if (kwl->kw[index].section != CFG_LISTEN)
6594 continue;
6595 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6596 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006597 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006598 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006599 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006600 err_code |= ERR_ALERT | ERR_FATAL;
6601 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006602 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006603 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006604 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006605 err_code |= ERR_WARN;
6606 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006607 }
Willy Tarreau93893792009-07-23 13:19:11 +02006608 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006609 }
6610 }
6611 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006612
Christopher Faulet767a84b2017-11-24 16:50:31 +01006613 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006614 err_code |= ERR_ALERT | ERR_FATAL;
6615 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006616 }
Willy Tarreau93893792009-07-23 13:19:11 +02006617 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006618 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006619 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006620}
6621
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006622int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006623cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6624{
6625#ifdef CONFIG_HAP_NS
6626 const char *err;
6627 const char *item = args[0];
6628
6629 if (!strcmp(item, "namespace_list")) {
6630 return 0;
6631 }
6632 else if (!strcmp(item, "namespace")) {
6633 size_t idx = 1;
6634 const char *current;
6635 while (*(current = args[idx++])) {
6636 err = invalid_char(current);
6637 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006638 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6639 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006640 return ERR_ALERT | ERR_FATAL;
6641 }
6642
6643 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006644 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6645 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006646 return ERR_ALERT | ERR_FATAL;
6647 }
6648 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006649 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6650 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006651 return ERR_ALERT | ERR_FATAL;
6652 }
6653 }
6654 }
6655
6656 return 0;
6657#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006658 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6659 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006660 return ERR_ALERT | ERR_FATAL;
6661#endif
6662}
6663
6664int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006665cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6666{
6667
6668 int err_code = 0;
6669 const char *err;
6670
6671 if (!strcmp(args[0], "userlist")) { /* new userlist */
6672 struct userlist *newul;
6673
6674 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006675 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6676 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006677 err_code |= ERR_ALERT | ERR_FATAL;
6678 goto out;
6679 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006680 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6681 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006682
6683 err = invalid_char(args[1]);
6684 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006685 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6686 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006687 err_code |= ERR_ALERT | ERR_FATAL;
6688 goto out;
6689 }
6690
6691 for (newul = userlist; newul; newul = newul->next)
6692 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006693 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6694 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006695 err_code |= ERR_WARN;
6696 goto out;
6697 }
6698
Vincent Bernat02779b62016-04-03 13:48:43 +02006699 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006700 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006701 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006702 err_code |= ERR_ALERT | ERR_ABORT;
6703 goto out;
6704 }
6705
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006706 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006707 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006708 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006709 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006710 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006711 goto out;
6712 }
6713
6714 newul->next = userlist;
6715 userlist = newul;
6716
6717 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006718 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006719 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006720 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006721
6722 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006723 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6724 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006725 err_code |= ERR_ALERT | ERR_FATAL;
6726 goto out;
6727 }
6728
6729 err = invalid_char(args[1]);
6730 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006731 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6732 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006733 err_code |= ERR_ALERT | ERR_FATAL;
6734 goto out;
6735 }
6736
William Lallemand4ac9f542015-05-28 18:03:51 +02006737 if (!userlist)
6738 goto out;
6739
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006740 for (ag = userlist->groups; ag; ag = ag->next)
6741 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006742 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6743 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006744 err_code |= ERR_ALERT;
6745 goto out;
6746 }
6747
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006748 ag = calloc(1, sizeof(*ag));
6749 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006750 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006751 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006752 goto out;
6753 }
6754
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006755 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006756 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006757 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006758 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006759 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006760 goto out;
6761 }
6762
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006763 cur_arg = 2;
6764
6765 while (*args[cur_arg]) {
6766 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006767 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006768 cur_arg += 2;
6769 continue;
6770 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006771 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6772 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006773 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006774 free(ag->groupusers);
6775 free(ag->name);
6776 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006777 goto out;
6778 }
6779 }
6780
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006781 ag->next = userlist->groups;
6782 userlist->groups = ag;
6783
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006784 } else if (!strcmp(args[0], "user")) { /* new user */
6785 struct auth_users *newuser;
6786 int cur_arg;
6787
6788 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006789 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6790 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006791 err_code |= ERR_ALERT | ERR_FATAL;
6792 goto out;
6793 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006794 if (!userlist)
6795 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006796
6797 for (newuser = userlist->users; newuser; newuser = newuser->next)
6798 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006799 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6800 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006801 err_code |= ERR_ALERT;
6802 goto out;
6803 }
6804
Vincent Bernat02779b62016-04-03 13:48:43 +02006805 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006806 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006807 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006808 err_code |= ERR_ALERT | ERR_ABORT;
6809 goto out;
6810 }
6811
6812 newuser->user = strdup(args[1]);
6813
6814 newuser->next = userlist->users;
6815 userlist->users = newuser;
6816
6817 cur_arg = 2;
6818
6819 while (*args[cur_arg]) {
6820 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006821#ifdef CONFIG_HAP_CRYPT
6822 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006823 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6824 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006825 err_code |= ERR_ALERT | ERR_FATAL;
6826 goto out;
6827 }
6828#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006829 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6830 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006831 err_code |= ERR_ALERT;
6832#endif
6833 newuser->pass = strdup(args[cur_arg + 1]);
6834 cur_arg += 2;
6835 continue;
6836 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6837 newuser->pass = strdup(args[cur_arg + 1]);
6838 newuser->flags |= AU_O_INSECURE;
6839 cur_arg += 2;
6840 continue;
6841 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006842 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006843 cur_arg += 2;
6844 continue;
6845 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006846 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6847 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006848 err_code |= ERR_ALERT | ERR_FATAL;
6849 goto out;
6850 }
6851 }
6852 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006853 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 +01006854 err_code |= ERR_ALERT | ERR_FATAL;
6855 }
6856
6857out:
6858 return err_code;
6859}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006860
Christopher Faulet79bdef32016-11-04 22:36:15 +01006861int
6862cfg_parse_scope(const char *file, int linenum, char *line)
6863{
6864 char *beg, *end, *scope = NULL;
6865 int err_code = 0;
6866 const char *err;
6867
6868 beg = line + 1;
6869 end = strchr(beg, ']');
6870
6871 /* Detect end of scope declaration */
6872 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006873 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
6874 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006875 err_code |= ERR_ALERT | ERR_FATAL;
6876 goto out;
6877 }
6878
6879 /* Get scope name and check its validity */
6880 scope = my_strndup(beg, end-beg);
6881 err = invalid_char(scope);
6882 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006883 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
6884 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006885 err_code |= ERR_ALERT | ERR_ABORT;
6886 goto out;
6887 }
6888
6889 /* Be sure to have a scope declaration alone on its line */
6890 line = end+1;
6891 while (isspace((unsigned char)*line))
6892 line++;
6893 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006894 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
6895 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006896 err_code |= ERR_ALERT | ERR_ABORT;
6897 goto out;
6898 }
6899
6900 /* We have a valid scope declaration, save it */
6901 free(cfg_scope);
6902 cfg_scope = scope;
6903 scope = NULL;
6904
6905 out:
6906 free(scope);
6907 return err_code;
6908}
6909
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01006910int
6911cfg_parse_track_sc_num(unsigned int *track_sc_num,
6912 const char *arg, const char *end, char **errmsg)
6913{
6914 const char *p;
6915 unsigned int num;
6916
6917 p = arg;
6918 num = read_uint64(&arg, end);
6919
6920 if (arg != end) {
6921 memprintf(errmsg, "Wrong track-sc number '%s'", p);
6922 return -1;
6923 }
6924
6925 if (num >= MAX_SESS_STKCTR) {
6926 memprintf(errmsg, "%u track-sc number exceeding "
6927 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
6928 return -1;
6929 }
6930
6931 *track_sc_num = num;
6932 return 0;
6933}
6934
Willy Tarreaubaaee002006-06-26 02:48:02 +02006935/*
6936 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02006937 * Returns the error code, 0 if OK, or any combination of :
6938 * - ERR_ABORT: must abort ASAP
6939 * - ERR_FATAL: we can continue parsing but not start the service
6940 * - ERR_WARN: a warning has been emitted
6941 * - ERR_ALERT: an alert has been emitted
6942 * Only the two first ones can stop processing, the two others are just
6943 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02006944 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02006945int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02006946{
William Lallemand64e84512015-05-12 14:25:37 +02006947 char *thisline;
6948 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006949 FILE *f;
6950 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02006951 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02006952 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01006953 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02006954 int readbytes = 0;
6955
6956 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006957 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02006958 return -1;
6959 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01006960
David Carlier97880bb2016-04-08 10:35:26 +01006961 if ((f=fopen(file,"r")) == NULL) {
6962 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006963 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01006964 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006965
William Lallemandb2f07452015-05-12 14:27:13 +02006966next_line:
William Lallemand64e84512015-05-12 14:25:37 +02006967 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02006968 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006969 char *end;
6970 char *args[MAX_LINE_ARGS + 1];
6971 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02006972 int dquote = 0; /* double quote */
6973 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006974
Willy Tarreaubaaee002006-06-26 02:48:02 +02006975 linenum++;
6976
6977 end = line + strlen(line);
6978
William Lallemand64e84512015-05-12 14:25:37 +02006979 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006980 /* Check if we reached the limit and the last char is not \n.
6981 * Watch out for the last line without the terminating '\n'!
6982 */
William Lallemand64e84512015-05-12 14:25:37 +02006983 char *newline;
6984 int newlinesize = linesize * 2;
6985
6986 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
6987 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006988 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
6989 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02006990 err_code |= ERR_ALERT | ERR_FATAL;
6991 continue;
6992 }
6993
6994 readbytes = linesize - 1;
6995 linesize = newlinesize;
6996 thisline = newline;
6997 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006998 }
6999
William Lallemand64e84512015-05-12 14:25:37 +02007000 readbytes = 0;
7001
Willy Tarreaubaaee002006-06-26 02:48:02 +02007002 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007003 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007004 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007005
Christopher Faulet79bdef32016-11-04 22:36:15 +01007006
7007 if (*line == '[') {/* This is the begining if a scope */
7008 err_code |= cfg_parse_scope(file, linenum, line);
7009 goto next_line;
7010 }
7011
Willy Tarreaubaaee002006-06-26 02:48:02 +02007012 arg = 0;
7013 args[arg] = line;
7014
7015 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007016 if (*line == '"' && !squote) { /* double quote outside single quotes */
7017 if (dquote)
7018 dquote = 0;
7019 else
7020 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007021 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007022 end--;
7023 }
7024 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7025 if (squote)
7026 squote = 0;
7027 else
7028 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007029 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007030 end--;
7031 }
7032 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007033 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7034 * C equivalent value. Other combinations left unchanged (eg: \1).
7035 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007036 int skip = 0;
7037 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7038 *line = line[1];
7039 skip = 1;
7040 }
7041 else if (line[1] == 'r') {
7042 *line = '\r';
7043 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007044 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007045 else if (line[1] == 'n') {
7046 *line = '\n';
7047 skip = 1;
7048 }
7049 else if (line[1] == 't') {
7050 *line = '\t';
7051 skip = 1;
7052 }
7053 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007054 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007055 unsigned char hex1, hex2;
7056 hex1 = toupper(line[2]) - '0';
7057 hex2 = toupper(line[3]) - '0';
7058 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7059 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7060 *line = (hex1<<4) + hex2;
7061 skip = 3;
7062 }
7063 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007064 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007065 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007066 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007067 } else if (line[1] == '"') {
7068 *line = '"';
7069 skip = 1;
7070 } else if (line[1] == '\'') {
7071 *line = '\'';
7072 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007073 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7074 *line = '$';
7075 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007076 }
7077 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007078 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007079 end -= skip;
7080 }
7081 line++;
7082 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007083 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007084 /* end of string, end of loop */
7085 *line = 0;
7086 break;
7087 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007088 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007089 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007090 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007091 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007092 line++;
7093 args[++arg] = line;
7094 }
William Lallemandb2f07452015-05-12 14:27:13 +02007095 else if (dquote && *line == '$') {
7096 /* environment variables are evaluated inside double quotes */
7097 char *var_beg;
7098 char *var_end;
7099 char save_char;
7100 char *value;
7101 int val_len;
7102 int newlinesize;
7103 int braces = 0;
7104
7105 var_beg = line + 1;
7106 var_end = var_beg;
7107
7108 if (*var_beg == '{') {
7109 var_beg++;
7110 var_end++;
7111 braces = 1;
7112 }
7113
7114 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007115 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 +02007116 err_code |= ERR_ALERT | ERR_FATAL;
7117 goto next_line; /* skip current line */
7118 }
7119
7120 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7121 var_end++;
7122
7123 save_char = *var_end;
7124 *var_end = '\0';
7125 value = getenv(var_beg);
7126 *var_end = save_char;
7127 val_len = value ? strlen(value) : 0;
7128
7129 if (braces) {
7130 if (*var_end == '}') {
7131 var_end++;
7132 braces = 0;
7133 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007134 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007135 err_code |= ERR_ALERT | ERR_FATAL;
7136 goto next_line; /* skip current line */
7137 }
7138 }
7139
7140 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7141
7142 /* if not enough space in thisline */
7143 if (newlinesize > linesize) {
7144 char *newline;
7145
7146 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7147 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007148 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007149 err_code |= ERR_ALERT | ERR_FATAL;
7150 goto next_line; /* slip current line */
7151 }
7152 /* recompute pointers if realloc returns a new pointer */
7153 if (newline != thisline) {
7154 int i;
7155 int diff;
7156
7157 for (i = 0; i <= arg; i++) {
7158 diff = args[i] - thisline;
7159 args[i] = newline + diff;
7160 }
7161
7162 diff = var_end - thisline;
7163 var_end = newline + diff;
7164 diff = end - thisline;
7165 end = newline + diff;
7166 diff = line - thisline;
7167 line = newline + diff;
7168 thisline = newline;
7169 }
7170 linesize = newlinesize;
7171 }
7172
7173 /* insert value inside the line */
7174 memmove(line + val_len, var_end, end - var_end + 1);
7175 memcpy(line, value, val_len);
7176 end += val_len - (var_end - line);
7177 line += val_len;
7178 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007179 else {
7180 line++;
7181 }
7182 }
William Lallemandb2f07452015-05-12 14:27:13 +02007183
William Lallemandf9873ba2015-05-05 17:37:14 +02007184 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007185 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007186 err_code |= ERR_ALERT | ERR_FATAL;
7187 }
7188
7189 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007190 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007191 err_code |= ERR_ALERT | ERR_FATAL;
7192 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007193
7194 /* empty line */
7195 if (!**args)
7196 continue;
7197
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007198 if (*line) {
7199 /* we had to stop due to too many args.
7200 * Let's terminate the string, print the offending part then cut the
7201 * last arg.
7202 */
7203 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7204 line++;
7205 *line = '\0';
7206
Christopher Faulet767a84b2017-11-24 16:50:31 +01007207 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7208 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007209 err_code |= ERR_ALERT | ERR_FATAL;
7210 args[arg] = line;
7211 }
7212
Willy Tarreau540abe42007-05-02 20:50:16 +02007213 /* zero out remaining args and ensure that at least one entry
7214 * is zeroed out.
7215 */
7216 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007217 args[arg] = line;
7218 }
7219
Willy Tarreau3842f002009-06-14 11:39:52 +02007220 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007221 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007222 char *tmp;
7223
Willy Tarreau3842f002009-06-14 11:39:52 +02007224 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007225 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007226 for (arg=0; *args[arg+1]; arg++)
7227 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007228 *tmp = '\0'; // fix the next arg to \0
7229 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007230 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007231 else if (!strcmp(args[0], "default")) {
7232 kwm = KWM_DEF;
7233 for (arg=0; *args[arg+1]; arg++)
7234 args[arg] = args[arg+1]; // shift args after inversion
7235 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007236
William Lallemand0f99e342011-10-12 17:50:54 +02007237 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7238 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007239 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007240 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007241 }
7242
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007243 /* detect section start */
7244 list_for_each_entry(ics, &sections, list) {
7245 if (strcmp(args[0], ics->section_name) == 0) {
7246 cursection = ics->section_name;
7247 cs = ics;
7248 break;
7249 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007250 }
7251
William Lallemandd2ff56d2017-10-16 11:06:50 +02007252 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007253 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007254 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007255 } else {
7256 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007257
William Lallemandd2ff56d2017-10-16 11:06:50 +02007258 if (pcs != cs && pcs && pcs->post_section_parser) {
7259 err_code |= pcs->post_section_parser();
7260 if (err_code & ERR_ABORT)
7261 goto err;
7262 }
7263
7264 err_code |= cs->section_parser(file, linenum, args, kwm);
7265 if (err_code & ERR_ABORT)
7266 goto err;
7267 }
7268 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007269 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007270
7271 if (pcs == cs && pcs && pcs->post_section_parser)
7272 err_code |= pcs->post_section_parser();
7273
7274err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007275 free(cfg_scope);
7276 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007277 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007278 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007279 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007280 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007281}
7282
Willy Tarreau64ab6072014-09-16 12:17:36 +02007283/* This function propagates processes from frontend <from> to backend <to> so
7284 * that it is always guaranteed that a backend pointed to by a frontend is
7285 * bound to all of its processes. After that, if the target is a "listen"
7286 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007287 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007288 * checked first to ensure that <to> is already bound to all processes of
7289 * <from>, there is no risk of looping and we ensure to follow the shortest
7290 * path to the destination.
7291 *
7292 * It is possible to set <to> to NULL for the first call so that the function
7293 * takes care of visiting the initial frontend in <from>.
7294 *
7295 * It is important to note that the function relies on the fact that all names
7296 * have already been resolved.
7297 */
7298void propagate_processes(struct proxy *from, struct proxy *to)
7299{
7300 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007301
7302 if (to) {
7303 /* check whether we need to go down */
7304 if (from->bind_proc &&
7305 (from->bind_proc & to->bind_proc) == from->bind_proc)
7306 return;
7307
7308 if (!from->bind_proc && !to->bind_proc)
7309 return;
7310
7311 to->bind_proc = from->bind_proc ?
7312 (to->bind_proc | from->bind_proc) : 0;
7313
7314 /* now propagate down */
7315 from = to;
7316 }
7317
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007318 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007319 return;
7320
Willy Tarreauf6b70012014-12-18 14:00:43 +01007321 if (from->state == PR_STSTOPPED)
7322 return;
7323
Willy Tarreau64ab6072014-09-16 12:17:36 +02007324 /* default_backend */
7325 if (from->defbe.be)
7326 propagate_processes(from, from->defbe.be);
7327
7328 /* use_backend */
7329 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007330 if (rule->dynamic)
7331 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007332 to = rule->be.backend;
7333 propagate_processes(from, to);
7334 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007335}
7336
Willy Tarreaubb925012009-07-23 13:36:36 +02007337/*
7338 * Returns the error code, 0 if OK, or any combination of :
7339 * - ERR_ABORT: must abort ASAP
7340 * - ERR_FATAL: we can continue parsing but not start the service
7341 * - ERR_WARN: a warning has been emitted
7342 * - ERR_ALERT: an alert has been emitted
7343 * Only the two first ones can stop processing, the two others are just
7344 * indicators.
7345 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007346int check_config_validity()
7347{
7348 int cfgerr = 0;
7349 struct proxy *curproxy = NULL;
7350 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007351 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007352 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007353 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007354 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007355 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06007356 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007357
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007358 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007359 /*
7360 * Now, check for the integrity of all that we have collected.
7361 */
7362
7363 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007364 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007365
Willy Tarreau193b8c62012-11-22 00:17:38 +01007366 if (!global.tune.max_http_hdr)
7367 global.tune.max_http_hdr = MAX_HTTP_HDR;
7368
7369 if (!global.tune.cookie_len)
7370 global.tune.cookie_len = CAPTURE_LEN;
7371
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007372 if (!global.tune.requri_len)
7373 global.tune.requri_len = REQURI_LEN;
7374
Willy Tarreaubafbe012017-11-24 17:34:44 +01007375 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007376
Willy Tarreaubafbe012017-11-24 17:34:44 +01007377 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007378
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007379 /* Post initialisation of the users and groups lists. */
7380 err_code = userlist_postinit();
7381 if (err_code != ERR_NONE)
7382 goto out;
7383
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007384 /* first, we will invert the proxy list order */
7385 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007386 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007387 struct proxy *next;
7388
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007389 next = proxies_list->next;
7390 proxies_list->next = curproxy;
7391 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007392 if (!next)
7393 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007394 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007395 }
7396
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007397 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007398 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007399 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007400 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007401 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007402 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007403 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007404 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007405
Willy Tarreau050536d2012-10-04 08:47:34 +02007406 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007407 /* proxy ID not set, use automatic numbering with first
7408 * spare entry starting with next_pxid.
7409 */
7410 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7411 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7412 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007413 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007414 next_pxid++;
7415
Willy Tarreau55ea7572007-06-17 19:56:27 +02007416
Willy Tarreaubaaee002006-06-26 02:48:02 +02007417 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007418 /* ensure we don't keep listeners uselessly bound */
7419 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007420 free((void *)curproxy->table.peers.name);
7421 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007422 continue;
7423 }
7424
Willy Tarreau102df612014-05-07 23:56:38 +02007425 /* Check multi-process mode compatibility for the current proxy */
7426
7427 if (curproxy->bind_proc) {
7428 /* an explicit bind-process was specified, let's check how many
7429 * processes remain.
7430 */
David Carliere6c39412015-07-02 07:00:17 +00007431 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007432
7433 curproxy->bind_proc &= nbits(global.nbproc);
7434 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007435 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 +02007436 curproxy->bind_proc = 1;
7437 }
7438 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007439 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 +02007440 curproxy->bind_proc = 0;
7441 }
7442 }
7443
Willy Tarreau3d209582014-05-09 17:06:11 +02007444 /* check and reduce the bind-proc of each listener */
7445 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7446 unsigned long mask;
7447
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007448 /* HTTP frontends with "h2" as ALPN/NPN will work in
7449 * HTTP/2 and absolutely require buffers 16kB or larger.
7450 */
7451#ifdef USE_OPENSSL
7452 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7453#ifdef OPENSSL_NPN_NEGOTIATED
7454 /* check NPN */
7455 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007456 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",
7457 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007458 cfgerr++;
7459 }
7460#endif
7461#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7462 /* check ALPN */
7463 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007464 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",
7465 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007466 cfgerr++;
7467 }
7468#endif
7469 } /* HTTP && bufsize < 16384 */
7470#endif
7471
Willy Tarreau3d209582014-05-09 17:06:11 +02007472 if (!bind_conf->bind_proc)
7473 continue;
7474
7475 mask = nbits(global.nbproc);
7476 if (curproxy->bind_proc)
7477 mask &= curproxy->bind_proc;
7478 /* mask cannot be null here thanks to the previous checks */
7479
David Carliere6c39412015-07-02 07:00:17 +00007480 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007481 bind_conf->bind_proc &= mask;
7482
7483 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007484 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",
7485 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007486 bind_conf->bind_proc = mask & ~(mask - 1);
7487 }
7488 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007489 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",
7490 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007491 bind_conf->bind_proc = 0;
7492 }
7493 }
7494
Willy Tarreauff01a212009-03-15 13:46:16 +01007495 switch (curproxy->mode) {
7496 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007497 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007498 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007499 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7500 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007501 cfgerr++;
7502 }
7503
7504 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007505 ha_warning("config : servers will be ignored for %s '%s'.\n",
7506 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007507 break;
7508
7509 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007510 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007511 break;
7512
7513 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007514 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007515 break;
7516 }
7517
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007518 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007519 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7520 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007521 err_code |= ERR_WARN;
7522 }
7523
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007524 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007525 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007526 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007527 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7528 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007529 cfgerr++;
7530 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007531#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007532 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007533 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7534 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007535 cfgerr++;
7536 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007537#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007538 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007539 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7540 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007541 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007542 }
7543 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007544 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007545 /* If no LB algo is set in a backend, and we're not in
7546 * transparent mode, dispatch mode nor proxy mode, we
7547 * want to use balance roundrobin by default.
7548 */
7549 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7550 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007551 }
7552 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007553
Willy Tarreau1620ec32011-08-06 17:05:02 +02007554 if (curproxy->options & PR_O_DISPATCH)
7555 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7556 else if (curproxy->options & PR_O_HTTP_PROXY)
7557 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7558 else if (curproxy->options & PR_O_TRANSP)
7559 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007560
Willy Tarreau1620ec32011-08-06 17:05:02 +02007561 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7562 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007563 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7564 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007565 err_code |= ERR_WARN;
7566 curproxy->options &= ~PR_O_DISABLE404;
7567 }
7568 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007569 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7570 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007571 err_code |= ERR_WARN;
7572 curproxy->options &= ~PR_O2_CHK_SNDST;
7573 }
Willy Tarreauef781042010-01-27 11:53:01 +01007574 }
7575
Simon Horman98637e52014-06-20 12:30:16 +09007576 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7577 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007578 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7579 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007580 cfgerr++;
7581 }
7582 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007583 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7584 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007585 cfgerr++;
7586 }
7587 }
7588
Simon Horman64e34162015-02-06 11:11:57 +09007589 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007590 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007591 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7592 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7593 "'email-alert myhostname', or 'email-alert to' "
7594 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7595 "to be present).\n",
7596 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007597 err_code |= ERR_WARN;
7598 free_email_alert(curproxy);
7599 }
7600 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007601 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007602 }
7603
Simon Horman98637e52014-06-20 12:30:16 +09007604 if (curproxy->check_command) {
7605 int clear = 0;
7606 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007607 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7608 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007609 err_code |= ERR_WARN;
7610 clear = 1;
7611 }
7612 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007613 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7614 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007615 cfgerr++;
7616 }
7617 if (clear) {
7618 free(curproxy->check_command);
7619 curproxy->check_command = NULL;
7620 }
7621 }
7622
7623 if (curproxy->check_path) {
7624 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007625 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7626 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007627 err_code |= ERR_WARN;
7628 free(curproxy->check_path);
7629 curproxy->check_path = NULL;
7630 }
7631 }
7632
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007633 /* if a default backend was specified, let's find it */
7634 if (curproxy->defbe.name) {
7635 struct proxy *target;
7636
Willy Tarreauafb39922015-05-26 12:04:09 +02007637 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007638 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007639 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7640 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007641 cfgerr++;
7642 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007643 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7644 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007645 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007646 } else if (target->mode != curproxy->mode &&
7647 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7648
Christopher Faulet767a84b2017-11-24 16:50:31 +01007649 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7650 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7651 curproxy->conf.file, curproxy->conf.line,
7652 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7653 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007654 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007655 } else {
7656 free(curproxy->defbe.name);
7657 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007658 /* Update tot_fe_maxconn for a further fullconn's computation */
7659 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007660 /* Emit a warning if this proxy also has some servers */
7661 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007662 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7663 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007664 err_code |= ERR_WARN;
7665 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007666 }
7667 }
7668
Emeric Brun3f783572017-01-12 11:21:28 +01007669 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7670 /* Case of listen without default backend
7671 * The curproxy will be its own default backend
7672 * so we update tot_fe_maxconn for a further
7673 * fullconn's computation */
7674 curproxy->tot_fe_maxconn += curproxy->maxconn;
7675 }
7676
Willy Tarreau55ea7572007-06-17 19:56:27 +02007677 /* find the target proxy for 'use_backend' rules */
7678 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007679 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007680 struct logformat_node *node;
7681 char *pxname;
7682
7683 /* Try to parse the string as a log format expression. If the result
7684 * of the parsing is only one entry containing a simple string, then
7685 * it's a standard string corresponding to a static rule, thus the
7686 * parsing is cancelled and be.name is restored to be resolved.
7687 */
7688 pxname = rule->be.name;
7689 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007690 curproxy->conf.args.ctx = ARGC_UBK;
7691 curproxy->conf.args.file = rule->file;
7692 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007693 err = NULL;
7694 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007695 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7696 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007697 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007698 cfgerr++;
7699 continue;
7700 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007701 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7702
7703 if (!LIST_ISEMPTY(&rule->be.expr)) {
7704 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7705 rule->dynamic = 1;
7706 free(pxname);
7707 continue;
7708 }
7709 /* simple string: free the expression and fall back to static rule */
7710 free(node->arg);
7711 free(node);
7712 }
7713
7714 rule->dynamic = 0;
7715 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007716
Willy Tarreauafb39922015-05-26 12:04:09 +02007717 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007718 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007719 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7720 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007721 cfgerr++;
7722 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007723 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7724 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007725 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007726 } else if (target->mode != curproxy->mode &&
7727 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7728
Christopher Faulet767a84b2017-11-24 16:50:31 +01007729 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7730 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7731 curproxy->conf.file, curproxy->conf.line,
7732 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7733 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007734 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007735 } else {
7736 free((void *)rule->be.name);
7737 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007738 /* For each target of switching rules, we update
7739 * their tot_fe_maxconn, except if a previous rule point
7740 * on the same backend or on the default backend */
7741 if (rule->be.backend != curproxy->defbe.be) {
7742 struct switching_rule *swrule;
7743
7744 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7745 if (rule == swrule) {
7746 target->tot_fe_maxconn += curproxy->maxconn;
7747 break;
7748 }
7749 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7750 /* there is multiple ref of this backend */
7751 break;
7752 }
7753 }
7754 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007755 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007756 }
7757
Willy Tarreau64ab6072014-09-16 12:17:36 +02007758 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007759 list_for_each_entry(srule, &curproxy->server_rules, list) {
7760 struct server *target = findserver(curproxy, srule->srv.name);
7761
7762 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007763 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7764 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007765 cfgerr++;
7766 continue;
7767 }
7768 free((void *)srule->srv.name);
7769 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007770 }
7771
Emeric Brunb982a3d2010-01-04 15:45:53 +01007772 /* find the target table for 'stick' rules */
7773 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7774 struct proxy *target;
7775
Emeric Brun1d33b292010-01-04 15:47:17 +01007776 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7777 if (mrule->flags & STK_IS_STORE)
7778 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7779
Emeric Brunb982a3d2010-01-04 15:45:53 +01007780 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007781 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007782 else
7783 target = curproxy;
7784
7785 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007786 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7787 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007788 cfgerr++;
7789 }
7790 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007791 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7792 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007793 cfgerr++;
7794 }
Willy Tarreau12785782012-04-27 21:37:17 +02007795 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007796 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7797 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007798 cfgerr++;
7799 }
7800 else {
7801 free((void *)mrule->table.name);
7802 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007803 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007804 }
7805 }
7806
7807 /* find the target table for 'store response' rules */
7808 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7809 struct proxy *target;
7810
Emeric Brun1d33b292010-01-04 15:47:17 +01007811 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7812
Emeric Brunb982a3d2010-01-04 15:45:53 +01007813 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007814 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007815 else
7816 target = curproxy;
7817
7818 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007819 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7820 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007821 cfgerr++;
7822 }
7823 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007824 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7825 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007826 cfgerr++;
7827 }
Willy Tarreau12785782012-04-27 21:37:17 +02007828 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007829 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7830 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007831 cfgerr++;
7832 }
7833 else {
7834 free((void *)mrule->table.name);
7835 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007836 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007837 }
7838 }
7839
Christopher Faulete4e830d2017-09-18 14:51:41 +02007840 /* check validity for 'tcp-request' layer 4 rules */
7841 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
7842 err = NULL;
7843 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007844 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007845 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01007846 cfgerr++;
7847 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02007848 }
7849
Christopher Faulete4e830d2017-09-18 14:51:41 +02007850 /* check validity for 'tcp-request' layer 5 rules */
7851 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
7852 err = NULL;
7853 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007854 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007855 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007856 cfgerr++;
7857 }
7858 }
7859
Christopher Faulete4e830d2017-09-18 14:51:41 +02007860 /* check validity for 'tcp-request' layer 6 rules */
7861 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
7862 err = NULL;
7863 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007864 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007865 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007866 cfgerr++;
7867 }
7868 }
7869
Christopher Faulete4e830d2017-09-18 14:51:41 +02007870 /* check validity for 'http-request' layer 7 rules */
7871 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
7872 err = NULL;
7873 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007874 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007875 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007876 cfgerr++;
7877 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007878 }
7879
Christopher Faulete4e830d2017-09-18 14:51:41 +02007880 /* check validity for 'http-response' layer 7 rules */
7881 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
7882 err = NULL;
7883 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007884 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007885 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02007886 cfgerr++;
7887 }
Willy Tarreau09448f72014-06-25 18:12:15 +02007888 }
7889
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02007890 /* move any "block" rules at the beginning of the http-request rules */
7891 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
7892 /* insert block_rules into http_req_rules at the beginning */
7893 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
7894 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
7895 curproxy->block_rules.n->p = &curproxy->http_req_rules;
7896 curproxy->http_req_rules.n = curproxy->block_rules.n;
7897 LIST_INIT(&curproxy->block_rules);
7898 }
7899
Emeric Brun32da3c42010-09-23 18:39:19 +02007900 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02007901 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02007902
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02007903 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02007904 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
7905 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01007906 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02007907 break;
7908 }
7909 }
7910
7911 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007912 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
7913 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02007914 free((void *)curproxy->table.peers.name);
7915 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02007916 cfgerr++;
7917 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02007918 else if (curpeers->state == PR_STSTOPPED) {
7919 /* silently disable this peers section */
7920 curproxy->table.peers.p = NULL;
7921 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007922 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007923 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
7924 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02007925 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02007926 cfgerr++;
7927 }
7928 }
7929
Simon Horman9dc49962015-01-30 11:22:59 +09007930
7931 if (curproxy->email_alert.mailers.name) {
7932 struct mailers *curmailers = mailers;
7933
7934 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02007935 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09007936 break;
Simon Horman9dc49962015-01-30 11:22:59 +09007937 }
Simon Horman9dc49962015-01-30 11:22:59 +09007938 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007939 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
7940 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09007941 free_email_alert(curproxy);
7942 cfgerr++;
7943 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02007944 else {
7945 err = NULL;
7946 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007947 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02007948 free(err);
7949 cfgerr++;
7950 }
7951 }
Simon Horman9dc49962015-01-30 11:22:59 +09007952 }
7953
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01007954 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01007955 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007956 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007957 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
7958 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007959 cfgerr++;
7960 goto out_uri_auth_compat;
7961 }
7962
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01007963 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01007964 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02007965 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01007966 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007967
Willy Tarreau95fa4692010-02-01 13:05:50 +01007968 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
7969 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007970
7971 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01007972 uri_auth_compat_req[i++] = "realm";
7973 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
7974 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007975
Willy Tarreau95fa4692010-02-01 13:05:50 +01007976 uri_auth_compat_req[i++] = "unless";
7977 uri_auth_compat_req[i++] = "{";
7978 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
7979 uri_auth_compat_req[i++] = "}";
7980 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007981
Willy Tarreauff011f22011-01-06 17:51:27 +01007982 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
7983 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01007984 cfgerr++;
7985 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007986 }
7987
Willy Tarreauff011f22011-01-06 17:51:27 +01007988 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01007989
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007990 if (curproxy->uri_auth->auth_realm) {
7991 free(curproxy->uri_auth->auth_realm);
7992 curproxy->uri_auth->auth_realm = NULL;
7993 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01007994
7995 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007996 }
7997out_uri_auth_compat:
7998
Dragan Dosen43885c72015-10-01 13:18:13 +02007999 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008000 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008001 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8002 if (!curproxy->conf.logformat_sd_string) {
8003 /* set the default logformat_sd_string */
8004 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8005 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008006 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008007 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008008 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008009
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008010 /* compile the log format */
8011 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008012 if (curproxy->conf.logformat_string != default_http_log_format &&
8013 curproxy->conf.logformat_string != default_tcp_log_format &&
8014 curproxy->conf.logformat_string != clf_http_log_format)
8015 free(curproxy->conf.logformat_string);
8016 curproxy->conf.logformat_string = NULL;
8017 free(curproxy->conf.lfs_file);
8018 curproxy->conf.lfs_file = NULL;
8019 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008020
8021 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8022 free(curproxy->conf.logformat_sd_string);
8023 curproxy->conf.logformat_sd_string = NULL;
8024 free(curproxy->conf.lfsd_file);
8025 curproxy->conf.lfsd_file = NULL;
8026 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008027 }
8028
Willy Tarreau62a61232013-04-12 18:13:46 +02008029 if (curproxy->conf.logformat_string) {
8030 curproxy->conf.args.ctx = ARGC_LOG;
8031 curproxy->conf.args.file = curproxy->conf.lfs_file;
8032 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008033 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008034 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008035 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008036 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8037 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008038 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008039 cfgerr++;
8040 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008041 curproxy->conf.args.file = NULL;
8042 curproxy->conf.args.line = 0;
8043 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008044
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008045 if (curproxy->conf.logformat_sd_string) {
8046 curproxy->conf.args.ctx = ARGC_LOGSD;
8047 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8048 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008049 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008050 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 +01008051 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008052 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8053 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008054 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008055 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008056 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008057 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8058 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008059 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008060 cfgerr++;
8061 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008062 curproxy->conf.args.file = NULL;
8063 curproxy->conf.args.line = 0;
8064 }
8065
Willy Tarreau62a61232013-04-12 18:13:46 +02008066 if (curproxy->conf.uniqueid_format_string) {
8067 curproxy->conf.args.ctx = ARGC_UIF;
8068 curproxy->conf.args.file = curproxy->conf.uif_file;
8069 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008070 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008071 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 +01008072 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008073 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8074 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008075 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008076 cfgerr++;
8077 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008078 curproxy->conf.args.file = NULL;
8079 curproxy->conf.args.line = 0;
8080 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008081
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008082 /* only now we can check if some args remain unresolved.
8083 * This must be done after the users and groups resolution.
8084 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008085 cfgerr += smp_resolve_args(curproxy);
8086 if (!cfgerr)
8087 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008088
Willy Tarreau2738a142006-07-08 17:28:09 +02008089 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008090 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008091 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008092 (!curproxy->timeout.connect ||
8093 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008094 ha_warning("config : missing timeouts for %s '%s'.\n"
8095 " | While not properly invalid, you will certainly encounter various problems\n"
8096 " | with such a configuration. To fix this, please ensure that all following\n"
8097 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8098 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008099 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008100 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008101
Willy Tarreau1fa31262007-12-03 00:36:16 +01008102 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8103 * We must still support older configurations, so let's find out whether those
8104 * parameters have been set or must be copied from contimeouts.
8105 */
8106 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008107 if (!curproxy->timeout.tarpit ||
8108 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008109 /* tarpit timeout not set. We search in the following order:
8110 * default.tarpit, curr.connect, default.connect.
8111 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008112 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008113 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008114 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008115 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008116 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008117 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008118 }
8119 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008120 (!curproxy->timeout.queue ||
8121 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008122 /* queue timeout not set. We search in the following order:
8123 * default.queue, curr.connect, default.connect.
8124 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008125 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008126 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008127 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008128 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008129 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008130 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008131 }
8132 }
8133
Willy Tarreau1620ec32011-08-06 17:05:02 +02008134 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008135 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008136 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008137 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008138 }
8139
Willy Tarreau215663d2014-06-13 18:30:23 +02008140 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8141 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008142 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8143 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008144 err_code |= ERR_WARN;
8145 }
8146
Willy Tarreau193b8c62012-11-22 00:17:38 +01008147 /* ensure that cookie capture length is not too large */
8148 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008149 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8150 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008151 err_code |= ERR_WARN;
8152 curproxy->capture_len = global.tune.cookie_len - 1;
8153 }
8154
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008155 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008156 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008157 curproxy->req_cap_pool = create_pool("ptrcap",
8158 curproxy->nb_req_cap * sizeof(char *),
8159 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008160 }
8161
8162 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008163 curproxy->rsp_cap_pool = create_pool("ptrcap",
8164 curproxy->nb_rsp_cap * sizeof(char *),
8165 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008166 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008167
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008168 switch (curproxy->load_server_state_from_file) {
8169 case PR_SRV_STATE_FILE_UNSPEC:
8170 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8171 break;
8172 case PR_SRV_STATE_FILE_GLOBAL:
8173 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008174 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",
8175 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008176 err_code |= ERR_WARN;
8177 }
8178 break;
8179 }
8180
Willy Tarreaubaaee002006-06-26 02:48:02 +02008181 /* first, we will invert the servers list order */
8182 newsrv = NULL;
8183 while (curproxy->srv) {
8184 struct server *next;
8185
8186 next = curproxy->srv->next;
8187 curproxy->srv->next = newsrv;
8188 newsrv = curproxy->srv;
8189 if (!next)
8190 break;
8191 curproxy->srv = next;
8192 }
8193
Willy Tarreau17edc812014-01-03 12:14:34 +01008194 /* Check that no server name conflicts. This causes trouble in the stats.
8195 * We only emit a warning for the first conflict affecting each server,
8196 * in order to avoid combinatory explosion if all servers have the same
8197 * name. We do that only for servers which do not have an explicit ID,
8198 * because these IDs were made also for distinguishing them and we don't
8199 * want to annoy people who correctly manage them.
8200 */
8201 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8202 struct server *other_srv;
8203
8204 if (newsrv->puid)
8205 continue;
8206
8207 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8208 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008209 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",
8210 newsrv->conf.file, newsrv->conf.line,
8211 proxy_type_str(curproxy), curproxy->id,
8212 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008213 break;
8214 }
8215 }
8216 }
8217
Willy Tarreaudd701652010-05-25 23:03:02 +02008218 /* assign automatic UIDs to servers which don't have one yet */
8219 next_id = 1;
8220 newsrv = curproxy->srv;
8221 while (newsrv != NULL) {
8222 if (!newsrv->puid) {
8223 /* server ID not set, use automatic numbering with first
8224 * spare entry starting with next_svid.
8225 */
8226 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8227 newsrv->conf.id.key = newsrv->puid = next_id;
8228 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8229 }
8230 next_id++;
8231 newsrv = newsrv->next;
8232 }
8233
Willy Tarreau20697042007-11-15 23:26:18 +01008234 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008235 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008236
Willy Tarreau62c3be22012-01-20 13:12:32 +01008237 /*
8238 * If this server supports a maxconn parameter, it needs a dedicated
8239 * tasks to fill the emptied slots when a connection leaves.
8240 * Also, resolve deferred tracking dependency if needed.
8241 */
8242 newsrv = curproxy->srv;
8243 while (newsrv != NULL) {
8244 if (newsrv->minconn > newsrv->maxconn) {
8245 /* Only 'minconn' was specified, or it was higher than or equal
8246 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8247 * this will avoid further useless expensive computations.
8248 */
8249 newsrv->maxconn = newsrv->minconn;
8250 } else if (newsrv->maxconn && !newsrv->minconn) {
8251 /* minconn was not specified, so we set it to maxconn */
8252 newsrv->minconn = newsrv->maxconn;
8253 }
8254
Willy Tarreau17d45382016-12-22 21:16:08 +01008255 /* this will also properly set the transport layer for prod and checks */
8256 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8257 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8258 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8259 }
Emeric Brun94324a42012-10-11 14:00:19 +02008260
Willy Tarreau2f075e92013-12-03 11:11:34 +01008261 /* set the check type on the server */
8262 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8263
Willy Tarreau62c3be22012-01-20 13:12:32 +01008264 if (newsrv->trackit) {
8265 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008266 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008267 char *pname, *sname;
8268
8269 pname = newsrv->trackit;
8270 sname = strrchr(pname, '/');
8271
8272 if (sname)
8273 *sname++ = '\0';
8274 else {
8275 sname = pname;
8276 pname = NULL;
8277 }
8278
8279 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008280 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008281 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008282 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8283 proxy_type_str(curproxy), curproxy->id,
8284 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008285 cfgerr++;
8286 goto next_srv;
8287 }
8288 } else
8289 px = curproxy;
8290
8291 srv = findserver(px, sname);
8292 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008293 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8294 proxy_type_str(curproxy), curproxy->id,
8295 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008296 cfgerr++;
8297 goto next_srv;
8298 }
8299
Willy Tarreau32091232014-05-16 13:52:00 +02008300 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8301 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8302 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008303 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8304 "tracking as it does not have any check nor agent enabled.\n",
8305 proxy_type_str(curproxy), curproxy->id,
8306 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008307 cfgerr++;
8308 goto next_srv;
8309 }
8310
8311 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8312
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008313 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008314 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8315 "belongs to a tracking chain looping back to %s/%s.\n",
8316 proxy_type_str(curproxy), curproxy->id,
8317 newsrv->id, px->id, srv->id, px->id,
8318 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008319 cfgerr++;
8320 goto next_srv;
8321 }
8322
8323 if (curproxy != px &&
8324 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008325 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8326 "tracking: disable-on-404 option inconsistency.\n",
8327 proxy_type_str(curproxy), curproxy->id,
8328 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008329 cfgerr++;
8330 goto next_srv;
8331 }
8332
Willy Tarreau62c3be22012-01-20 13:12:32 +01008333 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008334 newsrv->tracknext = srv->trackers;
8335 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008336
8337 free(newsrv->trackit);
8338 newsrv->trackit = NULL;
8339 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008340
Willy Tarreau62c3be22012-01-20 13:12:32 +01008341 next_srv:
8342 newsrv = newsrv->next;
8343 }
8344
Olivier Houchard4e694042017-03-14 20:01:29 +01008345 /*
8346 * Try to generate dynamic cookies for servers now.
8347 * It couldn't be done earlier, since at the time we parsed
8348 * the server line, we may not have known yet that we
8349 * should use dynamic cookies, or the secret key may not
8350 * have been provided yet.
8351 */
8352 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8353 newsrv = curproxy->srv;
8354 while (newsrv != NULL) {
8355 srv_set_dyncookie(newsrv);
8356 newsrv = newsrv->next;
8357 }
8358
8359 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008360 /* We have to initialize the server lookup mechanism depending
8361 * on what LB algorithm was choosen.
8362 */
8363
8364 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8365 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8366 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008367 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8368 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8369 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02008370 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
8371 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8372 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02008373 } else {
8374 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8375 fwrr_init_server_groups(curproxy);
8376 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008377 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008378
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008379 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008380 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8381 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8382 fwlc_init_server_tree(curproxy);
8383 } else {
8384 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8385 fas_init_server_tree(curproxy);
8386 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008387 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008388
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008389 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008390 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8391 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8392 chash_init_server_tree(curproxy);
8393 } else {
8394 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8395 init_server_map(curproxy);
8396 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008397 break;
8398 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008399 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008400
8401 if (curproxy->options & PR_O_LOGASAP)
8402 curproxy->to_log &= ~LW_BYTES;
8403
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008404 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008405 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8406 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008407 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8408 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008409 err_code |= ERR_WARN;
8410 }
8411
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008412 if (curproxy->mode != PR_MODE_HTTP) {
8413 int optnum;
8414
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008415 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008416 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8417 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008418 err_code |= ERR_WARN;
8419 curproxy->uri_auth = NULL;
8420 }
8421
Willy Tarreaude7dc882017-03-10 11:49:21 +01008422 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008423 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8424 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008425 err_code |= ERR_WARN;
8426 }
8427
8428 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008429 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8430 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008431 err_code |= ERR_WARN;
8432 }
8433
8434 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008435 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8436 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008437 err_code |= ERR_WARN;
8438 }
8439
8440 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008441 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8442 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008443 err_code |= ERR_WARN;
8444 }
8445
8446 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008447 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8448 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008449 err_code |= ERR_WARN;
8450 }
8451
Willy Tarreau87cf5142011-08-19 22:57:24 +02008452 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008453 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8454 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008455 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008456 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008457 }
8458
8459 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008460 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8461 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008462 err_code |= ERR_WARN;
8463 curproxy->options &= ~PR_O_ORGTO;
8464 }
8465
8466 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8467 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8468 (curproxy->cap & cfg_opts[optnum].cap) &&
8469 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008470 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8471 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008472 err_code |= ERR_WARN;
8473 curproxy->options &= ~cfg_opts[optnum].val;
8474 }
8475 }
8476
8477 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8478 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8479 (curproxy->cap & cfg_opts2[optnum].cap) &&
8480 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008481 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8482 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008483 err_code |= ERR_WARN;
8484 curproxy->options2 &= ~cfg_opts2[optnum].val;
8485 }
8486 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008487
Willy Tarreau29fbe512015-08-20 19:35:14 +02008488#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008489 if (curproxy->conn_src.bind_hdr_occ) {
8490 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008491 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8492 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008493 err_code |= ERR_WARN;
8494 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008495#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008496 }
8497
Willy Tarreaubaaee002006-06-26 02:48:02 +02008498 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008499 * ensure that we're not cross-dressing a TCP server into HTTP.
8500 */
8501 newsrv = curproxy->srv;
8502 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008503 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008504 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8505 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008506 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008507 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008508
Willy Tarreau0cec3312011-10-31 13:49:26 +01008509 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008510 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8511 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008512 err_code |= ERR_WARN;
8513 }
8514
Willy Tarreauc93cd162014-05-13 15:54:22 +02008515 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008516 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8517 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008518 err_code |= ERR_WARN;
8519 }
8520
Willy Tarreau29fbe512015-08-20 19:35:14 +02008521#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008522 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8523 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008524 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8525 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008526 err_code |= ERR_WARN;
8527 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008528#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008529
Willy Tarreau46deab62018-04-28 07:18:15 +02008530 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
8531 curproxy->options &= ~PR_O_REUSE_MASK;
8532
Willy Tarreau4c183462017-01-06 12:21:38 +01008533 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8534 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8535 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8536 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8537 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008538 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",
8539 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008540 err_code |= ERR_WARN;
8541 }
8542
8543
8544 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008545 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",
8546 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008547 err_code |= ERR_WARN;
8548 }
8549 }
8550
Willy Tarreau21d2af32008-02-14 20:25:24 +01008551 newsrv = newsrv->next;
8552 }
8553
Willy Tarreaue42bd962014-09-16 16:21:19 +02008554 /* check if we have a frontend with "tcp-request content" looking at L7
8555 * with no inspect-delay
8556 */
8557 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008558 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8559 if (arule->action == ACT_TCP_CAPTURE &&
8560 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008561 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008562 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8563 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008564 break;
8565 }
8566
Christopher Faulete4e830d2017-09-18 14:51:41 +02008567 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008568 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8569 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8570 " This means that these rules will randomly find their contents. This can be fixed by"
8571 " setting the tcp-request inspect-delay.\n",
8572 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008573 err_code |= ERR_WARN;
8574 }
8575 }
8576
Christopher Fauletd7c91962015-04-30 11:48:27 +02008577 /* Check filter configuration, if any */
8578 cfgerr += flt_check(curproxy);
8579
Willy Tarreauc1a21672009-08-16 22:37:44 +02008580 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008581 if (!curproxy->accept)
8582 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008583
Willy Tarreauc1a21672009-08-16 22:37:44 +02008584 if (curproxy->tcp_req.inspect_delay ||
8585 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008586 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008587
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008588 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008589 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008590 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008591 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008592
8593 /* both TCP and HTTP must check switching rules */
8594 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008595
8596 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008597 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008598 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8599 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 +01008600 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008601 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8602 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008603 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008604 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008605 }
8606
8607 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008608 if (curproxy->tcp_req.inspect_delay ||
8609 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8610 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8611
Emeric Brun97679e72010-09-23 17:56:44 +02008612 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8613 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8614
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008615 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008616 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008617 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008618 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008619
8620 /* If the backend does requires RDP cookie persistence, we have to
8621 * enable the corresponding analyser.
8622 */
8623 if (curproxy->options2 & PR_O2_RDPC_PRST)
8624 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008625
8626 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008627 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008628 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8629 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 +01008630 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008631 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8632 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008633 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008634 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008635 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008636 }
8637
8638 /***********************************************************/
8639 /* At this point, target names have already been resolved. */
8640 /***********************************************************/
8641
8642 /* Check multi-process mode compatibility */
8643
8644 if (global.nbproc > 1 && global.stats_fe) {
8645 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8646 unsigned long mask;
8647
8648 mask = nbits(global.nbproc);
8649 if (global.stats_fe->bind_proc)
8650 mask &= global.stats_fe->bind_proc;
8651
8652 if (bind_conf->bind_proc)
8653 mask &= bind_conf->bind_proc;
8654
8655 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008656 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008657 break;
8658 }
8659 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008660 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 +02008661 }
8662 }
8663
8664 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008665 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008666 if (curproxy->bind_proc)
8667 continue;
8668
8669 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8670 unsigned long mask;
8671
Willy Tarreaue428b082015-05-04 21:57:58 +02008672 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008673 curproxy->bind_proc |= mask;
8674 }
8675
8676 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008677 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008678 }
8679
8680 if (global.stats_fe) {
8681 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8682 unsigned long mask;
8683
Cyril Bonté06181952016-02-24 00:14:54 +01008684 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008685 global.stats_fe->bind_proc |= mask;
8686 }
8687 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008688 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008689 }
8690
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008691 /* propagate bindings from frontends to backends. Don't do it if there
8692 * are any fatal errors as we must not call it with unresolved proxies.
8693 */
8694 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008695 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008696 if (curproxy->cap & PR_CAP_FE)
8697 propagate_processes(curproxy, NULL);
8698 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008699 }
8700
8701 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008702 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008703 if (curproxy->bind_proc)
8704 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008705 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008706 }
8707
8708 /*******************************************************/
8709 /* At this step, all proxies have a non-null bind_proc */
8710 /*******************************************************/
8711
8712 /* perform the final checks before creating tasks */
8713
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008714 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008715 struct listener *listener;
8716 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008717
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008718 /* Configure SSL for each bind line.
8719 * Note: if configuration fails at some point, the ->ctx member
8720 * remains NULL so that listeners can later detach.
8721 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008722 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008723 if (bind_conf->xprt->prepare_bind_conf &&
8724 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008725 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008726 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008727
Willy Tarreaue6b98942007-10-29 01:09:36 +01008728 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008729 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008730 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008731 int nbproc;
8732
8733 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008734 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008735 nbits(global.nbproc));
8736
8737 if (!nbproc) /* no intersection between listener and frontend */
8738 nbproc = 1;
8739
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008740 if (!listener->luid) {
8741 /* listener ID not set, use automatic numbering with first
8742 * spare entry starting with next_luid.
8743 */
8744 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8745 listener->conf.id.key = listener->luid = next_id;
8746 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008747 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008748 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008749
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008750 /* enable separate counters */
8751 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008752 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008753 if (!listener->name)
8754 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008755 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008756
Willy Tarreaue6b98942007-10-29 01:09:36 +01008757 if (curproxy->options & PR_O_TCP_NOLING)
8758 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008759 if (!listener->maxconn)
8760 listener->maxconn = curproxy->maxconn;
8761 if (!listener->backlog)
8762 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008763 if (!listener->maxaccept)
8764 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8765
8766 /* we want to have an optimal behaviour on single process mode to
8767 * maximize the work at once, but in multi-process we want to keep
8768 * some fairness between processes, so we target half of the max
8769 * number of events to be balanced over all the processes the proxy
8770 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8771 * used to disable the limit.
8772 */
8773 if (listener->maxaccept > 0) {
8774 if (nbproc > 1)
8775 listener->maxaccept = (listener->maxaccept + 1) / 2;
8776 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8777 }
8778
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008779 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008780 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008781 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008782
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008783 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008784 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008785
Willy Tarreau620408f2016-10-21 16:37:51 +02008786 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8787 listener->options |= LI_O_TCP_L5_RULES;
8788
Willy Tarreaude3041d2010-05-31 10:56:17 +02008789 if (curproxy->mon_mask.s_addr)
8790 listener->options |= LI_O_CHK_MONNET;
8791
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008792 /* smart accept mode is automatic in HTTP mode */
8793 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008794 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008795 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8796 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008797 }
8798
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008799 /* Release unused SSL configs */
8800 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008801 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8802 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008803 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008804
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008805 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008806 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008807 int count, maxproc = 0;
8808
8809 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008810 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008811 if (count > maxproc)
8812 maxproc = count;
8813 }
8814 /* backends have 0, frontends have 1 or more */
8815 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008816 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8817 " limited to process assigned to the current request.\n",
8818 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008819
Willy Tarreau102df612014-05-07 23:56:38 +02008820 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008821 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
8822 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008823 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008824 }
Willy Tarreau102df612014-05-07 23:56:38 +02008825 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008826 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
8827 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008828 }
8829 }
Willy Tarreau918ff602011-07-25 16:33:49 +02008830
8831 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02008832 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02008833 if (curproxy->task) {
8834 curproxy->task->context = curproxy;
8835 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02008836 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008837 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
8838 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02008839 cfgerr++;
8840 }
Willy Tarreaub369a042014-09-16 13:21:03 +02008841 }
8842
Willy Tarreaufbb78422011-06-05 15:38:35 +02008843 /* automatically compute fullconn if not set. We must not do it in the
8844 * loop above because cross-references are not yet fully resolved.
8845 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008846 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008847 /* If <fullconn> is not set, let's set it to 10% of the sum of
8848 * the possible incoming frontend's maxconns.
8849 */
8850 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008851 /* we have the sum of the maxconns in <total>. We only
8852 * keep 10% of that sum to set the default fullconn, with
8853 * a hard minimum of 1 (to avoid a divide by zero).
8854 */
Emeric Brun3f783572017-01-12 11:21:28 +01008855 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02008856 if (!curproxy->fullconn)
8857 curproxy->fullconn = 1;
8858 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01008859 }
8860
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008861 /*
8862 * Recount currently required checks.
8863 */
8864
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008865 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008866 int optnum;
8867
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008868 for (optnum = 0; cfg_opts[optnum].name; optnum++)
8869 if (curproxy->options & cfg_opts[optnum].val)
8870 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008871
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008872 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
8873 if (curproxy->options2 & cfg_opts2[optnum].val)
8874 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008875 }
8876
Willy Tarreau0fca4832015-05-01 19:12:05 +02008877 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008878 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02008879 if (curproxy->table.peers.p)
8880 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
8881
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008882 if (cfg_peers) {
8883 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02008884 struct peer *p, *pb;
8885
Willy Tarreau1e273012015-05-01 19:15:17 +02008886 /* Remove all peers sections which don't have a valid listener,
8887 * which are not used by any table, or which are bound to more
8888 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02008889 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008890 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02008891 while (*last) {
8892 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008893
8894 if (curpeers->state == PR_STSTOPPED) {
8895 /* the "disabled" keyword was present */
8896 if (curpeers->peers_fe)
8897 stop_proxy(curpeers->peers_fe);
8898 curpeers->peers_fe = NULL;
8899 }
8900 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008901 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
8902 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008903 }
David Carliere6c39412015-07-02 07:00:17 +00008904 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02008905 /* either it's totally stopped or too much used */
8906 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008907 ha_alert("Peers section '%s': peers referenced by sections "
8908 "running in different processes (%d different ones). "
8909 "Check global.nbproc and all tables' bind-process "
8910 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02008911 cfgerr++;
8912 }
8913 stop_proxy(curpeers->peers_fe);
8914 curpeers->peers_fe = NULL;
8915 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008916 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02008917 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02008918 last = &curpeers->next;
8919 continue;
8920 }
8921
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008922 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02008923 p = curpeers->remote;
8924 while (p) {
8925 pb = p->next;
8926 free(p->id);
8927 free(p);
8928 p = pb;
8929 }
8930
8931 /* Destroy and unlink this curpeers section.
8932 * Note: curpeers is backed up into *last.
8933 */
8934 free(curpeers->id);
8935 curpeers = curpeers->next;
8936 free(*last);
8937 *last = curpeers;
8938 }
8939 }
8940
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008941 /* initialize stick-tables on backend capable proxies. This must not
8942 * be done earlier because the data size may be discovered while parsing
8943 * other proxies.
8944 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008945 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008946 if (curproxy->state == PR_STSTOPPED)
8947 continue;
8948
8949 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008950 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008951 cfgerr++;
8952 }
8953 }
8954
Simon Horman0d16a402015-01-30 11:22:58 +09008955 if (mailers) {
8956 struct mailers *curmailers = mailers, **last;
8957 struct mailer *m, *mb;
8958
8959 /* Remove all mailers sections which don't have a valid listener.
8960 * This can happen when a mailers section is never referenced.
8961 */
8962 last = &mailers;
8963 while (*last) {
8964 curmailers = *last;
8965 if (curmailers->users) {
8966 last = &curmailers->next;
8967 continue;
8968 }
8969
Christopher Faulet767a84b2017-11-24 16:50:31 +01008970 ha_warning("Removing incomplete section 'mailers %s'.\n",
8971 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09008972
8973 m = curmailers->mailer_list;
8974 while (m) {
8975 mb = m->next;
8976 free(m->id);
8977 free(m);
8978 m = mb;
8979 }
8980
8981 /* Destroy and unlink this curmailers section.
8982 * Note: curmailers is backed up into *last.
8983 */
8984 free(curmailers->id);
8985 curmailers = curmailers->next;
8986 free(*last);
8987 *last = curmailers;
8988 }
8989 }
8990
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008991 /* Update server_state_file_name to backend name if backend is supposed to use
8992 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008993 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008994 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
8995 curproxy->server_state_file_name == NULL)
8996 curproxy->server_state_file_name = strdup(curproxy->id);
8997 }
8998
Willy Tarreaubafbe012017-11-24 17:34:44 +01008999 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009000 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009001 MEM_F_SHARED);
9002
Ben Draut054fbee2018-04-13 15:43:04 -06009003 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
9004 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
9005 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
9006 curr_resolvers->id, curr_resolvers->conf.file,
9007 curr_resolvers->conf.line);
9008 err_code |= ERR_WARN;
9009 }
9010 }
9011
William Lallemand48b4bb42017-10-23 14:36:34 +02009012 list_for_each_entry(postparser, &postparsers, list) {
9013 if (postparser->func)
9014 cfgerr += postparser->func();
9015 }
9016
Willy Tarreaubb925012009-07-23 13:36:36 +02009017 if (cfgerr > 0)
9018 err_code |= ERR_ALERT | ERR_FATAL;
9019 out:
9020 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009021}
9022
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009023/*
9024 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9025 * parsing sessions.
9026 */
9027void cfg_register_keywords(struct cfg_kw_list *kwl)
9028{
9029 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9030}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009031
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009032/*
9033 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9034 */
9035void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9036{
9037 LIST_DEL(&kwl->list);
9038 LIST_INIT(&kwl->list);
9039}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009040
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009041/* this function register new section in the haproxy configuration file.
9042 * <section_name> is the name of this new section and <section_parser>
9043 * is the called parser. If two section declaration have the same name,
9044 * only the first declared is used.
9045 */
9046int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009047 int (*section_parser)(const char *, int, char **, int),
9048 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009049{
9050 struct cfg_section *cs;
9051
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009052 list_for_each_entry(cs, &sections, list) {
9053 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009054 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009055 return 0;
9056 }
9057 }
9058
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009059 cs = calloc(1, sizeof(*cs));
9060 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009061 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009062 return 0;
9063 }
9064
9065 cs->section_name = section_name;
9066 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009067 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009068
9069 LIST_ADDQ(&sections, &cs->list);
9070
9071 return 1;
9072}
9073
William Lallemand48b4bb42017-10-23 14:36:34 +02009074/* this function register a new function which will be called once the haproxy
9075 * configuration file has been parsed. It's useful to check dependencies
9076 * between sections or to resolve items once everything is parsed.
9077 */
9078int cfg_register_postparser(char *name, int (*func)())
9079{
9080 struct cfg_postparser *cp;
9081
9082 cp = calloc(1, sizeof(*cp));
9083 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009084 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009085 return 0;
9086 }
9087 cp->name = name;
9088 cp->func = func;
9089
9090 LIST_ADDQ(&postparsers, &cp->list);
9091
9092 return 1;
9093}
9094
Willy Tarreaubaaee002006-06-26 02:48:02 +02009095/*
David Carlier845efb52015-09-25 11:49:18 +01009096 * free all config section entries
9097 */
9098void cfg_unregister_sections(void)
9099{
9100 struct cfg_section *cs, *ics;
9101
9102 list_for_each_entry_safe(cs, ics, &sections, list) {
9103 LIST_DEL(&cs->list);
9104 free(cs);
9105 }
9106}
9107
Christopher Faulet7110b402016-10-26 11:09:44 +02009108void cfg_backup_sections(struct list *backup_sections)
9109{
9110 struct cfg_section *cs, *ics;
9111
9112 list_for_each_entry_safe(cs, ics, &sections, list) {
9113 LIST_DEL(&cs->list);
9114 LIST_ADDQ(backup_sections, &cs->list);
9115 }
9116}
9117
9118void cfg_restore_sections(struct list *backup_sections)
9119{
9120 struct cfg_section *cs, *ics;
9121
9122 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9123 LIST_DEL(&cs->list);
9124 LIST_ADDQ(&sections, &cs->list);
9125 }
9126}
9127
Willy Tarreau659fbf02016-05-26 17:55:28 +02009128__attribute__((constructor))
9129static void cfgparse_init(void)
9130{
9131 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009132 cfg_register_section("listen", cfg_parse_listen, NULL);
9133 cfg_register_section("frontend", cfg_parse_listen, NULL);
9134 cfg_register_section("backend", cfg_parse_listen, NULL);
9135 cfg_register_section("defaults", cfg_parse_listen, NULL);
9136 cfg_register_section("global", cfg_parse_global, NULL);
9137 cfg_register_section("userlist", cfg_parse_users, NULL);
9138 cfg_register_section("peers", cfg_parse_peers, NULL);
9139 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9140 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9141 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009142}
9143
David Carlier845efb52015-09-25 11:49:18 +01009144/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009145 * Local variables:
9146 * c-indent-level: 8
9147 * c-basic-offset: 8
9148 * End:
9149 */