blob: c40e71dc790d6e952c0b1fe85f8cfebb42724a52 [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>
Willy Tarreaubaaee002006-06-26 02:48:02 +020087
88
Willy Tarreauf3c69202006-07-09 16:42:34 +020089/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
90 * ssl-hello-chk option to ensure that the remote server speaks SSL.
91 *
92 * Check RFC 2246 (TLSv1.0) sections A.3 and A.4 for details.
93 */
94const char sslv3_client_hello_pkt[] = {
95 "\x16" /* ContentType : 0x16 = Hanshake */
96 "\x03\x00" /* ProtocolVersion : 0x0300 = SSLv3 */
97 "\x00\x79" /* ContentLength : 0x79 bytes after this one */
98 "\x01" /* HanshakeType : 0x01 = CLIENT HELLO */
99 "\x00\x00\x75" /* HandshakeLength : 0x75 bytes after this one */
100 "\x03\x00" /* Hello Version : 0x0300 = v3 */
101 "\x00\x00\x00\x00" /* Unix GMT Time (s) : filled with <now> (@0x0B) */
102 "HAPROXYSSLCHK\nHAPROXYSSLCHK\n" /* Random : must be exactly 28 bytes */
103 "\x00" /* Session ID length : empty (no session ID) */
104 "\x00\x4E" /* Cipher Suite Length : 78 bytes after this one */
105 "\x00\x01" "\x00\x02" "\x00\x03" "\x00\x04" /* 39 most common ciphers : */
106 "\x00\x05" "\x00\x06" "\x00\x07" "\x00\x08" /* 0x01...0x1B, 0x2F...0x3A */
107 "\x00\x09" "\x00\x0A" "\x00\x0B" "\x00\x0C" /* This covers RSA/DH, */
108 "\x00\x0D" "\x00\x0E" "\x00\x0F" "\x00\x10" /* various bit lengths, */
109 "\x00\x11" "\x00\x12" "\x00\x13" "\x00\x14" /* SHA1/MD5, DES/3DES/AES... */
110 "\x00\x15" "\x00\x16" "\x00\x17" "\x00\x18"
111 "\x00\x19" "\x00\x1A" "\x00\x1B" "\x00\x2F"
112 "\x00\x30" "\x00\x31" "\x00\x32" "\x00\x33"
113 "\x00\x34" "\x00\x35" "\x00\x36" "\x00\x37"
114 "\x00\x38" "\x00\x39" "\x00\x3A"
115 "\x01" /* Compression Length : 0x01 = 1 byte for types */
116 "\x00" /* Compression Type : 0x00 = NULL compression */
117};
118
Willy Tarreau3842f002009-06-14 11:39:52 +0200119/* various keyword modifiers */
120enum kw_mod {
121 KWM_STD = 0, /* normal */
122 KWM_NO, /* "no" prefixed before the keyword */
123 KWM_DEF, /* "default" prefixed before the keyword */
124};
125
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100126/* permit to store configuration section */
127struct cfg_section {
128 struct list list;
129 char *section_name;
130 int (*section_parser)(const char *, int, char **, int);
William Lallemandd2ff56d2017-10-16 11:06:50 +0200131 int (*post_section_parser)();
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100132};
133
134/* Used to chain configuration sections definitions. This list
135 * stores struct cfg_section
136 */
137struct list sections = LIST_HEAD_INIT(sections);
138
William Lallemand48b4bb42017-10-23 14:36:34 +0200139/* store post configuration parsing */
140
141struct cfg_postparser {
142 struct list list;
143 char *name;
144 int (*func)();
145};
146
147struct list postparsers = LIST_HEAD_INIT(postparsers);
148
Willy Tarreau13943ab2006-12-31 00:24:10 +0100149/* some of the most common options which are also the easiest to handle */
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100150struct cfg_opt {
Willy Tarreau13943ab2006-12-31 00:24:10 +0100151 const char *name;
152 unsigned int val;
153 unsigned int cap;
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100154 unsigned int checks;
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100155 unsigned int mode;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100156};
157
158/* proxy->options */
159static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100160{
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100161 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
162 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
163 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
164 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
165 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
166 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100167 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau9fbe18e2015-05-01 22:42:08 +0200168 { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau0f228a02015-05-01 15:37:53 +0200169 { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreau9420b122013-12-15 18:58:25 +0100170 { "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100171 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
172 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
173 { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100174 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100175#ifdef TPROXY
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100176 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100177#else
178 { "transparent", 0, 0, 0, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100179#endif
180
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100181 { NULL, 0, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100182};
183
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100184/* proxy->options2 */
185static const struct cfg_opt cfg_opts2[] =
186{
187#ifdef CONFIG_HAP_LINUX_SPLICE
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100188 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
189 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
190 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100191#else
192 { "splice-request", 0, 0, 0, 0 },
193 { "splice-response", 0, 0, 0, 0 },
194 { "splice-auto", 0, 0, 0, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100195#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100196 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
197 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
198 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
199 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
200 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0, 0 },
201 { "socket-stats", PR_O2_SOCKSTAT, PR_CAP_FE, 0, 0 },
202 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0, 0 },
203 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0, 0 },
204 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Jamie Gloudon801a0a32012-08-25 00:18:33 -0400205 { "independent-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100206 { "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreaue52564c2010-04-27 22:19:14 +0200207 { "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau96e31212011-05-30 18:10:30 +0200208 { "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100209 { NULL, 0, 0, 0 }
210};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200211
Willy Tarreau6daf3432008-01-22 16:44:08 +0100212static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200213static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
214int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100215int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100216char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200217
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200218/* List head of all known configuration keywords */
219static struct cfg_kw_list cfg_keywords = {
220 .list = LIST_HEAD_INIT(cfg_keywords.list)
221};
222
Willy Tarreaubaaee002006-06-26 02:48:02 +0200223/*
224 * converts <str> to a list of listeners which are dynamically allocated.
225 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
226 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
227 * - <port> is a numerical port from 1 to 65535 ;
228 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
229 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200230 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
231 * not NULL, it must be a valid pointer to either NULL or a freeable area that
232 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200233 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200234int 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 +0200235{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100236 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200237 int port, end;
238
239 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200240
Willy Tarreaubaaee002006-06-26 02:48:02 +0200241 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100242 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200243 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100244 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200245
246 str = next;
247 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100248 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200249 *next++ = 0;
250 }
251
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100252 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200253 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200254 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100255 if (!ss2)
256 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200257
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100258 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100259 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200260 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100261 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200262 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200263
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100264 if (!port || !end) {
265 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
266 goto fail;
267 }
268
Emeric Bruned760922010-10-22 17:59:25 +0200269 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200270 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200271 goto fail;
272 }
273
274 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200275 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200276 goto fail;
277 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200278 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100279 else if (ss2->ss_family == AF_UNSPEC) {
280 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100281 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100282
283 /* We want to attach to an already bound fd whose number
284 * is in the addr part of ss2 when cast to sockaddr_in.
285 * Note that by definition there is a single listener.
286 * We still have to determine the address family to
287 * register the correct protocol.
288 */
289 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
290 addr_len = sizeof(*ss2);
291 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
292 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
293 goto fail;
294 }
295
296 port = end = get_host_port(ss2);
297 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200298
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100299 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100300 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200301 memprintf(err, "%s for address '%s'.\n", *err, str);
302 goto fail;
303 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200304 } /* end while(next) */
305 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200306 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200307 fail:
308 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200309 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200310}
311
William Lallemand6e62fb62015-04-28 16:55:23 +0200312/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100313 * Report an error in <msg> when there are too many arguments. This version is
314 * intended to be used by keyword parsers so that the message will be included
315 * into the general error message. The index is the current keyword in args.
316 * Return 0 if the number of argument is correct, otherwise build a message and
317 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
318 * message may also be null, it will simply not be produced (useful to check only).
319 * <msg> and <err_code> are only affected on error.
320 */
321int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
322{
323 int i;
324
325 if (!*args[index + maxarg + 1])
326 return 0;
327
328 if (msg) {
329 *msg = NULL;
330 memprintf(msg, "%s", args[0]);
331 for (i = 1; i <= index; i++)
332 memprintf(msg, "%s %s", *msg, args[i]);
333
334 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
335 }
336 if (err_code)
337 *err_code |= ERR_ALERT | ERR_FATAL;
338
339 return 1;
340}
341
342/*
343 * same as too_many_args_idx with a 0 index
344 */
345int too_many_args(int maxarg, char **args, char **msg, int *err_code)
346{
347 return too_many_args_idx(maxarg, 0, args, msg, err_code);
348}
349
350/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200351 * Report a fatal Alert when there is too much arguments
352 * The index is the current keyword in args
353 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
354 * Fill err_code with an ERR_ALERT and an ERR_FATAL
355 */
356int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
357{
358 char *kw = NULL;
359 int i;
360
361 if (!*args[index + maxarg + 1])
362 return 0;
363
364 memprintf(&kw, "%s", args[0]);
365 for (i = 1; i <= index; i++) {
366 memprintf(&kw, "%s %s", kw, args[i]);
367 }
368
Christopher Faulet767a84b2017-11-24 16:50:31 +0100369 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 +0200370 free(kw);
371 *err_code |= ERR_ALERT | ERR_FATAL;
372 return 1;
373}
374
375/*
376 * same as alertif_too_many_args_idx with a 0 index
377 */
378int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
379{
380 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
381}
382
Willy Tarreau620408f2016-10-21 16:37:51 +0200383/* Report a warning if a rule is placed after a 'tcp-request session' rule.
384 * Return 1 if the warning has been emitted, otherwise 0.
385 */
386int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
387{
388 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100389 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
390 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200391 return 1;
392 }
393 return 0;
394}
395
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200396/* Report a warning if a rule is placed after a 'tcp-request content' rule.
397 * Return 1 if the warning has been emitted, otherwise 0.
398 */
399int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
400{
401 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100402 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
403 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200404 return 1;
405 }
406 return 0;
407}
408
Willy Tarreau721d8e02017-12-01 18:25:08 +0100409/* Report a warning if a rule is placed after a 'monitor fail' rule.
410 * Return 1 if the warning has been emitted, otherwise 0.
411 */
412int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
413{
414 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
415 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
416 file, line, arg);
417 return 1;
418 }
419 return 0;
420}
421
Willy Tarreau61d18892009-03-31 10:49:21 +0200422/* Report a warning if a rule is placed after a 'block' rule.
423 * Return 1 if the warning has been emitted, otherwise 0.
424 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100425int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200426{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200427 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100428 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
429 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200430 return 1;
431 }
432 return 0;
433}
434
Willy Tarreau5002f572014-04-23 01:32:02 +0200435/* Report a warning if a rule is placed after an 'http_request' rule.
436 * Return 1 if the warning has been emitted, otherwise 0.
437 */
438int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
439{
440 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100441 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
442 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200443 return 1;
444 }
445 return 0;
446}
447
Willy Tarreau61d18892009-03-31 10:49:21 +0200448/* Report a warning if a rule is placed after a reqrewrite rule.
449 * Return 1 if the warning has been emitted, otherwise 0.
450 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100451int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200452{
453 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100454 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
455 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200456 return 1;
457 }
458 return 0;
459}
460
461/* Report a warning if a rule is placed after a reqadd rule.
462 * Return 1 if the warning has been emitted, otherwise 0.
463 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100464int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200465{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100466 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100467 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
468 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200469 return 1;
470 }
471 return 0;
472}
473
474/* Report a warning if a rule is placed after a redirect rule.
475 * Return 1 if the warning has been emitted, otherwise 0.
476 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100477int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200478{
479 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100480 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
481 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200482 return 1;
483 }
484 return 0;
485}
486
487/* Report a warning if a rule is placed after a 'use_backend' rule.
488 * Return 1 if the warning has been emitted, otherwise 0.
489 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100490int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200491{
492 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100493 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
494 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200495 return 1;
496 }
497 return 0;
498}
499
Willy Tarreauee445d92014-04-23 01:39:04 +0200500/* Report a warning if a rule is placed after a 'use-server' rule.
501 * Return 1 if the warning has been emitted, otherwise 0.
502 */
503int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
504{
505 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100506 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
507 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200508 return 1;
509 }
510 return 0;
511}
512
Willy Tarreaud39ad442016-11-25 15:16:12 +0100513/* report a warning if a redirect rule is dangerously placed */
514int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200515{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100516 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200517 warnif_rule_after_use_server(proxy, file, line, arg);
518}
519
Willy Tarreaud39ad442016-11-25 15:16:12 +0100520/* report a warning if a reqadd rule is dangerously placed */
521int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200522{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100523 return warnif_rule_after_redirect(proxy, file, line, arg) ||
524 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200525}
526
Willy Tarreaud39ad442016-11-25 15:16:12 +0100527/* report a warning if a reqxxx rule is dangerously placed */
528int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200529{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100530 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
531 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200532}
533
534/* report a warning if an http-request rule is dangerously placed */
535int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
536{
Willy Tarreau61d18892009-03-31 10:49:21 +0200537 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100538 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200539}
540
Willy Tarreaud39ad442016-11-25 15:16:12 +0100541/* report a warning if a block rule is dangerously placed */
542int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200543{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100544 return warnif_rule_after_http_req(proxy, file, line, arg) ||
545 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200546}
547
Willy Tarreau721d8e02017-12-01 18:25:08 +0100548/* report a warning if a block rule is dangerously placed */
549int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200550{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100551 return warnif_rule_after_block(proxy, file, line, arg) ||
552 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200553}
554
Willy Tarreau721d8e02017-12-01 18:25:08 +0100555/* report a warning if a "tcp request content" rule is dangerously placed */
556int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
557{
558 return warnif_rule_after_monitor(proxy, file, line, arg) ||
559 warnif_misplaced_monitor(proxy, file, line, arg);
560}
561
Willy Tarreaud39ad442016-11-25 15:16:12 +0100562/* report a warning if a "tcp request session" rule is dangerously placed */
563int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200564{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100565 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
566 warnif_misplaced_tcp_cont(proxy, file, line, arg);
567}
568
569/* report a warning if a "tcp request connection" rule is dangerously placed */
570int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
571{
572 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
573 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200574}
575
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100576/* Report it if a request ACL condition uses some keywords that are incompatible
577 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
578 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
579 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100580 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100581static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100582{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100583 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200584 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100585
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100586 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100587 return 0;
588
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100589 acl = acl_cond_conflicts(cond, where);
590 if (acl) {
591 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100592 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
593 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100594 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100595 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
596 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100597 return ERR_WARN;
598 }
599 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100600 return 0;
601
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100602 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100603 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
604 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100605 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100606 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
607 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100608 return ERR_WARN;
609}
610
Christopher Faulet62519022017-10-16 15:49:32 +0200611/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100612 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100613 * two such numbers delimited by a dash ('-'). On success, it returns
614 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200615 *
616 * Note: this function can also be used to parse a thread number or a set of
617 * threads.
618 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100619int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200620{
Christopher Faulet26028f62017-11-22 15:01:51 +0100621 if (autoinc) {
622 *autoinc = 0;
623 if (strncmp(arg, "auto:", 5) == 0) {
624 arg += 5;
625 *autoinc = 1;
626 }
627 }
628
Christopher Faulet62519022017-10-16 15:49:32 +0200629 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100630 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200631 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100632 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200633 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100634 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200635 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100636 char *dash;
637 unsigned int low, high;
638
Christopher Faulet5ab51772017-11-22 11:21:58 +0100639 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100640 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100641 return -1;
642 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100643
644 low = high = str2uic(arg);
645 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100646 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
647
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100648 if (high < low) {
649 unsigned int swap = low;
650 low = high;
651 high = swap;
652 }
653
Christopher Faulet5ab51772017-11-22 11:21:58 +0100654 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100655 memprintf(err, "'%s' is not a valid number/range."
656 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100657 arg, LONGBITS);
658 return 1;
659 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100660
661 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100662 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200663 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100664
Christopher Faulet5ab51772017-11-22 11:21:58 +0100665 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200666}
667
David Carlier7e351ee2017-12-01 09:14:02 +0000668#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200669/* Parse cpu sets. Each CPU set is either a unique number between 0 and
670 * <LONGBITS> or a range with two such numbers delimited by a dash
671 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
672 * returns 0. otherwise it returns 1 with an error message in <err>.
673 */
674static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
675{
676 int cur_arg = 0;
677
678 *cpu_set = 0;
679 while (*args[cur_arg]) {
680 char *dash;
681 unsigned int low, high;
682
683 if (!isdigit((int)*args[cur_arg])) {
684 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
685 return -1;
686 }
687
688 low = high = str2uic(args[cur_arg]);
689 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100690 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200691
692 if (high < low) {
693 unsigned int swap = low;
694 low = high;
695 high = swap;
696 }
697
698 if (high >= LONGBITS) {
699 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
700 return 1;
701 }
702
703 while (low <= high)
704 *cpu_set |= 1UL << low++;
705
706 cur_arg++;
707 }
708 return 0;
709}
David Carlier7e351ee2017-12-01 09:14:02 +0000710#endif
711
Willy Tarreaubaaee002006-06-26 02:48:02 +0200712/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200713 * parse a line in a <global> section. Returns the error code, 0 if OK, or
714 * any combination of :
715 * - ERR_ABORT: must abort ASAP
716 * - ERR_FATAL: we can continue parsing but not start the service
717 * - ERR_WARN: a warning has been emitted
718 * - ERR_ALERT: an alert has been emitted
719 * Only the two first ones can stop processing, the two others are just
720 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200721 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200722int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200723{
Willy Tarreau058e9072009-07-20 09:30:05 +0200724 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200725 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200726
727 if (!strcmp(args[0], "global")) { /* new section */
728 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200729 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200730 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200731 }
732 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200733 if (alertif_too_many_args(0, file, linenum, args, &err_code))
734 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200735 global.mode |= MODE_DAEMON;
736 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200737 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200738 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200739 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200740 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100741 if (!strcmp(args[1], "no-exit-on-failure")) {
742 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200743 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100744 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 +0200745 err_code |= ERR_ALERT | ERR_FATAL;
746 goto out;
747 }
748 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200749 global.mode |= MODE_MWORKER;
750 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200751 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200752 if (alertif_too_many_args(0, file, linenum, args, &err_code))
753 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200754 global.mode |= MODE_DEBUG;
755 }
756 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200757 if (alertif_too_many_args(0, file, linenum, args, &err_code))
758 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100759 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200760 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200761 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200762 if (alertif_too_many_args(0, file, linenum, args, &err_code))
763 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100764 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200765 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200766 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200767 if (alertif_too_many_args(0, file, linenum, args, &err_code))
768 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100769 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200770 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100771 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200772 if (alertif_too_many_args(0, file, linenum, args, &err_code))
773 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100774 global.tune.options &= ~GTUNE_USE_SPLICE;
775 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200776 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200777 if (alertif_too_many_args(0, file, linenum, args, &err_code))
778 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200779 global.tune.options &= ~GTUNE_USE_GAI;
780 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000781 else if (!strcmp(args[0], "noreuseport")) {
782 if (alertif_too_many_args(0, file, linenum, args, &err_code))
783 goto out;
784 global.tune.options &= ~GTUNE_USE_REUSEPORT;
785 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200786 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200787 if (alertif_too_many_args(0, file, linenum, args, &err_code))
788 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200789 global.mode |= MODE_QUIET;
790 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200791 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200792 if (alertif_too_many_args(1, file, linenum, args, &err_code))
793 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200794 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100795 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200796 err_code |= ERR_ALERT;
797 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200798 }
799 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100800 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200801 err_code |= ERR_ALERT | ERR_FATAL;
802 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200803 }
804 global.tune.maxpollevents = atol(args[1]);
805 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100806 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200807 if (alertif_too_many_args(1, file, linenum, args, &err_code))
808 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100809 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100810 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200811 err_code |= ERR_ALERT;
812 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100813 }
814 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100815 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200816 err_code |= ERR_ALERT | ERR_FATAL;
817 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100818 }
819 global.tune.maxaccept = atol(args[1]);
820 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200821 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200822 if (alertif_too_many_args(1, file, linenum, args, &err_code))
823 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200824 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100825 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200826 err_code |= ERR_ALERT | ERR_FATAL;
827 goto out;
828 }
829 global.tune.chksize = atol(args[1]);
830 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100831 else if (!strcmp(args[0], "tune.recv_enough")) {
832 if (alertif_too_many_args(1, file, linenum, args, &err_code))
833 goto out;
834 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100835 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100836 err_code |= ERR_ALERT | ERR_FATAL;
837 goto out;
838 }
839 global.tune.recv_enough = atol(args[1]);
840 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100841 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200842 if (alertif_too_many_args(1, file, linenum, args, &err_code))
843 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100844 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100845 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100846 err_code |= ERR_ALERT | ERR_FATAL;
847 goto out;
848 }
849 global.tune.buf_limit = atol(args[1]);
850 if (global.tune.buf_limit) {
851 if (global.tune.buf_limit < 3)
852 global.tune.buf_limit = 3;
853 if (global.tune.buf_limit <= global.tune.reserved_bufs)
854 global.tune.buf_limit = global.tune.reserved_bufs + 1;
855 }
856 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100857 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200858 if (alertif_too_many_args(1, file, linenum, args, &err_code))
859 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100860 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100861 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100862 err_code |= ERR_ALERT | ERR_FATAL;
863 goto out;
864 }
865 global.tune.reserved_bufs = atol(args[1]);
866 if (global.tune.reserved_bufs < 2)
867 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100868 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
869 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100870 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200871 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200872 if (alertif_too_many_args(1, file, linenum, args, &err_code))
873 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200874 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100875 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200876 err_code |= ERR_ALERT | ERR_FATAL;
877 goto out;
878 }
879 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200880 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100881 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200882 err_code |= ERR_ALERT | ERR_FATAL;
883 goto out;
884 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200885 }
886 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200887 if (alertif_too_many_args(1, file, linenum, args, &err_code))
888 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200889 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100890 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200891 err_code |= ERR_ALERT | ERR_FATAL;
892 goto out;
893 }
894 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200895 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100896 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200897 err_code |= ERR_ALERT | ERR_FATAL;
898 goto out;
899 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200900 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100901 else if (!strcmp(args[0], "tune.idletimer")) {
902 unsigned int idle;
903 const char *res;
904
William Lallemand1a748ae2015-05-19 16:37:23 +0200905 if (alertif_too_many_args(1, file, linenum, args, &err_code))
906 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100907 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100908 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 +0100909 err_code |= ERR_ALERT | ERR_FATAL;
910 goto out;
911 }
912
913 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
914 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100915 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100916 file, linenum, *res, args[0]);
917 err_code |= ERR_ALERT | ERR_FATAL;
918 goto out;
919 }
920
921 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100922 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 +0100923 err_code |= ERR_ALERT | ERR_FATAL;
924 goto out;
925 }
926 global.tune.idle_timer = idle;
927 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100928 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200929 if (alertif_too_many_args(1, file, linenum, args, &err_code))
930 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100931 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100932 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100933 err_code |= ERR_ALERT;
934 goto out;
935 }
936 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100937 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100938 err_code |= ERR_ALERT | ERR_FATAL;
939 goto out;
940 }
941 global.tune.client_rcvbuf = atol(args[1]);
942 }
943 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200944 if (alertif_too_many_args(1, file, linenum, args, &err_code))
945 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100946 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100947 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100948 err_code |= ERR_ALERT;
949 goto out;
950 }
951 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100952 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100953 err_code |= ERR_ALERT | ERR_FATAL;
954 goto out;
955 }
956 global.tune.server_rcvbuf = atol(args[1]);
957 }
958 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200959 if (alertif_too_many_args(1, file, linenum, args, &err_code))
960 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100961 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100962 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100963 err_code |= ERR_ALERT;
964 goto out;
965 }
966 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100967 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100968 err_code |= ERR_ALERT | ERR_FATAL;
969 goto out;
970 }
971 global.tune.client_sndbuf = atol(args[1]);
972 }
973 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200974 if (alertif_too_many_args(1, file, linenum, args, &err_code))
975 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100976 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100977 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100978 err_code |= ERR_ALERT;
979 goto out;
980 }
981 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100982 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100983 err_code |= ERR_ALERT | ERR_FATAL;
984 goto out;
985 }
986 global.tune.server_sndbuf = atol(args[1]);
987 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200988 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200989 if (alertif_too_many_args(1, file, linenum, args, &err_code))
990 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200991 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100992 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200993 err_code |= ERR_ALERT | ERR_FATAL;
994 goto out;
995 }
996 global.tune.pipesize = atol(args[1]);
997 }
Willy Tarreau193b8c62012-11-22 00:17:38 +0100998 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200999 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1000 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001001 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001002 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001003 err_code |= ERR_ALERT | ERR_FATAL;
1004 goto out;
1005 }
1006 global.tune.cookie_len = atol(args[1]) + 1;
1007 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001008 else if (!strcmp(args[0], "tune.http.logurilen")) {
1009 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1010 goto out;
1011 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001012 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001013 err_code |= ERR_ALERT | ERR_FATAL;
1014 goto out;
1015 }
1016 global.tune.requri_len = atol(args[1]) + 1;
1017 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001018 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001019 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1020 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001021 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001022 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001023 err_code |= ERR_ALERT | ERR_FATAL;
1024 goto out;
1025 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001026 global.tune.max_http_hdr = atoi(args[1]);
1027 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001028 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1029 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001030 err_code |= ERR_ALERT | ERR_FATAL;
1031 goto out;
1032 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001033 }
William Lallemandf3747832012-11-09 12:33:10 +01001034 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001035 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1036 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001037 if (*args[1]) {
1038 global.tune.comp_maxlevel = atoi(args[1]);
1039 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001040 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1041 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001042 err_code |= ERR_ALERT | ERR_FATAL;
1043 goto out;
1044 }
1045 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001046 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1047 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001048 err_code |= ERR_ALERT | ERR_FATAL;
1049 goto out;
1050 }
1051 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001052 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1053 if (*args[1]) {
1054 global.tune.pattern_cache = atoi(args[1]);
1055 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001056 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1057 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001058 err_code |= ERR_ALERT | ERR_FATAL;
1059 goto out;
1060 }
1061 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001062 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1063 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001064 err_code |= ERR_ALERT | ERR_FATAL;
1065 goto out;
1066 }
1067 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001068 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001069 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1070 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001071 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001072 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001073 err_code |= ERR_ALERT;
1074 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001075 }
1076 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001077 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001078 err_code |= ERR_ALERT | ERR_FATAL;
1079 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001080 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001081 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001082 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 +01001083 err_code |= ERR_WARN;
1084 goto out;
1085 }
1086
Willy Tarreaubaaee002006-06-26 02:48:02 +02001087 }
1088 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001089 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1090 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001091 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001092 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001093 err_code |= ERR_ALERT;
1094 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001095 }
1096 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001097 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001098 err_code |= ERR_ALERT | ERR_FATAL;
1099 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001100 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001101 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001102 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 +01001103 err_code |= ERR_WARN;
1104 goto out;
1105 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001106 }
Simon Horman98637e52014-06-20 12:30:16 +09001107 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001108 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1109 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001110 global.external_check = 1;
1111 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001112 /* user/group name handling */
1113 else if (!strcmp(args[0], "user")) {
1114 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001115 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1116 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001117 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001118 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001119 err_code |= ERR_ALERT;
1120 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001121 }
1122 errno = 0;
1123 ha_user = getpwnam(args[1]);
1124 if (ha_user != NULL) {
1125 global.uid = (int)ha_user->pw_uid;
1126 }
1127 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001128 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 +02001129 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001130 }
1131 }
1132 else if (!strcmp(args[0], "group")) {
1133 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001134 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1135 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001136 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001137 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001138 err_code |= ERR_ALERT;
1139 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001140 }
1141 errno = 0;
1142 ha_group = getgrnam(args[1]);
1143 if (ha_group != NULL) {
1144 global.gid = (int)ha_group->gr_gid;
1145 }
1146 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001147 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 +02001148 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001149 }
1150 }
1151 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001152 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001153 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1154 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001155 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001156 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001157 err_code |= ERR_ALERT | ERR_FATAL;
1158 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001159 }
1160 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001161 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001162 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1163 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001164 err_code |= ERR_ALERT | ERR_FATAL;
1165 goto out;
1166 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001167 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001168 else if (!strcmp(args[0], "nbthread")) {
1169 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1170 goto out;
1171 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001172 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001173 err_code |= ERR_ALERT | ERR_FATAL;
1174 goto out;
1175 }
1176 global.nbthread = atol(args[1]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001177#ifndef USE_THREAD
1178 if (global.nbthread > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 ha_alert("HAProxy is not compiled with threads support, please check build options for USE_THREAD.\n");
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001180 global.nbthread = 1;
1181 err_code |= ERR_ALERT | ERR_FATAL;
1182 goto out;
1183 }
1184#endif
Willy Tarreau421f02e2018-01-20 18:19:22 +01001185 if (global.nbthread < 1 || global.nbthread > MAX_THREADS) {
1186 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1187 file, linenum, args[0], MAX_THREADS, global.nbthread);
1188 err_code |= ERR_ALERT | ERR_FATAL;
1189 goto out;
1190 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001191 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001192 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001193 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1194 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001195 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001196 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001197 err_code |= ERR_ALERT;
1198 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001199 }
1200 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001201 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001202 err_code |= ERR_ALERT | ERR_FATAL;
1203 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001204 }
1205 global.maxconn = atol(args[1]);
1206#ifdef SYSTEM_MAXCONN
1207 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001208 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 +02001209 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001210 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001211 }
1212#endif /* SYSTEM_MAXCONN */
1213 }
Emeric Brun850efd52014-01-29 12:24:34 +01001214 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001215 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1216 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001217 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]);
Emeric Brun850efd52014-01-29 12:24:34 +01001219 err_code |= ERR_ALERT | ERR_FATAL;
1220 goto out;
1221 }
1222 if (strcmp(args[1],"none") == 0)
1223 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1224 else if (strcmp(args[1],"required") == 0)
1225 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1226 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001227 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001228 err_code |= ERR_ALERT | ERR_FATAL;
1229 goto out;
1230 }
1231 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001232 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001233 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1234 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001235 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001236 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001237 err_code |= ERR_ALERT;
1238 goto out;
1239 }
1240 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001241 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001242 err_code |= ERR_ALERT | ERR_FATAL;
1243 goto out;
1244 }
1245 global.cps_lim = atol(args[1]);
1246 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001247 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001248 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1249 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001250 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001251 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001252 err_code |= ERR_ALERT;
1253 goto out;
1254 }
1255 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001256 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001257 err_code |= ERR_ALERT | ERR_FATAL;
1258 goto out;
1259 }
1260 global.sps_lim = atol(args[1]);
1261 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001262 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001263 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1264 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001265 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001266 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001267 err_code |= ERR_ALERT;
1268 goto out;
1269 }
1270 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001271 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001272 err_code |= ERR_ALERT | ERR_FATAL;
1273 goto out;
1274 }
1275 global.ssl_lim = atol(args[1]);
1276 }
William Lallemandd85f9172012-11-09 17:05:39 +01001277 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001278 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1279 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001280 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001281 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 +01001282 err_code |= ERR_ALERT | ERR_FATAL;
1283 goto out;
1284 }
1285 global.comp_rate_lim = atoi(args[1]) * 1024;
1286 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001287 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001288 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1289 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001290 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001291 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001292 err_code |= ERR_ALERT;
1293 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001294 }
1295 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001296 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001297 err_code |= ERR_ALERT | ERR_FATAL;
1298 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001299 }
1300 global.maxpipes = atol(args[1]);
1301 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001302 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001303 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1304 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001305 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001306 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001307 err_code |= ERR_ALERT | ERR_FATAL;
1308 goto out;
1309 }
William Lallemande3a7d992012-11-20 11:25:20 +01001310 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001311 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001312 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001313 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1314 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001315 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001316 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 +01001317 err_code |= ERR_ALERT | ERR_FATAL;
1318 goto out;
1319 }
1320 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001321 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001322 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 +01001323 err_code |= ERR_ALERT | ERR_FATAL;
1324 goto out;
1325 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001326 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001327
Willy Tarreaubaaee002006-06-26 02:48:02 +02001328 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001329 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1330 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001331 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001332 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001333 err_code |= ERR_ALERT;
1334 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001335 }
1336 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001337 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001338 err_code |= ERR_ALERT | ERR_FATAL;
1339 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001340 }
1341 global.rlimit_nofile = atol(args[1]);
1342 }
1343 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001344 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1345 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001346 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001347 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001348 err_code |= ERR_ALERT;
1349 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001350 }
1351 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001352 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001353 err_code |= ERR_ALERT | ERR_FATAL;
1354 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001355 }
1356 global.chroot = strdup(args[1]);
1357 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001358 else if (!strcmp(args[0], "description")) {
1359 int i, len=0;
1360 char *d;
1361
1362 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001363 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1364 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001365 err_code |= ERR_ALERT | ERR_FATAL;
1366 goto out;
1367 }
1368
Willy Tarreau348acfe2014-04-14 15:00:39 +02001369 for (i = 1; *args[i]; i++)
1370 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001371
1372 if (global.desc)
1373 free(global.desc);
1374
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001375 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001376
Willy Tarreau348acfe2014-04-14 15:00:39 +02001377 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1378 for (i = 2; *args[i]; i++)
1379 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001380 }
1381 else if (!strcmp(args[0], "node")) {
1382 int i;
1383 char c;
1384
William Lallemand1a748ae2015-05-19 16:37:23 +02001385 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1386 goto out;
1387
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001388 for (i=0; args[1][i]; i++) {
1389 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001390 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1391 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001392 break;
1393 }
1394
1395 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001396 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1397 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1398 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001399 err_code |= ERR_ALERT | ERR_FATAL;
1400 goto out;
1401 }
1402
1403 if (global.node)
1404 free(global.node);
1405
1406 global.node = strdup(args[1]);
1407 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001408 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001409 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1410 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001411 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001412 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001413 err_code |= ERR_ALERT;
1414 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001415 }
1416 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001417 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 +02001418 err_code |= ERR_ALERT | ERR_FATAL;
1419 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001420 }
1421 global.pidfile = strdup(args[1]);
1422 }
Emeric Bruned760922010-10-22 17:59:25 +02001423 else if (!strcmp(args[0], "unix-bind")) {
1424 int cur_arg = 1;
1425 while (*(args[cur_arg])) {
1426 if (!strcmp(args[cur_arg], "prefix")) {
1427 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001428 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001429 err_code |= ERR_ALERT;
1430 cur_arg += 2;
1431 continue;
1432 }
1433
1434 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001435 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 +02001436 err_code |= ERR_ALERT | ERR_FATAL;
1437 goto out;
1438 }
1439 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1440 cur_arg += 2;
1441 continue;
1442 }
1443
1444 if (!strcmp(args[cur_arg], "mode")) {
1445
1446 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1447 cur_arg += 2;
1448 continue;
1449 }
1450
1451 if (!strcmp(args[cur_arg], "uid")) {
1452
1453 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1454 cur_arg += 2;
1455 continue;
1456 }
1457
1458 if (!strcmp(args[cur_arg], "gid")) {
1459
1460 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1461 cur_arg += 2;
1462 continue;
1463 }
1464
1465 if (!strcmp(args[cur_arg], "user")) {
1466 struct passwd *user;
1467
1468 user = getpwnam(args[cur_arg + 1]);
1469 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001470 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1471 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001472 err_code |= ERR_ALERT | ERR_FATAL;
1473 goto out;
1474 }
1475
1476 global.unix_bind.ux.uid = user->pw_uid;
1477 cur_arg += 2;
1478 continue;
1479 }
1480
1481 if (!strcmp(args[cur_arg], "group")) {
1482 struct group *group;
1483
1484 group = getgrnam(args[cur_arg + 1]);
1485 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001486 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1487 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001488 err_code |= ERR_ALERT | ERR_FATAL;
1489 goto out;
1490 }
1491
1492 global.unix_bind.ux.gid = group->gr_gid;
1493 cur_arg += 2;
1494 continue;
1495 }
1496
Christopher Faulet767a84b2017-11-24 16:50:31 +01001497 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1498 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001499 err_code |= ERR_ALERT | ERR_FATAL;
1500 goto out;
1501 }
1502 }
William Lallemand0f99e342011-10-12 17:50:54 +02001503 else if (!strcmp(args[0], "log") && kwm == KWM_NO) { /* no log */
1504 /* delete previous herited or defined syslog servers */
1505 struct logsrv *back;
1506 struct logsrv *tmp;
1507
1508 if (*(args[1]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001509 ha_alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
William Lallemand0f99e342011-10-12 17:50:54 +02001510 err_code |= ERR_ALERT | ERR_FATAL;
1511 goto out;
1512 }
1513
1514 list_for_each_entry_safe(tmp, back, &global.logsrvs, list) {
1515 LIST_DEL(&tmp->list);
1516 free(tmp);
1517 }
1518 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001519 else if (!strcmp(args[0], "log")) { /* syslog server address */
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001520 struct sockaddr_storage *sk;
1521 int port1, port2;
William Lallemand0f99e342011-10-12 17:50:54 +02001522 struct logsrv *logsrv;
Willy Tarreau18324f52014-06-27 18:10:07 +02001523 int arg = 0;
1524 int len = 0;
William Lallemand0f99e342011-10-12 17:50:54 +02001525
William Lallemand1a748ae2015-05-19 16:37:23 +02001526 if (alertif_too_many_args(8, file, linenum, args, &err_code)) /* does not strictly check optional arguments */
1527 goto out;
1528
Willy Tarreaubaaee002006-06-26 02:48:02 +02001529 if (*(args[1]) == 0 || *(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001530 ha_alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001531 err_code |= ERR_ALERT | ERR_FATAL;
1532 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001533 }
William Lallemand0f99e342011-10-12 17:50:54 +02001534
Vincent Bernat02779b62016-04-03 13:48:43 +02001535 logsrv = calloc(1, sizeof(*logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02001536
Willy Tarreau18324f52014-06-27 18:10:07 +02001537 /* just after the address, a length may be specified */
1538 if (strcmp(args[arg+2], "len") == 0) {
1539 len = atoi(args[arg+3]);
1540 if (len < 80 || len > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001541 ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
1542 file, linenum, args[arg+3]);
Willy Tarreau18324f52014-06-27 18:10:07 +02001543 err_code |= ERR_ALERT | ERR_FATAL;
1544 goto out;
1545 }
1546 logsrv->maxlen = len;
1547
1548 /* skip these two args */
1549 arg += 2;
1550 }
1551 else
1552 logsrv->maxlen = MAX_SYSLOG_LEN;
1553
Christopher Faulet084aa962017-08-29 16:54:41 +02001554 if (logsrv->maxlen > global.max_syslog_len)
Willy Tarreau18324f52014-06-27 18:10:07 +02001555 global.max_syslog_len = logsrv->maxlen;
Willy Tarreau18324f52014-06-27 18:10:07 +02001556
Dragan Dosen1322d092015-09-22 16:05:32 +02001557 /* after the length, a format may be specified */
1558 if (strcmp(args[arg+2], "format") == 0) {
1559 logsrv->format = get_log_format(args[arg+3]);
1560 if (logsrv->format < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001561 ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
Dragan Dosen1322d092015-09-22 16:05:32 +02001562 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01001563 free(logsrv);
Dragan Dosen1322d092015-09-22 16:05:32 +02001564 goto out;
1565 }
1566
1567 /* skip these two args */
1568 arg += 2;
1569 }
1570
David Carlier97880bb2016-04-08 10:35:26 +01001571 if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code)) {
1572 free(logsrv);
William Lallemand1a748ae2015-05-19 16:37:23 +02001573 goto out;
David Carlier97880bb2016-04-08 10:35:26 +01001574 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001575
Willy Tarreau18324f52014-06-27 18:10:07 +02001576 logsrv->facility = get_log_facility(args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02001577 if (logsrv->facility < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001578 ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001579 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001580 logsrv->facility = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001581 }
1582
William Lallemand0f99e342011-10-12 17:50:54 +02001583 logsrv->level = 7; /* max syslog level = debug */
Willy Tarreau18324f52014-06-27 18:10:07 +02001584 if (*(args[arg+3])) {
1585 logsrv->level = get_log_level(args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02001586 if (logsrv->level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001587 ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001588 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001589 logsrv->level = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001590 }
1591 }
1592
William Lallemand0f99e342011-10-12 17:50:54 +02001593 logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
Willy Tarreau18324f52014-06-27 18:10:07 +02001594 if (*(args[arg+4])) {
1595 logsrv->minlvl = get_log_level(args[arg+4]);
William Lallemand0f99e342011-10-12 17:50:54 +02001596 if (logsrv->minlvl < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001597 ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001598 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001599 logsrv->minlvl = 0;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02001600 }
1601 }
1602
Willy Tarreau48ef4c92017-01-06 18:32:38 +01001603 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001604 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001605 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001606 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001607 free(logsrv);
1608 goto out;
1609 }
1610 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001611
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001612 if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001613 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001614 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
1615 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01001616 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001617 free(logsrv);
Willy Tarreaud5191e72010-02-09 20:50:45 +01001618 goto out;
1619 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001620
William Lallemand0f99e342011-10-12 17:50:54 +02001621 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001622 if (!port1)
William Lallemand0f99e342011-10-12 17:50:54 +02001623 set_host_port(&logsrv->addr, SYSLOG_PORT);
Robert Tsai81ae1952007-12-05 10:47:29 +01001624 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001625
William Lallemand0f99e342011-10-12 17:50:54 +02001626 LIST_ADDQ(&global.logsrvs, &logsrv->list);
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001627 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001628 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1629 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001630
1631 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001632 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001633 err_code |= ERR_ALERT;
1634 goto out;
1635 }
1636
1637 if (*(args[1]))
1638 name = args[1];
1639 else
1640 name = hostname;
1641
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001642 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001643 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001644 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001645 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1646 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001647 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001648 err_code |= ERR_ALERT;
1649 goto out;
1650 }
1651
1652 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001653 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001654 err_code |= ERR_FATAL;
1655 goto out;
1656 }
1657
1658 global.server_state_base = strdup(args[1]);
1659 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001660 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1661 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001662 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001663 err_code |= ERR_ALERT;
1664 goto out;
1665 }
1666
1667 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001668 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001669 err_code |= ERR_FATAL;
1670 goto out;
1671 }
1672
1673 global.server_state_file = strdup(args[1]);
1674 }
Kevinm48936af2010-12-22 16:08:21 +00001675 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001676 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1677 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001678 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001679 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001680 err_code |= ERR_ALERT | ERR_FATAL;
1681 goto out;
1682 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001683 chunk_destroy(&global.log_tag);
1684 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001685 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001686 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001687 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1688 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001689 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001690 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001691 err_code |= ERR_ALERT;
1692 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001693 }
1694 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001695 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001696 err_code |= ERR_ALERT | ERR_FATAL;
1697 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001698 }
1699 global.spread_checks = atol(args[1]);
1700 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001701 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 +02001702 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001703 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001704 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001705 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1706 const char *err;
1707 unsigned int val;
1708
William Lallemand1a748ae2015-05-19 16:37:23 +02001709 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1710 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001711 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001712 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001713 err_code |= ERR_ALERT | ERR_FATAL;
1714 goto out;
1715 }
1716
1717 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1718 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001719 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 +02001720 err_code |= ERR_ALERT | ERR_FATAL;
1721 }
1722 global.max_spread_checks = val;
1723 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001724 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001725 err_code |= ERR_ALERT | ERR_FATAL;
1726 }
1727 }
Christopher Faulet62519022017-10-16 15:49:32 +02001728 else if (strcmp(args[0], "cpu-map") == 0) {
1729 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001730#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001731 char *slash;
1732 unsigned long proc = 0, thread = 0, cpus;
1733 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001734
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001735 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001736 ha_alert("parsing [%s:%d] : %s expects a process number "
1737 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1738 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1739 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001740 err_code |= ERR_ALERT | ERR_FATAL;
1741 goto out;
1742 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001743
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001744 if ((slash = strchr(args[1], '/')) != NULL)
1745 *slash = 0;
1746
Christopher Faulet26028f62017-11-22 15:01:51 +01001747 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001748 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001749 err_code |= ERR_ALERT | ERR_FATAL;
1750 goto out;
1751 }
1752
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001753 if (slash) {
1754 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001755 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001756 err_code |= ERR_ALERT | ERR_FATAL;
1757 goto out;
1758 }
1759 *slash = '/';
1760
1761 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001762 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1763 "a process range _AND_ a thread range\n",
1764 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001765 err_code |= ERR_ALERT | ERR_FATAL;
1766 goto out;
1767 }
1768 }
1769
Christopher Faulet62519022017-10-16 15:49:32 +02001770 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001771 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001772 err_code |= ERR_ALERT | ERR_FATAL;
1773 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001774 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001775
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001776 if (autoinc &&
1777 my_popcountl(proc) != my_popcountl(cpus) &&
1778 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001779 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1780 "must have the same size to be automatically bound\n",
1781 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001782 err_code |= ERR_ALERT | ERR_FATAL;
1783 goto out;
1784 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001785
Christopher Faulet26028f62017-11-22 15:01:51 +01001786 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001787 /* No mapping for this process */
1788 if (!(proc & (1UL << i)))
1789 continue;
1790
1791 /* Mapping at the process level */
1792 if (!thread) {
1793 if (!autoinc)
1794 global.cpu_map.proc[i] = cpus;
1795 else {
1796 n += my_ffsl(cpus >> n);
1797 global.cpu_map.proc[i] = (1UL << (n-1));
1798 }
1799 continue;
1800 }
1801
1802 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001803 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001804 /* Np mapping for this thread */
1805 if (!(thread & (1UL << j)))
1806 continue;
1807
1808 if (!autoinc)
1809 global.cpu_map.thread[i][j] = cpus;
1810 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001811 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001812 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001813 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001814 }
1815 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001816#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001817 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1818 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001819 err_code |= ERR_ALERT | ERR_FATAL;
1820 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001821#endif /* ! USE_CPU_AFFINITY */
1822 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001823 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1824 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1825 goto out;
1826
1827 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001828 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001829 err_code |= ERR_ALERT | ERR_FATAL;
1830 goto out;
1831 }
1832
1833 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1834 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001835 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 +01001836 err_code |= ERR_ALERT | ERR_FATAL;
1837 goto out;
1838 }
1839 }
1840 else if (!strcmp(args[0], "unsetenv")) {
1841 int arg;
1842
1843 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001844 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001845 err_code |= ERR_ALERT | ERR_FATAL;
1846 goto out;
1847 }
1848
1849 for (arg = 1; *args[arg]; arg++) {
1850 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001851 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 +01001852 err_code |= ERR_ALERT | ERR_FATAL;
1853 goto out;
1854 }
1855 }
1856 }
1857 else if (!strcmp(args[0], "resetenv")) {
1858 extern char **environ;
1859 char **env = environ;
1860
1861 /* args contain variable names to keep, one per argument */
1862 while (*env) {
1863 int arg;
1864
1865 /* look for current variable in among all those we want to keep */
1866 for (arg = 1; *args[arg]; arg++) {
1867 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1868 (*env)[strlen(args[arg])] == '=')
1869 break;
1870 }
1871
1872 /* delete this variable */
1873 if (!*args[arg]) {
1874 char *delim = strchr(*env, '=');
1875
1876 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001877 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 +01001878 err_code |= ERR_ALERT | ERR_FATAL;
1879 goto out;
1880 }
1881
1882 memcpy(trash.str, *env, delim - *env);
1883 trash.str[delim - *env] = 0;
1884
1885 if (unsetenv(trash.str) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001886 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 +01001887 err_code |= ERR_ALERT | ERR_FATAL;
1888 goto out;
1889 }
1890 }
1891 else
1892 env++;
1893 }
1894 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001895 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001896 struct cfg_kw_list *kwl;
1897 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001898 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001899
1900 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1901 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1902 if (kwl->kw[index].section != CFG_GLOBAL)
1903 continue;
1904 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001905 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001906 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001907 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001908 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001909 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001910 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001911 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001912 err_code |= ERR_WARN;
1913 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001914 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001915 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001916 }
1917 }
1918 }
1919
Christopher Faulet767a84b2017-11-24 16:50:31 +01001920 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001921 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001922 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001923
Willy Tarreau058e9072009-07-20 09:30:05 +02001924 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001925 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001926 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001927}
1928
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001929void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001930{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001931 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001932 defproxy.mode = PR_MODE_TCP;
1933 defproxy.state = PR_STNEW;
1934 defproxy.maxconn = cfg_maxpconn;
1935 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001936 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001937 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001938
Simon Horman66183002013-02-23 10:16:43 +09001939 defproxy.defsrv.check.inter = DEF_CHKINTR;
1940 defproxy.defsrv.check.fastinter = 0;
1941 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001942 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1943 defproxy.defsrv.agent.fastinter = 0;
1944 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001945 defproxy.defsrv.check.rise = DEF_RISETIME;
1946 defproxy.defsrv.check.fall = DEF_FALLTIME;
1947 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1948 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001949 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001950 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001951 defproxy.defsrv.maxqueue = 0;
1952 defproxy.defsrv.minconn = 0;
1953 defproxy.defsrv.maxconn = 0;
1954 defproxy.defsrv.slowstart = 0;
1955 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1956 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1957 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001958
1959 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001960 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001961}
1962
Willy Tarreauade5ec42010-01-28 19:33:49 +01001963
Willy Tarreau63af98d2014-05-18 08:11:41 +02001964/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1965 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1966 * ERR_FATAL in case of error.
1967 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001968static int create_cond_regex_rule(const char *file, int line,
1969 struct proxy *px, int dir, int action, int flags,
1970 const char *cmd, const char *reg, const char *repl,
1971 const char **cond_start)
1972{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001973 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001974 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001975 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001976 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001977 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001978 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001979 int cs;
1980 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001981
1982 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001983 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001984 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001985 goto err;
1986 }
1987
1988 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001989 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001990 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001991 goto err;
1992 }
1993
Christopher Faulet898566e2016-10-26 11:06:28 +02001994 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001995 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001996
Willy Tarreau5321c422010-01-28 20:35:13 +01001997 if (cond_start &&
1998 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001999 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002000 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
2001 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002002 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01002003 goto err;
2004 }
2005 }
2006 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002007 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
2008 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002009 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01002010 goto err;
2011 }
2012
Willy Tarreau63af98d2014-05-18 08:11:41 +02002013 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01002014 (dir == SMP_OPT_DIR_REQ) ?
2015 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
2016 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
2017 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01002018
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002019 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01002020 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002021 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002022 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002023 goto err;
2024 }
2025
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002026 cs = !(flags & REG_ICASE);
2027 cap = !(flags & REG_NOSUB);
2028 error = NULL;
2029 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002030 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002031 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002032 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002033 goto err;
2034 }
2035
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02002036 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01002037 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01002038 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002039 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
2040 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002041 ret_code |= ERR_ALERT | ERR_FATAL;
2042 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002043 }
2044
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02002045 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02002046 ret_code |= ERR_WARN;
2047
2048 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002049
Willy Tarreau63af98d2014-05-18 08:11:41 +02002050 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002051 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01002052 err:
2053 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002054 free(errmsg);
2055 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002056}
2057
Willy Tarreaubaaee002006-06-26 02:48:02 +02002058/*
William Lallemand51097192015-04-14 16:35:22 +02002059 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02002060 * Returns the error code, 0 if OK, or any combination of :
2061 * - ERR_ABORT: must abort ASAP
2062 * - ERR_FATAL: we can continue parsing but not start the service
2063 * - ERR_WARN: a warning has been emitted
2064 * - ERR_ALERT: an alert has been emitted
2065 * Only the two first ones can stop processing, the two others are just
2066 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02002067 */
Emeric Brun32da3c42010-09-23 18:39:19 +02002068int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
2069{
2070 static struct peers *curpeers = NULL;
2071 struct peer *newpeer = NULL;
2072 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002073 struct bind_conf *bind_conf;
2074 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02002075 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01002076 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002077
2078 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002079 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002080 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01002081 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002082 goto out;
2083 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002084
William Lallemand6e62fb62015-04-28 16:55:23 +02002085 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2086 goto out;
2087
Emeric Brun32da3c42010-09-23 18:39:19 +02002088 err = invalid_char(args[1]);
2089 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002090 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2091 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01002092 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002093 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002094 }
2095
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002096 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02002097 /*
2098 * If there are two proxies with the same name only following
2099 * combinations are allowed:
2100 */
2101 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002102 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2103 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002104 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002105 }
2106 }
2107
Vincent Bernat02779b62016-04-03 13:48:43 +02002108 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002109 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002110 err_code |= ERR_ALERT | ERR_ABORT;
2111 goto out;
2112 }
2113
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002114 curpeers->next = cfg_peers;
2115 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002116 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002117 curpeers->conf.line = linenum;
2118 curpeers->last_change = now.tv_sec;
2119 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002120 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002121 }
2122 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002123 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002124 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002125 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002126
2127 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002128 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2129 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002130 err_code |= ERR_ALERT | ERR_FATAL;
2131 goto out;
2132 }
2133
2134 err = invalid_char(args[1]);
2135 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002136 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2137 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002138 err_code |= ERR_ALERT | ERR_FATAL;
2139 goto out;
2140 }
2141
Vincent Bernat02779b62016-04-03 13:48:43 +02002142 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002143 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002144 err_code |= ERR_ALERT | ERR_ABORT;
2145 goto out;
2146 }
2147
2148 /* the peers are linked backwards first */
2149 curpeers->count++;
2150 newpeer->next = curpeers->remote;
2151 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002152 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002153 newpeer->conf.line = linenum;
2154
2155 newpeer->last_change = now.tv_sec;
2156 newpeer->id = strdup(args[1]);
2157
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002158 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002159 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002160 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002161 err_code |= ERR_ALERT | ERR_FATAL;
2162 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002163 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002164
2165 proto = protocol_by_family(sk->ss_family);
2166 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002167 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2168 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002169 err_code |= ERR_ALERT | ERR_FATAL;
2170 goto out;
2171 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002172
2173 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002174 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2175 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002176 err_code |= ERR_ALERT | ERR_FATAL;
2177 goto out;
2178 }
2179
Willy Tarreau2aa38802013-02-20 19:20:59 +01002180 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002181 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2182 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002183 err_code |= ERR_ALERT | ERR_FATAL;
2184 goto out;
2185 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002186
Emeric Brun32da3c42010-09-23 18:39:19 +02002187 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002188 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002189 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002190 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002191 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002192
Emeric Brun32da3c42010-09-23 18:39:19 +02002193 if (strcmp(newpeer->id, localpeer) == 0) {
2194 /* Current is local peer, it define a frontend */
2195 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002196 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002197
2198 if (!curpeers->peers_fe) {
2199 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002200 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002201 err_code |= ERR_ALERT | ERR_ABORT;
2202 goto out;
2203 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002204
Willy Tarreau237250c2011-07-29 01:49:03 +02002205 init_new_proxy(curpeers->peers_fe);
2206 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002207 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002208 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2209 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002210 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002211
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002212 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002213
Willy Tarreau902636f2013-03-10 19:44:48 +01002214 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2215 if (errmsg && *errmsg) {
2216 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002217 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002218 }
2219 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002220 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2221 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002222 err_code |= ERR_FATAL;
2223 goto out;
2224 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002225
2226 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002227 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002228 l->maxconn = curpeers->peers_fe->maxconn;
2229 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002230 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002231 l->analysers |= curpeers->peers_fe->fe_req_ana;
2232 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002233 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2234 global.maxsock += l->maxconn;
2235 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002236 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002237 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002238 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2239 file, linenum, args[0], args[1],
2240 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002241 err_code |= ERR_FATAL;
2242 goto out;
2243 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002244 }
2245 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002246 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2247 curpeers->state = PR_STSTOPPED;
2248 }
2249 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2250 curpeers->state = PR_STNEW;
2251 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002252 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002253 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002254 err_code |= ERR_ALERT | ERR_FATAL;
2255 goto out;
2256 }
2257
2258out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002259 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002260 return err_code;
2261}
2262
Baptiste Assmann325137d2015-04-13 23:40:55 +02002263/*
2264 * Parse a <resolvers> section.
2265 * Returns the error code, 0 if OK, or any combination of :
2266 * - ERR_ABORT: must abort ASAP
2267 * - ERR_FATAL: we can continue parsing but not start the service
2268 * - ERR_WARN: a warning has been emitted
2269 * - ERR_ALERT: an alert has been emitted
2270 * Only the two first ones can stop processing, the two others are just
2271 * indicators.
2272 */
2273int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2274{
2275 static struct dns_resolvers *curr_resolvers = NULL;
2276 struct dns_nameserver *newnameserver = NULL;
2277 const char *err;
2278 int err_code = 0;
2279 char *errmsg = NULL;
2280
2281 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2282 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002283 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002284 err_code |= ERR_ALERT | ERR_ABORT;
2285 goto out;
2286 }
2287
2288 err = invalid_char(args[1]);
2289 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002290 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2291 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002292 err_code |= ERR_ALERT | ERR_ABORT;
2293 goto out;
2294 }
2295
2296 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2297 /* Error if two resolvers owns the same name */
2298 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002299 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2300 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002301 err_code |= ERR_ALERT | ERR_ABORT;
2302 }
2303 }
2304
Vincent Bernat02779b62016-04-03 13:48:43 +02002305 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002306 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002307 err_code |= ERR_ALERT | ERR_ABORT;
2308 goto out;
2309 }
2310
2311 /* default values */
2312 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2313 curr_resolvers->conf.file = strdup(file);
2314 curr_resolvers->conf.line = linenum;
2315 curr_resolvers->id = strdup(args[1]);
2316 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002317 /* default maximum response size */
2318 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002319 /* default hold period for nx, other, refuse and timeout is 30s */
2320 curr_resolvers->hold.nx = 30000;
2321 curr_resolvers->hold.other = 30000;
2322 curr_resolvers->hold.refused = 30000;
2323 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002324 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002325 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002326 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002327 curr_resolvers->timeout.resolve = 1000;
2328 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002329 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002330 curr_resolvers->nb_nameservers = 0;
2331 LIST_INIT(&curr_resolvers->nameservers);
2332 LIST_INIT(&curr_resolvers->resolutions.curr);
2333 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002334 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002335 }
2336 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2337 struct sockaddr_storage *sk;
2338 int port1, port2;
2339 struct protocol *proto;
2340
2341 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002342 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2343 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002344 err_code |= ERR_ALERT | ERR_FATAL;
2345 goto out;
2346 }
2347
2348 err = invalid_char(args[1]);
2349 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002350 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2351 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002352 err_code |= ERR_ALERT | ERR_FATAL;
2353 goto out;
2354 }
2355
Christopher Faulet67957bd2017-09-27 11:00:59 +02002356 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002357 /* Error if two resolvers owns the same name */
2358 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002359 ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
2360 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002361 err_code |= ERR_ALERT | ERR_FATAL;
2362 }
2363 }
2364
Vincent Bernat02779b62016-04-03 13:48:43 +02002365 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002366 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002367 err_code |= ERR_ALERT | ERR_ABORT;
2368 goto out;
2369 }
2370
2371 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002372 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002373 newnameserver->resolvers = curr_resolvers;
2374 newnameserver->conf.file = strdup(file);
2375 newnameserver->conf.line = linenum;
2376 newnameserver->id = strdup(args[1]);
2377
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002378 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002379 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002380 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002381 err_code |= ERR_ALERT | ERR_FATAL;
2382 goto out;
2383 }
2384
2385 proto = protocol_by_family(sk->ss_family);
2386 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002387 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002388 file, linenum, args[0], args[1]);
2389 err_code |= ERR_ALERT | ERR_FATAL;
2390 goto out;
2391 }
2392
2393 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002394 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2395 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002396 err_code |= ERR_ALERT | ERR_FATAL;
2397 goto out;
2398 }
2399
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002400 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002401 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2402 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002403 err_code |= ERR_ALERT | ERR_FATAL;
2404 goto out;
2405 }
2406
Baptiste Assmann325137d2015-04-13 23:40:55 +02002407 newnameserver->addr = *sk;
2408 }
2409 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2410 const char *res;
2411 unsigned int time;
2412
2413 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002414 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2415 file, linenum, args[0]);
2416 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002417 err_code |= ERR_ALERT | ERR_FATAL;
2418 goto out;
2419 }
2420 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2421 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002422 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2423 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002424 err_code |= ERR_ALERT | ERR_FATAL;
2425 goto out;
2426 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002427 if (strcmp(args[1], "nx") == 0)
2428 curr_resolvers->hold.nx = time;
2429 else if (strcmp(args[1], "other") == 0)
2430 curr_resolvers->hold.other = time;
2431 else if (strcmp(args[1], "refused") == 0)
2432 curr_resolvers->hold.refused = time;
2433 else if (strcmp(args[1], "timeout") == 0)
2434 curr_resolvers->hold.timeout = time;
2435 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002436 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002437 else if (strcmp(args[1], "obsolete") == 0)
2438 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002439 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002440 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2441 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002442 err_code |= ERR_ALERT | ERR_FATAL;
2443 goto out;
2444 }
2445
2446 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002447 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002448 int i = 0;
2449
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002450 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002451 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2452 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002453 err_code |= ERR_ALERT | ERR_FATAL;
2454 goto out;
2455 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002456
2457 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002458 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002459 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2460 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002461 err_code |= ERR_ALERT | ERR_FATAL;
2462 goto out;
2463 }
2464
2465 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002466 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002467 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002468 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2469 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002470 err_code |= ERR_WARN;
2471 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002472 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002473 else if (strcmp(args[0], "resolve_retries") == 0) {
2474 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002475 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2476 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002477 err_code |= ERR_ALERT | ERR_FATAL;
2478 goto out;
2479 }
2480 curr_resolvers->resolve_retries = atoi(args[1]);
2481 }
2482 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002483 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002484 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2485 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002486 err_code |= ERR_ALERT | ERR_FATAL;
2487 goto out;
2488 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002489 else if (strcmp(args[1], "retry") == 0 ||
2490 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002491 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002492 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002493
2494 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002495 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2496 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002497 err_code |= ERR_ALERT | ERR_FATAL;
2498 goto out;
2499 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002500 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002501 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002502 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2503 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002504 err_code |= ERR_ALERT | ERR_FATAL;
2505 goto out;
2506 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002507 if (args[1][2] == 't')
2508 curr_resolvers->timeout.retry = tout;
2509 else
2510 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002511 }
2512 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002513 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2514 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002515 err_code |= ERR_ALERT | ERR_FATAL;
2516 goto out;
2517 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002518 } /* neither "nameserver" nor "resolvers" */
2519 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002520 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002521 err_code |= ERR_ALERT | ERR_FATAL;
2522 goto out;
2523 }
2524
2525 out:
2526 free(errmsg);
2527 return err_code;
2528}
Simon Horman0d16a402015-01-30 11:22:58 +09002529
2530/*
William Lallemand51097192015-04-14 16:35:22 +02002531 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002532 * Returns the error code, 0 if OK, or any combination of :
2533 * - ERR_ABORT: must abort ASAP
2534 * - ERR_FATAL: we can continue parsing but not start the service
2535 * - ERR_WARN: a warning has been emitted
2536 * - ERR_ALERT: an alert has been emitted
2537 * Only the two first ones can stop processing, the two others are just
2538 * indicators.
2539 */
2540int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2541{
2542 static struct mailers *curmailers = NULL;
2543 struct mailer *newmailer = NULL;
2544 const char *err;
2545 int err_code = 0;
2546 char *errmsg = NULL;
2547
2548 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2549 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002550 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002551 err_code |= ERR_ALERT | ERR_ABORT;
2552 goto out;
2553 }
2554
2555 err = invalid_char(args[1]);
2556 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002557 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2558 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002559 err_code |= ERR_ALERT | ERR_ABORT;
2560 goto out;
2561 }
2562
2563 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2564 /*
2565 * If there are two proxies with the same name only following
2566 * combinations are allowed:
2567 */
2568 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002569 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2570 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002571 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002572 }
2573 }
2574
Vincent Bernat02779b62016-04-03 13:48:43 +02002575 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002576 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002577 err_code |= ERR_ALERT | ERR_ABORT;
2578 goto out;
2579 }
2580
2581 curmailers->next = mailers;
2582 mailers = curmailers;
2583 curmailers->conf.file = strdup(file);
2584 curmailers->conf.line = linenum;
2585 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002586 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2587 * But need enough time so that timeouts don't occur
2588 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002589 }
2590 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2591 struct sockaddr_storage *sk;
2592 int port1, port2;
2593 struct protocol *proto;
2594
2595 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002596 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2597 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002598 err_code |= ERR_ALERT | ERR_FATAL;
2599 goto out;
2600 }
2601
2602 err = invalid_char(args[1]);
2603 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002604 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2605 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002606 err_code |= ERR_ALERT | ERR_FATAL;
2607 goto out;
2608 }
2609
Vincent Bernat02779b62016-04-03 13:48:43 +02002610 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002611 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002612 err_code |= ERR_ALERT | ERR_ABORT;
2613 goto out;
2614 }
2615
2616 /* the mailers are linked backwards first */
2617 curmailers->count++;
2618 newmailer->next = curmailers->mailer_list;
2619 curmailers->mailer_list = newmailer;
2620 newmailer->mailers = curmailers;
2621 newmailer->conf.file = strdup(file);
2622 newmailer->conf.line = linenum;
2623
2624 newmailer->id = strdup(args[1]);
2625
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002626 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002627 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002628 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002629 err_code |= ERR_ALERT | ERR_FATAL;
2630 goto out;
2631 }
2632
2633 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002634 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002635 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2636 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002637 err_code |= ERR_ALERT | ERR_FATAL;
2638 goto out;
2639 }
2640
2641 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002642 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2643 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002644 err_code |= ERR_ALERT | ERR_FATAL;
2645 goto out;
2646 }
2647
2648 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002649 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2650 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002651 err_code |= ERR_ALERT | ERR_FATAL;
2652 goto out;
2653 }
2654
2655 newmailer->addr = *sk;
2656 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002657 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002658 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002659 }
2660 else if (strcmp(args[0], "timeout") == 0) {
2661 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002662 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2663 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002664 err_code |= ERR_ALERT | ERR_FATAL;
2665 goto out;
2666 }
2667 else if (strcmp(args[1], "mail") == 0) {
2668 const char *res;
2669 unsigned int timeout_mail;
2670 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002671 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2672 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002673 err_code |= ERR_ALERT | ERR_FATAL;
2674 goto out;
2675 }
2676 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2677 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002678 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2679 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002680 err_code |= ERR_ALERT | ERR_FATAL;
2681 goto out;
2682 }
2683 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002684 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 +01002685 err_code |= ERR_ALERT | ERR_FATAL;
2686 goto out;
2687 }
2688 curmailers->timeout.mail = timeout_mail;
2689 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002690 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002691 file, linenum, args[0], args[1]);
2692 err_code |= ERR_ALERT | ERR_FATAL;
2693 goto out;
2694 }
2695 }
Simon Horman0d16a402015-01-30 11:22:58 +09002696 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002697 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002698 err_code |= ERR_ALERT | ERR_FATAL;
2699 goto out;
2700 }
2701
2702out:
2703 free(errmsg);
2704 return err_code;
2705}
2706
Simon Horman9dc49962015-01-30 11:22:59 +09002707static void free_email_alert(struct proxy *p)
2708{
2709 free(p->email_alert.mailers.name);
2710 p->email_alert.mailers.name = NULL;
2711 free(p->email_alert.from);
2712 p->email_alert.from = NULL;
2713 free(p->email_alert.to);
2714 p->email_alert.to = NULL;
2715 free(p->email_alert.myhostname);
2716 p->email_alert.myhostname = NULL;
2717}
2718
Willy Tarreau3842f002009-06-14 11:39:52 +02002719int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002720{
2721 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002722 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002723 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002724 int rc;
2725 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002726 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002727 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002728 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002729 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002730 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002731
Willy Tarreau977b8e42006-12-29 14:19:17 +01002732 if (!strcmp(args[0], "listen"))
2733 rc = PR_CAP_LISTEN;
2734 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002735 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002736 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002737 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002738 else
2739 rc = PR_CAP_NONE;
2740
2741 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002742 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002743 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2744 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2745 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002746 err_code |= ERR_ALERT | ERR_ABORT;
2747 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002748 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002749
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002750 err = invalid_char(args[1]);
2751 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002752 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2753 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002754 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002755 }
2756
Willy Tarreau8f50b682015-05-26 11:45:02 +02002757 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2758 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002759 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2760 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2761 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002762 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002763 }
2764
Vincent Bernat02779b62016-04-03 13:48:43 +02002765 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002766 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002767 err_code |= ERR_ALERT | ERR_ABORT;
2768 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002769 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002770
Willy Tarreau97cb7802010-01-03 20:23:58 +01002771 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002772 curproxy->next = proxies_list;
2773 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002774 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2775 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002776 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002777 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002778 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002779 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002780
William Lallemand6e62fb62015-04-28 16:55:23 +02002781 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2782 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002783 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002784 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002785 }
2786
2787 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002788 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002789 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002790
Willy Tarreaubaaee002006-06-26 02:48:02 +02002791 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002792 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002793 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002794 curproxy->no_options = defproxy.no_options;
2795 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002796 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002797 curproxy->except_net = defproxy.except_net;
2798 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002799 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002800 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002801
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002802 if (defproxy.fwdfor_hdr_len) {
2803 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2804 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2805 }
2806
Willy Tarreaub86db342009-11-30 11:50:16 +01002807 if (defproxy.orgto_hdr_len) {
2808 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2809 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2810 }
2811
Mark Lamourinec2247f02012-01-04 13:02:01 -05002812 if (defproxy.server_id_hdr_len) {
2813 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2814 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2815 }
2816
Willy Tarreau977b8e42006-12-29 14:19:17 +01002817 if (curproxy->cap & PR_CAP_FE) {
2818 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002819 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002820 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002821
2822 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002823 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2824 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002825
2826 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2827 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002828
Willy Tarreau977b8e42006-12-29 14:19:17 +01002829 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002830 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002831 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002832 curproxy->fullconn = defproxy.fullconn;
2833 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002834 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002835 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002836
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002837 if (defproxy.check_req) {
2838 curproxy->check_req = calloc(1, defproxy.check_len);
2839 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2840 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002841 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002842
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002843 if (defproxy.expect_str) {
2844 curproxy->expect_str = strdup(defproxy.expect_str);
2845 if (defproxy.expect_regex) {
2846 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002847 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2848 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002849 }
2850 }
2851
Willy Tarreau67402132012-05-31 20:40:20 +02002852 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002853 if (defproxy.cookie_name)
2854 curproxy->cookie_name = strdup(defproxy.cookie_name);
2855 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002856
2857 if (defproxy.dyncookie_key)
2858 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002859 if (defproxy.cookie_domain)
2860 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002861
Willy Tarreau31936852010-10-06 16:59:56 +02002862 if (defproxy.cookie_maxidle)
2863 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2864
2865 if (defproxy.cookie_maxlife)
2866 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2867
Emeric Brun647caf12009-06-30 17:57:00 +02002868 if (defproxy.rdp_cookie_name)
2869 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2870 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2871
Willy Tarreau01732802007-11-01 22:48:15 +01002872 if (defproxy.url_param_name)
2873 curproxy->url_param_name = strdup(defproxy.url_param_name);
2874 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002875
Benoitaffb4812009-03-25 13:02:10 +01002876 if (defproxy.hh_name)
2877 curproxy->hh_name = strdup(defproxy.hh_name);
2878 curproxy->hh_len = defproxy.hh_len;
2879 curproxy->hh_match_domain = defproxy.hh_match_domain;
2880
Willy Tarreauef9a3602012-12-08 22:29:20 +01002881 if (defproxy.conn_src.iface_name)
2882 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2883 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002884 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002885#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002886 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002887#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002888 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002889 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002890
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002891 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002892 if (defproxy.capture_name)
2893 curproxy->capture_name = strdup(defproxy.capture_name);
2894 curproxy->capture_namelen = defproxy.capture_namelen;
2895 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002896 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002897
Willy Tarreau977b8e42006-12-29 14:19:17 +01002898 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002899 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002900 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002901 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002902 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002903 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002904 curproxy->mon_net = defproxy.mon_net;
2905 curproxy->mon_mask = defproxy.mon_mask;
2906 if (defproxy.monitor_uri)
2907 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2908 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002909 if (defproxy.defbe.name)
2910 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002911
2912 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002913 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2914 if (curproxy->conf.logformat_string &&
2915 curproxy->conf.logformat_string != default_http_log_format &&
2916 curproxy->conf.logformat_string != default_tcp_log_format &&
2917 curproxy->conf.logformat_string != clf_http_log_format)
2918 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2919
2920 if (defproxy.conf.lfs_file) {
2921 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2922 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2923 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002924
2925 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2926 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2927 if (curproxy->conf.logformat_sd_string &&
2928 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2929 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2930
2931 if (defproxy.conf.lfsd_file) {
2932 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2933 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2934 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002935 }
2936
2937 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002938 curproxy->timeout.connect = defproxy.timeout.connect;
2939 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002940 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002941 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002942 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002943 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002944 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002945 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002946 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002947 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002948 }
2949
Willy Tarreaubaaee002006-06-26 02:48:02 +02002950 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002951 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002952
2953 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002954 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002955 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002956 memcpy(node, tmplogsrv, sizeof(struct logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02002957 LIST_INIT(&node->list);
2958 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2959 }
2960
Willy Tarreau62a61232013-04-12 18:13:46 +02002961 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2962 if (curproxy->conf.uniqueid_format_string)
2963 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2964
Dragan Dosen43885c72015-10-01 13:18:13 +02002965 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002966
Willy Tarreau62a61232013-04-12 18:13:46 +02002967 if (defproxy.conf.uif_file) {
2968 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2969 curproxy->conf.uif_line = defproxy.conf.uif_line;
2970 }
William Lallemanda73203e2012-03-12 12:48:57 +01002971
2972 /* copy default header unique id */
2973 if (defproxy.header_unique_id)
2974 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2975
William Lallemand82fe75c2012-10-23 10:25:10 +02002976 /* default compression options */
2977 if (defproxy.comp != NULL) {
2978 curproxy->comp = calloc(1, sizeof(struct comp));
2979 curproxy->comp->algos = defproxy.comp->algos;
2980 curproxy->comp->types = defproxy.comp->types;
2981 }
2982
Willy Tarreaubaaee002006-06-26 02:48:02 +02002983 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002984 curproxy->conf.used_listener_id = EB_ROOT;
2985 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002986
Simon Horman98637e52014-06-20 12:30:16 +09002987 if (defproxy.check_path)
2988 curproxy->check_path = strdup(defproxy.check_path);
2989 if (defproxy.check_command)
2990 curproxy->check_command = strdup(defproxy.check_command);
2991
Simon Horman9dc49962015-01-30 11:22:59 +09002992 if (defproxy.email_alert.mailers.name)
2993 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
2994 if (defproxy.email_alert.from)
2995 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
2996 if (defproxy.email_alert.to)
2997 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
2998 if (defproxy.email_alert.myhostname)
2999 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003000 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003001 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003002
Willy Tarreau93893792009-07-23 13:19:11 +02003003 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003004 }
3005 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3006 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003007 /* FIXME-20070101: we should do this too at the end of the
3008 * config parsing to free all default values.
3009 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003010 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3011 err_code |= ERR_ABORT;
3012 goto out;
3013 }
3014
Willy Tarreaua534fea2008-08-03 12:19:50 +02003015 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003016 free(defproxy.check_command);
3017 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003018 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003019 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003020 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003021 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003022 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003023 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003024 free(defproxy.capture_name);
3025 free(defproxy.monitor_uri);
3026 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003027 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003028 free(defproxy.fwdfor_hdr_name);
3029 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003030 free(defproxy.orgto_hdr_name);
3031 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003032 free(defproxy.server_id_hdr_name);
3033 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003034 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003035 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003036 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003037 free(defproxy.expect_regex);
3038 defproxy.expect_regex = NULL;
3039 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003040
Willy Tarreau62a61232013-04-12 18:13:46 +02003041 if (defproxy.conf.logformat_string != default_http_log_format &&
3042 defproxy.conf.logformat_string != default_tcp_log_format &&
3043 defproxy.conf.logformat_string != clf_http_log_format)
3044 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003045
Willy Tarreau62a61232013-04-12 18:13:46 +02003046 free(defproxy.conf.uniqueid_format_string);
3047 free(defproxy.conf.lfs_file);
3048 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003049 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003050 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003051
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003052 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3053 free(defproxy.conf.logformat_sd_string);
3054 free(defproxy.conf.lfsd_file);
3055
Willy Tarreaua534fea2008-08-03 12:19:50 +02003056 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003057 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003058
Willy Tarreaubaaee002006-06-26 02:48:02 +02003059 /* we cannot free uri_auth because it might already be used */
3060 init_default_instance();
3061 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003062 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3063 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003064 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003065 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003066 }
3067 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003068 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003069 err_code |= ERR_ALERT | ERR_FATAL;
3070 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003071 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003072
3073 /* update the current file and line being parsed */
3074 curproxy->conf.args.file = curproxy->conf.file;
3075 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003076
3077 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003078 if (!strcmp(args[0], "server") ||
3079 !strcmp(args[0], "default-server") ||
3080 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003081 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3082 if (err_code & ERR_FATAL)
3083 goto out;
3084 }
3085 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003086 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003087 int cur_arg;
3088
Willy Tarreaubaaee002006-06-26 02:48:02 +02003089 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003090 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003091 err_code |= ERR_ALERT | ERR_FATAL;
3092 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003093 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003094 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003095 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003096
Willy Tarreau24709282013-03-10 21:32:12 +01003097 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003098 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3099 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003100 err_code |= ERR_ALERT | ERR_FATAL;
3101 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003102 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003103
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003104 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003105
3106 /* use default settings for unix sockets */
3107 bind_conf->ux.uid = global.unix_bind.ux.uid;
3108 bind_conf->ux.gid = global.unix_bind.ux.gid;
3109 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003110
3111 /* NOTE: the following line might create several listeners if there
3112 * are comma-separated IPs or port ranges. So all further processing
3113 * will have to be applied to all listeners created after last_listen.
3114 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003115 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3116 if (errmsg && *errmsg) {
3117 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003118 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003119 }
3120 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003121 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3122 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003123 err_code |= ERR_ALERT | ERR_FATAL;
3124 goto out;
3125 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003126
Willy Tarreau4348fad2012-09-20 16:48:07 +02003127 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3128 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003129 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003130 }
3131
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003132 cur_arg = 2;
3133 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003134 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003135 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003136 char *err;
3137
Willy Tarreau26982662012-09-12 23:17:10 +02003138 kw = bind_find_kw(args[cur_arg]);
3139 if (kw) {
3140 char *err = NULL;
3141 int code;
3142
3143 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003144 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3145 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003146 cur_arg += 1 + kw->skip ;
3147 err_code |= ERR_ALERT | ERR_FATAL;
3148 goto out;
3149 }
3150
Willy Tarreau4348fad2012-09-20 16:48:07 +02003151 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003152 err_code |= code;
3153
3154 if (code) {
3155 if (err && *err) {
3156 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003157 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003158 }
3159 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003160 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3161 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003162 if (code & ERR_FATAL) {
3163 free(err);
3164 cur_arg += 1 + kw->skip;
3165 goto out;
3166 }
3167 }
3168 free(err);
3169 cur_arg += 1 + kw->skip;
3170 continue;
3171 }
3172
Willy Tarreau8638f482012-09-18 18:01:17 +02003173 err = NULL;
3174 if (!bind_dumped) {
3175 bind_dump_kws(&err);
3176 indent_msg(&err, 4);
3177 bind_dumped = 1;
3178 }
3179
Christopher Faulet767a84b2017-11-24 16:50:31 +01003180 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3181 file, linenum, args[0], args[1], args[cur_arg],
3182 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003183 free(err);
3184
Willy Tarreau93893792009-07-23 13:19:11 +02003185 err_code |= ERR_ALERT | ERR_FATAL;
3186 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003187 }
Willy Tarreau93893792009-07-23 13:19:11 +02003188 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003189 }
3190 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003191 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003192 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3193 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003194 err_code |= ERR_ALERT | ERR_FATAL;
3195 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003196 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003197 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003198 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003199
Willy Tarreaubaaee002006-06-26 02:48:02 +02003200 /* flush useless bits */
3201 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003202 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003203 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003204 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003205 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003206 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003207
William Lallemanddf1425a2015-04-28 20:17:49 +02003208 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3209 goto out;
3210
Willy Tarreau1c47f852006-07-09 08:22:27 +02003211 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003212 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3213 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003214 err_code |= ERR_ALERT | ERR_FATAL;
3215 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003216 }
3217
Willy Tarreaua534fea2008-08-03 12:19:50 +02003218 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003219 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003220 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003221 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003222 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3223
Willy Tarreau93893792009-07-23 13:19:11 +02003224 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003225 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003226 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003227 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3228 goto out;
3229
Willy Tarreaubaaee002006-06-26 02:48:02 +02003230 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3231 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3232 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3233 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003234 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003235 err_code |= ERR_ALERT | ERR_FATAL;
3236 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003237 }
3238 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003239 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003240 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003241
3242 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003243 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003244 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003245 err_code |= ERR_ALERT | ERR_FATAL;
3246 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003247 }
3248
William Lallemanddf1425a2015-04-28 20:17:49 +02003249 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3250 goto out;
3251
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003252 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003253 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3254 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003255 err_code |= ERR_ALERT | ERR_FATAL;
3256 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003257 }
3258
3259 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003260 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003261 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003262
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003263 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003264 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3265 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003266 err_code |= ERR_ALERT | ERR_FATAL;
3267 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003268 }
3269
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003270 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3271 if (node) {
3272 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003273 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3274 file, linenum, proxy_type_str(curproxy), curproxy->id,
3275 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003276 err_code |= ERR_ALERT | ERR_FATAL;
3277 goto out;
3278 }
3279 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003280 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003281 else if (!strcmp(args[0], "description")) {
3282 int i, len=0;
3283 char *d;
3284
Cyril Bonté99ed3272010-01-24 23:29:44 +01003285 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003286 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003287 file, linenum, args[0]);
3288 err_code |= ERR_ALERT | ERR_FATAL;
3289 goto out;
3290 }
3291
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003292 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003293 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3294 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003295 return -1;
3296 }
3297
Willy Tarreau348acfe2014-04-14 15:00:39 +02003298 for (i = 1; *args[i]; i++)
3299 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003300
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003301 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003302 curproxy->desc = d;
3303
Willy Tarreau348acfe2014-04-14 15:00:39 +02003304 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3305 for (i = 2; *args[i]; i++)
3306 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003307
3308 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003309 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003310 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3311 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003312 curproxy->state = PR_STSTOPPED;
3313 }
3314 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003315 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3316 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003317 curproxy->state = PR_STNEW;
3318 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003319 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3320 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003321 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003322
3323 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003324 if (strcmp(args[cur_arg], "all") == 0) {
3325 set = 0;
3326 break;
3327 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003328 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003329 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003330 err_code |= ERR_ALERT | ERR_FATAL;
3331 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003332 }
3333 cur_arg++;
3334 }
3335 curproxy->bind_proc = set;
3336 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003337 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003338 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003339 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003340 err_code |= ERR_ALERT | ERR_FATAL;
3341 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003342 }
3343
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003344 err = invalid_char(args[1]);
3345 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003346 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3347 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003348 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003349 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003350 }
3351
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003352 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003353 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3354 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003355 err_code |= ERR_ALERT | ERR_FATAL;
3356 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003357 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003358 }
3359 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3360
3361 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3362 err_code |= ERR_WARN;
3363
3364 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003365 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3366 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003367 err_code |= ERR_ALERT | ERR_FATAL;
3368 goto out;
3369 }
3370 free(curproxy->dyncookie_key);
3371 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003372 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003373 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3374 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003375
Willy Tarreau977b8e42006-12-29 14:19:17 +01003376 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003377 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003378
Willy Tarreaubaaee002006-06-26 02:48:02 +02003379 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003380 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3381 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003382 err_code |= ERR_ALERT | ERR_FATAL;
3383 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003384 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003385
Willy Tarreau67402132012-05-31 20:40:20 +02003386 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003387 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003388 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003389 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003390 curproxy->cookie_name = strdup(args[1]);
3391 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003392
Willy Tarreaubaaee002006-06-26 02:48:02 +02003393 cur_arg = 2;
3394 while (*(args[cur_arg])) {
3395 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003396 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003397 }
3398 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003399 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003400 }
3401 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003402 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003403 }
3404 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003405 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003406 }
3407 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003408 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003409 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003410 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003411 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003412 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003413 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003414 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003415 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003416 else if (!strcmp(args[cur_arg], "httponly")) {
3417 curproxy->ck_opts |= PR_CK_HTTPONLY;
3418 }
3419 else if (!strcmp(args[cur_arg], "secure")) {
3420 curproxy->ck_opts |= PR_CK_SECURE;
3421 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003422 else if (!strcmp(args[cur_arg], "domain")) {
3423 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003424 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3425 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003426 err_code |= ERR_ALERT | ERR_FATAL;
3427 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003428 }
3429
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003430 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003431 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003432 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3433 " dots nor does not start with a dot."
3434 " RFC forbids it, this configuration may not work properly.\n",
3435 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003436 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003437 }
3438
3439 err = invalid_domainchar(args[cur_arg + 1]);
3440 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003441 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3442 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003443 err_code |= ERR_ALERT | ERR_FATAL;
3444 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003445 }
3446
Willy Tarreau68a897b2009-12-03 23:28:34 +01003447 if (!curproxy->cookie_domain) {
3448 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3449 } else {
3450 /* one domain was already specified, add another one by
3451 * building the string which will be returned along with
3452 * the cookie.
3453 */
3454 char *new_ptr;
3455 int new_len = strlen(curproxy->cookie_domain) +
3456 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3457 new_ptr = malloc(new_len);
3458 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3459 free(curproxy->cookie_domain);
3460 curproxy->cookie_domain = new_ptr;
3461 }
Willy Tarreau31936852010-10-06 16:59:56 +02003462 cur_arg++;
3463 }
3464 else if (!strcmp(args[cur_arg], "maxidle")) {
3465 unsigned int maxidle;
3466 const char *res;
3467
3468 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003469 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3470 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003471 err_code |= ERR_ALERT | ERR_FATAL;
3472 goto out;
3473 }
3474
3475 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3476 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003477 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3478 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003479 err_code |= ERR_ALERT | ERR_FATAL;
3480 goto out;
3481 }
3482 curproxy->cookie_maxidle = maxidle;
3483 cur_arg++;
3484 }
3485 else if (!strcmp(args[cur_arg], "maxlife")) {
3486 unsigned int maxlife;
3487 const char *res;
3488
3489 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003490 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3491 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003492 err_code |= ERR_ALERT | ERR_FATAL;
3493 goto out;
3494 }
3495
3496 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3497 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003498 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3499 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003500 err_code |= ERR_ALERT | ERR_FATAL;
3501 goto out;
3502 }
3503 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003504 cur_arg++;
3505 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003506 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003507
3508 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3509 err_code |= ERR_WARN;
3510 curproxy->ck_opts |= PR_CK_DYNAMIC;
3511 }
3512
Willy Tarreaubaaee002006-06-26 02:48:02 +02003513 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003514 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3515 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003516 err_code |= ERR_ALERT | ERR_FATAL;
3517 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003518 }
3519 cur_arg++;
3520 }
Willy Tarreau67402132012-05-31 20:40:20 +02003521 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003522 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3523 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003524 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003525 }
3526
Willy Tarreau67402132012-05-31 20:40:20 +02003527 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003528 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3529 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003530 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003531 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003532
Willy Tarreau67402132012-05-31 20:40:20 +02003533 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003534 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3535 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003536 err_code |= ERR_ALERT | ERR_FATAL;
3537 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003538 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003539 else if (!strcmp(args[0], "email-alert")) {
3540 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003541 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3542 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003543 err_code |= ERR_ALERT | ERR_FATAL;
3544 goto out;
3545 }
3546
3547 if (!strcmp(args[1], "from")) {
3548 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003549 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3550 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003551 err_code |= ERR_ALERT | ERR_FATAL;
3552 goto out;
3553 }
3554 free(curproxy->email_alert.from);
3555 curproxy->email_alert.from = strdup(args[2]);
3556 }
3557 else if (!strcmp(args[1], "mailers")) {
3558 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003559 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3560 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003561 err_code |= ERR_ALERT | ERR_FATAL;
3562 goto out;
3563 }
3564 free(curproxy->email_alert.mailers.name);
3565 curproxy->email_alert.mailers.name = strdup(args[2]);
3566 }
3567 else if (!strcmp(args[1], "myhostname")) {
3568 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003569 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3570 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003571 err_code |= ERR_ALERT | ERR_FATAL;
3572 goto out;
3573 }
3574 free(curproxy->email_alert.myhostname);
3575 curproxy->email_alert.myhostname = strdup(args[2]);
3576 }
Simon Horman64e34162015-02-06 11:11:57 +09003577 else if (!strcmp(args[1], "level")) {
3578 curproxy->email_alert.level = get_log_level(args[2]);
3579 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003580 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3581 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003582 err_code |= ERR_ALERT | ERR_FATAL;
3583 goto out;
3584 }
3585 }
Simon Horman9dc49962015-01-30 11:22:59 +09003586 else if (!strcmp(args[1], "to")) {
3587 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003588 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3589 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003590 err_code |= ERR_ALERT | ERR_FATAL;
3591 goto out;
3592 }
3593 free(curproxy->email_alert.to);
3594 curproxy->email_alert.to = strdup(args[2]);
3595 }
3596 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003597 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3598 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003599 err_code |= ERR_ALERT | ERR_FATAL;
3600 goto out;
3601 }
Simon Horman64e34162015-02-06 11:11:57 +09003602 /* Indicate that the email_alert is at least partially configured */
3603 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003604 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003605 else if (!strcmp(args[0], "external-check")) {
3606 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003607 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3608 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003609 err_code |= ERR_ALERT | ERR_FATAL;
3610 goto out;
3611 }
3612
3613 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003614 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003615 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003616 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003617 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3618 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003619 err_code |= ERR_ALERT | ERR_FATAL;
3620 goto out;
3621 }
3622 free(curproxy->check_command);
3623 curproxy->check_command = strdup(args[2]);
3624 }
3625 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003626 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003627 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003628 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003629 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3630 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003631 err_code |= ERR_ALERT | ERR_FATAL;
3632 goto out;
3633 }
3634 free(curproxy->check_path);
3635 curproxy->check_path = strdup(args[2]);
3636 }
3637 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003638 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3639 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003640 err_code |= ERR_ALERT | ERR_FATAL;
3641 goto out;
3642 }
3643 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003644 else if (!strcmp(args[0], "persist")) { /* persist */
3645 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003646 ha_alert("parsing [%s:%d] : missing persist method.\n",
3647 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003648 err_code |= ERR_ALERT | ERR_FATAL;
3649 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003650 }
3651
3652 if (!strncmp(args[1], "rdp-cookie", 10)) {
3653 curproxy->options2 |= PR_O2_RDPC_PRST;
3654
Emeric Brunb982a3d2010-01-04 15:45:53 +01003655 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003656 const char *beg, *end;
3657
3658 beg = args[1] + 11;
3659 end = strchr(beg, ')');
3660
William Lallemanddf1425a2015-04-28 20:17:49 +02003661 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3662 goto out;
3663
Emeric Brun647caf12009-06-30 17:57:00 +02003664 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003665 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3666 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003667 err_code |= ERR_ALERT | ERR_FATAL;
3668 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003669 }
3670
3671 free(curproxy->rdp_cookie_name);
3672 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3673 curproxy->rdp_cookie_len = end-beg;
3674 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003675 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003676 free(curproxy->rdp_cookie_name);
3677 curproxy->rdp_cookie_name = strdup("msts");
3678 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3679 }
3680 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003681 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3682 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003683 err_code |= ERR_ALERT | ERR_FATAL;
3684 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003685 }
3686 }
3687 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003688 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3689 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003690 err_code |= ERR_ALERT | ERR_FATAL;
3691 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003692 }
3693 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003694 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003695 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 +02003696 err_code |= ERR_ALERT | ERR_FATAL;
3697 goto out;
3698 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003699 else if (!strcmp(args[0], "load-server-state-from-file")) {
3700 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3701 err_code |= ERR_WARN;
3702 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3703 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3704 }
3705 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3706 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3707 }
3708 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3709 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3710 }
3711 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003712 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3713 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003714 err_code |= ERR_ALERT | ERR_FATAL;
3715 goto out;
3716 }
3717 }
3718 else if (!strcmp(args[0], "server-state-file-name")) {
3719 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3720 err_code |= ERR_WARN;
3721 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003722 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3723 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003724 err_code |= ERR_ALERT | ERR_FATAL;
3725 goto out;
3726 }
3727 else if (!strcmp(args[1], "use-backend-name"))
3728 curproxy->server_state_file_name = strdup(curproxy->id);
3729 else
3730 curproxy->server_state_file_name = strdup(args[1]);
3731 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003732 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003733 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003734 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003735
Willy Tarreaubaaee002006-06-26 02:48:02 +02003736 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003737 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003738 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 +01003739 err_code |= ERR_ALERT | ERR_FATAL;
3740 goto out;
3741 }
3742
William Lallemand1a748ae2015-05-19 16:37:23 +02003743 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3744 goto out;
3745
Willy Tarreaubaaee002006-06-26 02:48:02 +02003746 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003747 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3748 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003749 err_code |= ERR_ALERT | ERR_FATAL;
3750 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003751 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003752 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003753 curproxy->capture_name = strdup(args[2]);
3754 curproxy->capture_namelen = strlen(curproxy->capture_name);
3755 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003756 curproxy->to_log |= LW_COOKIE;
3757 }
3758 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3759 struct cap_hdr *hdr;
3760
3761 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003762 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 +02003763 err_code |= ERR_ALERT | ERR_FATAL;
3764 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003765 }
3766
William Lallemand1a748ae2015-05-19 16:37:23 +02003767 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3768 goto out;
3769
Willy Tarreaubaaee002006-06-26 02:48:02 +02003770 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003771 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3772 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003773 err_code |= ERR_ALERT | ERR_FATAL;
3774 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003775 }
3776
Vincent Bernat02779b62016-04-03 13:48:43 +02003777 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003778 hdr->next = curproxy->req_cap;
3779 hdr->name = strdup(args[3]);
3780 hdr->namelen = strlen(args[3]);
3781 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003782 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003783 hdr->index = curproxy->nb_req_cap++;
3784 curproxy->req_cap = hdr;
3785 curproxy->to_log |= LW_REQHDR;
3786 }
3787 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3788 struct cap_hdr *hdr;
3789
3790 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003791 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 +02003792 err_code |= ERR_ALERT | ERR_FATAL;
3793 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003794 }
3795
William Lallemand1a748ae2015-05-19 16:37:23 +02003796 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3797 goto out;
3798
Willy Tarreaubaaee002006-06-26 02:48:02 +02003799 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003800 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3801 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003802 err_code |= ERR_ALERT | ERR_FATAL;
3803 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003804 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003805 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003806 hdr->next = curproxy->rsp_cap;
3807 hdr->name = strdup(args[3]);
3808 hdr->namelen = strlen(args[3]);
3809 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003810 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003811 hdr->index = curproxy->nb_rsp_cap++;
3812 curproxy->rsp_cap = hdr;
3813 curproxy->to_log |= LW_RSPHDR;
3814 }
3815 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003816 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3817 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003818 err_code |= ERR_ALERT | ERR_FATAL;
3819 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003820 }
3821 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003822 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003823 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003824 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003825
William Lallemanddf1425a2015-04-28 20:17:49 +02003826 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3827 goto out;
3828
Willy Tarreaubaaee002006-06-26 02:48:02 +02003829 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003830 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3831 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003832 err_code |= ERR_ALERT | ERR_FATAL;
3833 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003834 }
3835 curproxy->conn_retries = atol(args[1]);
3836 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003837 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003838 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003839
3840 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003841 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003842 err_code |= ERR_ALERT | ERR_FATAL;
3843 goto out;
3844 }
3845
Willy Tarreau20b0de52012-12-24 15:45:22 +01003846 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003847 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003848 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3849 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3850 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3851 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003852 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3853 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003854 err_code |= ERR_WARN;
3855 }
3856
Willy Tarreauff011f22011-01-06 17:51:27 +01003857 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003858
Willy Tarreauff011f22011-01-06 17:51:27 +01003859 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003860 err_code |= ERR_ALERT | ERR_ABORT;
3861 goto out;
3862 }
3863
Willy Tarreau5002f572014-04-23 01:32:02 +02003864 err_code |= warnif_misplaced_http_req(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);
3868
Willy Tarreauff011f22011-01-06 17:51:27 +01003869 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003870 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003871 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003872 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003873
3874 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003875 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003876 err_code |= ERR_ALERT | ERR_FATAL;
3877 goto out;
3878 }
3879
3880 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003881 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003882 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3883 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003884 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3885 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003886 err_code |= ERR_WARN;
3887 }
3888
3889 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3890
3891 if (!rule) {
3892 err_code |= ERR_ALERT | ERR_ABORT;
3893 goto out;
3894 }
3895
3896 err_code |= warnif_cond_conflicts(rule->cond,
3897 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3898 file, linenum);
3899
3900 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3901 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003902 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3903 /* set the header name and length into the proxy structure */
3904 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3905 err_code |= ERR_WARN;
3906
3907 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003908 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3909 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003910 err_code |= ERR_ALERT | ERR_FATAL;
3911 goto out;
3912 }
3913
3914 /* set the desired header name */
3915 free(curproxy->server_id_hdr_name);
3916 curproxy->server_id_hdr_name = strdup(args[1]);
3917 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3918 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003919 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003920 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003921
Willy Tarreaub099aca2008-10-12 17:26:37 +02003922 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003923 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003924 err_code |= ERR_ALERT | ERR_FATAL;
3925 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003926 }
3927
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003928 /* emulate "block" using "http-request block". Since these rules are supposed to
3929 * be processed before all http-request rules, we put them into their own list
3930 * and will insert them at the end.
3931 */
3932 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3933 if (!rule) {
3934 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003935 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003936 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003937 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3938 err_code |= warnif_cond_conflicts(rule->cond,
3939 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3940 file, linenum);
3941 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003942
3943 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003944 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 +02003945
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003946 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003947 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003948 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003949
Cyril Bonté99ed3272010-01-24 23:29:44 +01003950 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003951 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003952 err_code |= ERR_ALERT | ERR_FATAL;
3953 goto out;
3954 }
3955
Willy Tarreaube4653b2015-05-28 15:26:58 +02003956 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003957 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3958 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003959 err_code |= ERR_ALERT | ERR_FATAL;
3960 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003961 }
3962
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003963 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003964 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003965 err_code |= warnif_cond_conflicts(rule->cond,
3966 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3967 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003968 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003969 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003970 struct switching_rule *rule;
3971
Willy Tarreaub099aca2008-10-12 17:26:37 +02003972 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003973 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003974 err_code |= ERR_ALERT | ERR_FATAL;
3975 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003976 }
3977
Willy Tarreau55ea7572007-06-17 19:56:27 +02003978 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003979 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003980
3981 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003982 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003983 err_code |= ERR_ALERT | ERR_FATAL;
3984 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003985 }
3986
Willy Tarreauf51658d2014-04-23 01:21:56 +02003987 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003988 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003989 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3990 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02003991 err_code |= ERR_ALERT | ERR_FATAL;
3992 goto out;
3993 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003994
Willy Tarreauf51658d2014-04-23 01:21:56 +02003995 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02003996 }
Willy Tarreau4f862642017-02-28 09:34:39 +01003997 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003998 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
3999 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004000 err_code |= ERR_ALERT | ERR_FATAL;
4001 goto out;
4002 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004003
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004004 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004005 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004006 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004007 goto out;
4008 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004009 rule->cond = cond;
4010 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004011 rule->line = linenum;
4012 rule->file = strdup(file);
4013 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004014 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004015 goto out;
4016 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004017 LIST_INIT(&rule->list);
4018 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4019 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004020 else if (strcmp(args[0], "use-server") == 0) {
4021 struct server_rule *rule;
4022
4023 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004024 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004025 err_code |= ERR_ALERT | ERR_FATAL;
4026 goto out;
4027 }
4028
4029 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4030 err_code |= ERR_WARN;
4031
4032 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004033 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004034 err_code |= ERR_ALERT | ERR_FATAL;
4035 goto out;
4036 }
4037
4038 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004039 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4040 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004041 err_code |= ERR_ALERT | ERR_FATAL;
4042 goto out;
4043 }
4044
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004045 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004046 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4047 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004048 err_code |= ERR_ALERT | ERR_FATAL;
4049 goto out;
4050 }
4051
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004052 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004053
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004054 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004055 rule->cond = cond;
4056 rule->srv.name = strdup(args[1]);
4057 LIST_INIT(&rule->list);
4058 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4059 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4060 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004061 else if ((!strcmp(args[0], "force-persist")) ||
4062 (!strcmp(args[0], "ignore-persist"))) {
4063 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004064
4065 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004066 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004067 err_code |= ERR_ALERT | ERR_FATAL;
4068 goto out;
4069 }
4070
Cyril Bonté4288c5a2018-03-12 22:02:59 +01004071 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01004072 err_code |= ERR_WARN;
4073
Willy Tarreauef6494c2010-01-28 17:12:36 +01004074 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004075 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4076 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004077 err_code |= ERR_ALERT | ERR_FATAL;
4078 goto out;
4079 }
4080
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004081 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004082 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4083 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004084 err_code |= ERR_ALERT | ERR_FATAL;
4085 goto out;
4086 }
4087
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004088 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4089 * where force-persist is applied.
4090 */
4091 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004092
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004093 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004094 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004095 if (!strcmp(args[0], "force-persist")) {
4096 rule->type = PERSIST_TYPE_FORCE;
4097 } else {
4098 rule->type = PERSIST_TYPE_IGNORE;
4099 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004100 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004101 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004102 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004103 else if (!strcmp(args[0], "stick-table")) {
4104 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004105 struct proxy *other;
4106
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004107 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004108 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004109 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4110 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004111 err_code |= ERR_ALERT | ERR_FATAL;
4112 goto out;
4113 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004114
Emeric Brun32da3c42010-09-23 18:39:19 +02004115 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004116 curproxy->table.type = (unsigned int)-1;
4117 while (*args[myidx]) {
4118 const char *err;
4119
4120 if (strcmp(args[myidx], "size") == 0) {
4121 myidx++;
4122 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004123 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4124 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004125 err_code |= ERR_ALERT | ERR_FATAL;
4126 goto out;
4127 }
4128 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004129 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4130 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004131 err_code |= ERR_ALERT | ERR_FATAL;
4132 goto out;
4133 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004134 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004135 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004136 else if (strcmp(args[myidx], "peers") == 0) {
4137 myidx++;
Godbach50523162013-12-11 19:48:57 +08004138 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004139 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4140 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004141 err_code |= ERR_ALERT | ERR_FATAL;
4142 goto out;
Godbach50523162013-12-11 19:48:57 +08004143 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004144 curproxy->table.peers.name = strdup(args[myidx++]);
4145 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004146 else if (strcmp(args[myidx], "expire") == 0) {
4147 myidx++;
4148 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004149 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4150 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004151 err_code |= ERR_ALERT | ERR_FATAL;
4152 goto out;
4153 }
4154 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4155 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004156 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4157 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004158 err_code |= ERR_ALERT | ERR_FATAL;
4159 goto out;
4160 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004161 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004162 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4163 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004164 err_code |= ERR_ALERT | ERR_FATAL;
4165 goto out;
4166 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004167 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004168 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004169 }
4170 else if (strcmp(args[myidx], "nopurge") == 0) {
4171 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004172 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004173 }
4174 else if (strcmp(args[myidx], "type") == 0) {
4175 myidx++;
4176 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004177 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4178 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004179 err_code |= ERR_ALERT | ERR_FATAL;
4180 goto out;
4181 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004182 /* myidx already points to next arg */
4183 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004184 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004185 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004186 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004187
4188 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004189 nw = args[myidx];
4190 while (*nw) {
4191 /* the "store" keyword supports a comma-separated list */
4192 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004193 sa = NULL; /* store arg */
4194 while (*nw && *nw != ',') {
4195 if (*nw == '(') {
4196 *nw = 0;
4197 sa = ++nw;
4198 while (*nw != ')') {
4199 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004200 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4201 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004202 err_code |= ERR_ALERT | ERR_FATAL;
4203 goto out;
4204 }
4205 nw++;
4206 }
4207 *nw = '\0';
4208 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004209 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004210 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004211 if (*nw)
4212 *nw++ = '\0';
4213 type = stktable_get_data_type(cw);
4214 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004215 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4216 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004217 err_code |= ERR_ALERT | ERR_FATAL;
4218 goto out;
4219 }
Willy Tarreauac782882010-06-20 10:41:54 +02004220
4221 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4222 switch (err) {
4223 case PE_NONE: break;
4224 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004225 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4226 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004227 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004228 break;
4229
4230 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004231 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4232 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004233 err_code |= ERR_ALERT | ERR_FATAL;
4234 goto out;
4235
4236 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004237 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4238 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004239 err_code |= ERR_ALERT | ERR_FATAL;
4240 goto out;
4241
4242 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004243 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4244 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004245 err_code |= ERR_ALERT | ERR_FATAL;
4246 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004247 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004248 }
4249 myidx++;
4250 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004251 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004252 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4253 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004254 err_code |= ERR_ALERT | ERR_FATAL;
4255 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004256 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004257 }
4258
4259 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004260 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4261 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004262 err_code |= ERR_ALERT | ERR_FATAL;
4263 goto out;
4264 }
4265
4266 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004267 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4268 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004269 err_code |= ERR_ALERT | ERR_FATAL;
4270 goto out;
4271 }
4272 }
4273 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004274 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004275 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004276 int myidx = 0;
4277 const char *name = NULL;
4278 int flags;
4279
4280 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004281 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004282 err_code |= ERR_ALERT | ERR_FATAL;
4283 goto out;
4284 }
4285
4286 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4287 err_code |= ERR_WARN;
4288 goto out;
4289 }
4290
4291 myidx++;
4292 if ((strcmp(args[myidx], "store") == 0) ||
4293 (strcmp(args[myidx], "store-request") == 0)) {
4294 myidx++;
4295 flags = STK_IS_STORE;
4296 }
4297 else if (strcmp(args[myidx], "store-response") == 0) {
4298 myidx++;
4299 flags = STK_IS_STORE | STK_ON_RSP;
4300 }
4301 else if (strcmp(args[myidx], "match") == 0) {
4302 myidx++;
4303 flags = STK_IS_MATCH;
4304 }
4305 else if (strcmp(args[myidx], "on") == 0) {
4306 myidx++;
4307 flags = STK_IS_MATCH | STK_IS_STORE;
4308 }
4309 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004310 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004311 err_code |= ERR_ALERT | ERR_FATAL;
4312 goto out;
4313 }
4314
4315 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004316 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004317 err_code |= ERR_ALERT | ERR_FATAL;
4318 goto out;
4319 }
4320
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004321 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004322 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004323 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004324 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004325 err_code |= ERR_ALERT | ERR_FATAL;
4326 goto out;
4327 }
4328
4329 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004330 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004331 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4332 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004333 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004334 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004335 goto out;
4336 }
4337 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004338 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004339 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4340 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004341 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004342 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004343 goto out;
4344 }
4345 }
4346
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004347 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004348 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004349
Emeric Brunb982a3d2010-01-04 15:45:53 +01004350 if (strcmp(args[myidx], "table") == 0) {
4351 myidx++;
4352 name = args[myidx++];
4353 }
4354
Willy Tarreauef6494c2010-01-28 17:12:36 +01004355 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004356 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004357 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4358 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004359 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004360 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004361 goto out;
4362 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004363 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004364 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004365 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4366 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004367 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004368 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004369 goto out;
4370 }
Emeric Brun97679e72010-09-23 17:56:44 +02004371 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004372 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004373 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004374 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004375
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004376 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004377 rule->cond = cond;
4378 rule->expr = expr;
4379 rule->flags = flags;
4380 rule->table.name = name ? strdup(name) : NULL;
4381 LIST_INIT(&rule->list);
4382 if (flags & STK_ON_RSP)
4383 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4384 else
4385 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4386 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004387 else if (!strcmp(args[0], "stats")) {
4388 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4389 curproxy->uri_auth = NULL; /* we must detach from the default config */
4390
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004391 if (!*args[1]) {
4392 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004393 } else if (!strcmp(args[1], "admin")) {
4394 struct stats_admin_rule *rule;
4395
4396 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004397 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 +02004398 err_code |= ERR_ALERT | ERR_FATAL;
4399 goto out;
4400 }
4401
4402 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004403 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004404 err_code |= ERR_ALERT | ERR_ABORT;
4405 goto out;
4406 }
4407
4408 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004409 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4410 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004411 err_code |= ERR_ALERT | ERR_FATAL;
4412 goto out;
4413 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004414 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004415 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4416 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004417 err_code |= ERR_ALERT | ERR_FATAL;
4418 goto out;
4419 }
4420
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004421 err_code |= warnif_cond_conflicts(cond,
4422 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4423 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004424
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004425 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004426 rule->cond = cond;
4427 LIST_INIT(&rule->list);
4428 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004429 } else if (!strcmp(args[1], "uri")) {
4430 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004431 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004432 err_code |= ERR_ALERT | ERR_FATAL;
4433 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004434 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004435 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004436 err_code |= ERR_ALERT | ERR_ABORT;
4437 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004438 }
4439 } else if (!strcmp(args[1], "realm")) {
4440 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004441 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004442 err_code |= ERR_ALERT | ERR_FATAL;
4443 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004444 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004445 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004446 err_code |= ERR_ALERT | ERR_ABORT;
4447 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004448 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004449 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004450 unsigned interval;
4451
4452 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4453 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004454 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4455 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004456 err_code |= ERR_ALERT | ERR_FATAL;
4457 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004458 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004459 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004460 err_code |= ERR_ALERT | ERR_ABORT;
4461 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004462 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004463 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004464 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004465
4466 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004467 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004468 err_code |= ERR_ALERT | ERR_FATAL;
4469 goto out;
4470 }
4471
4472 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004473 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004474 err_code |= ERR_ALERT | ERR_ABORT;
4475 goto out;
4476 }
4477
Willy Tarreauff011f22011-01-06 17:51:27 +01004478 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004479 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004480 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4481 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004482 err_code |= ERR_WARN;
4483 }
4484
Willy Tarreauff011f22011-01-06 17:51:27 +01004485 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004486
Willy Tarreauff011f22011-01-06 17:51:27 +01004487 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004488 err_code |= ERR_ALERT | ERR_ABORT;
4489 goto out;
4490 }
4491
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004492 err_code |= warnif_cond_conflicts(rule->cond,
4493 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4494 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004495 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004496
Willy Tarreaubaaee002006-06-26 02:48:02 +02004497 } else if (!strcmp(args[1], "auth")) {
4498 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004499 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004500 err_code |= ERR_ALERT | ERR_FATAL;
4501 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004502 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004503 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004504 err_code |= ERR_ALERT | ERR_ABORT;
4505 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004506 }
4507 } else if (!strcmp(args[1], "scope")) {
4508 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004509 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004510 err_code |= ERR_ALERT | ERR_FATAL;
4511 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004512 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004513 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004514 err_code |= ERR_ALERT | ERR_ABORT;
4515 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004516 }
4517 } else if (!strcmp(args[1], "enable")) {
4518 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004519 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004520 err_code |= ERR_ALERT | ERR_ABORT;
4521 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004522 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004523 } else if (!strcmp(args[1], "hide-version")) {
4524 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004525 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004526 err_code |= ERR_ALERT | ERR_ABORT;
4527 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004528 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004529 } else if (!strcmp(args[1], "show-legends")) {
4530 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004531 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004532 err_code |= ERR_ALERT | ERR_ABORT;
4533 goto out;
4534 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004535 } else if (!strcmp(args[1], "show-node")) {
4536
4537 if (*args[2]) {
4538 int i;
4539 char c;
4540
4541 for (i=0; args[2][i]; i++) {
4542 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004543 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4544 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004545 break;
4546 }
4547
4548 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004549 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4550 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4551 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004552 err_code |= ERR_ALERT | ERR_FATAL;
4553 goto out;
4554 }
4555 }
4556
4557 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004558 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004559 err_code |= ERR_ALERT | ERR_ABORT;
4560 goto out;
4561 }
4562 } else if (!strcmp(args[1], "show-desc")) {
4563 char *desc = NULL;
4564
4565 if (*args[2]) {
4566 int i, len=0;
4567 char *d;
4568
Willy Tarreau348acfe2014-04-14 15:00:39 +02004569 for (i = 2; *args[i]; i++)
4570 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004571
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004572 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004573
Willy Tarreau348acfe2014-04-14 15:00:39 +02004574 d += snprintf(d, desc + len - d, "%s", args[2]);
4575 for (i = 3; *args[i]; i++)
4576 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004577 }
4578
4579 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004580 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4581 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004582 else {
4583 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4584 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004585 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004586 err_code |= ERR_ALERT | ERR_ABORT;
4587 goto out;
4588 }
4589 free(desc);
4590 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004591 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004592stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004593 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4594 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004595 err_code |= ERR_ALERT | ERR_FATAL;
4596 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004597 }
4598 }
4599 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004600 int optnum;
4601
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004602 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004603 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4604 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004605 err_code |= ERR_ALERT | ERR_FATAL;
4606 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004607 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004608
4609 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4610 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004611 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004612 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4613 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004614 err_code |= ERR_ALERT | ERR_FATAL;
4615 goto out;
4616 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004617 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4618 goto out;
4619
Willy Tarreau93893792009-07-23 13:19:11 +02004620 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4621 err_code |= ERR_WARN;
4622 goto out;
4623 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004624
Willy Tarreau3842f002009-06-14 11:39:52 +02004625 curproxy->no_options &= ~cfg_opts[optnum].val;
4626 curproxy->options &= ~cfg_opts[optnum].val;
4627
4628 switch (kwm) {
4629 case KWM_STD:
4630 curproxy->options |= cfg_opts[optnum].val;
4631 break;
4632 case KWM_NO:
4633 curproxy->no_options |= cfg_opts[optnum].val;
4634 break;
4635 case KWM_DEF: /* already cleared */
4636 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004637 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004638
Willy Tarreau93893792009-07-23 13:19:11 +02004639 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004640 }
4641 }
4642
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004643 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4644 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004645 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004646 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4647 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004648 err_code |= ERR_ALERT | ERR_FATAL;
4649 goto out;
4650 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004651 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4652 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004653 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4654 err_code |= ERR_WARN;
4655 goto out;
4656 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004657
Willy Tarreau3842f002009-06-14 11:39:52 +02004658 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4659 curproxy->options2 &= ~cfg_opts2[optnum].val;
4660
4661 switch (kwm) {
4662 case KWM_STD:
4663 curproxy->options2 |= cfg_opts2[optnum].val;
4664 break;
4665 case KWM_NO:
4666 curproxy->no_options2 |= cfg_opts2[optnum].val;
4667 break;
4668 case KWM_DEF: /* already cleared */
4669 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004670 }
Willy Tarreau93893792009-07-23 13:19:11 +02004671 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004672 }
4673 }
4674
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004675 /* HTTP options override each other. They can be cancelled using
4676 * "no option xxx" which only switches to default mode if the mode
4677 * was this one (useful for cancelling options set in defaults
4678 * sections).
4679 */
4680 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004681 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4682 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004683 if (kwm == KWM_STD) {
4684 curproxy->options &= ~PR_O_HTTP_MODE;
4685 curproxy->options |= PR_O_HTTP_PCL;
4686 goto out;
4687 }
4688 else if (kwm == KWM_NO) {
4689 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4690 curproxy->options &= ~PR_O_HTTP_MODE;
4691 goto out;
4692 }
4693 }
4694 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004695 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4696 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004697 if (kwm == KWM_STD) {
4698 curproxy->options &= ~PR_O_HTTP_MODE;
4699 curproxy->options |= PR_O_HTTP_FCL;
4700 goto out;
4701 }
4702 else if (kwm == KWM_NO) {
4703 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4704 curproxy->options &= ~PR_O_HTTP_MODE;
4705 goto out;
4706 }
4707 }
4708 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004709 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4710 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004711 if (kwm == KWM_STD) {
4712 curproxy->options &= ~PR_O_HTTP_MODE;
4713 curproxy->options |= PR_O_HTTP_SCL;
4714 goto out;
4715 }
4716 else if (kwm == KWM_NO) {
4717 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4718 curproxy->options &= ~PR_O_HTTP_MODE;
4719 goto out;
4720 }
4721 }
4722 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004723 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4724 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004725 if (kwm == KWM_STD) {
4726 curproxy->options &= ~PR_O_HTTP_MODE;
4727 curproxy->options |= PR_O_HTTP_KAL;
4728 goto out;
4729 }
4730 else if (kwm == KWM_NO) {
4731 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4732 curproxy->options &= ~PR_O_HTTP_MODE;
4733 goto out;
4734 }
4735 }
4736 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004737 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4738 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004739 if (kwm == KWM_STD) {
4740 curproxy->options &= ~PR_O_HTTP_MODE;
4741 curproxy->options |= PR_O_HTTP_TUN;
4742 goto out;
4743 }
4744 else if (kwm == KWM_NO) {
4745 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4746 curproxy->options &= ~PR_O_HTTP_MODE;
4747 goto out;
4748 }
4749 }
4750
Joseph Lynch726ab712015-05-11 23:25:34 -07004751 /* Redispatch can take an integer argument that control when the
4752 * resispatch occurs. All values are relative to the retries option.
4753 * This can be cancelled using "no option xxx".
4754 */
4755 if (strcmp(args[1], "redispatch") == 0) {
4756 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4757 err_code |= ERR_WARN;
4758 goto out;
4759 }
4760
4761 curproxy->no_options &= ~PR_O_REDISP;
4762 curproxy->options &= ~PR_O_REDISP;
4763
4764 switch (kwm) {
4765 case KWM_STD:
4766 curproxy->options |= PR_O_REDISP;
4767 curproxy->redispatch_after = -1;
4768 if(*args[2]) {
4769 curproxy->redispatch_after = atol(args[2]);
4770 }
4771 break;
4772 case KWM_NO:
4773 curproxy->no_options |= PR_O_REDISP;
4774 curproxy->redispatch_after = 0;
4775 break;
4776 case KWM_DEF: /* already cleared */
4777 break;
4778 }
4779 goto out;
4780 }
4781
Willy Tarreau3842f002009-06-14 11:39:52 +02004782 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004783 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4784 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004785 err_code |= ERR_ALERT | ERR_FATAL;
4786 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004787 }
4788
Emeric Brun3a058f32009-06-30 18:26:00 +02004789 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004790 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004791 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004792 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004793 if (*(args[2]) != '\0') {
4794 if (!strcmp(args[2], "clf")) {
4795 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004796 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004797 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004798 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004799 err_code |= ERR_ALERT | ERR_FATAL;
4800 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004801 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004802 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4803 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004804 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004805 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4806 char *oldlogformat = "log-format";
4807 char *clflogformat = "";
4808
4809 if (curproxy->conf.logformat_string == default_http_log_format)
4810 oldlogformat = "option httplog";
4811 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4812 oldlogformat = "option tcplog";
4813 else if (curproxy->conf.logformat_string == clf_http_log_format)
4814 oldlogformat = "option httplog clf";
4815 if (logformat == clf_http_log_format)
4816 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004817 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4818 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004819 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004820 if (curproxy->conf.logformat_string != default_http_log_format &&
4821 curproxy->conf.logformat_string != default_tcp_log_format &&
4822 curproxy->conf.logformat_string != clf_http_log_format)
4823 free(curproxy->conf.logformat_string);
4824 curproxy->conf.logformat_string = logformat;
4825
4826 free(curproxy->conf.lfs_file);
4827 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4828 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004829
4830 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4831 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4832 file, linenum, curproxy->id);
4833 err_code |= ERR_WARN;
4834 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004835 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004836 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004837 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4838 char *oldlogformat = "log-format";
4839
4840 if (curproxy->conf.logformat_string == default_http_log_format)
4841 oldlogformat = "option httplog";
4842 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4843 oldlogformat = "option tcplog";
4844 else if (curproxy->conf.logformat_string == clf_http_log_format)
4845 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004846 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4847 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004848 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004849 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004850 if (curproxy->conf.logformat_string != default_http_log_format &&
4851 curproxy->conf.logformat_string != default_tcp_log_format &&
4852 curproxy->conf.logformat_string != clf_http_log_format)
4853 free(curproxy->conf.logformat_string);
4854 curproxy->conf.logformat_string = default_tcp_log_format;
4855
4856 free(curproxy->conf.lfs_file);
4857 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4858 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004859
4860 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4861 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004862
4863 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4864 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4865 file, linenum, curproxy->id);
4866 err_code |= ERR_WARN;
4867 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004868 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004869 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004870 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004871 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004872 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004873
William Lallemanddf1425a2015-04-28 20:17:49 +02004874 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4875 goto out;
4876
Willy Tarreau13943ab2006-12-31 00:24:10 +01004877 if (curproxy->cap & PR_CAP_FE)
4878 curproxy->options |= PR_O_TCP_CLI_KA;
4879 if (curproxy->cap & PR_CAP_BE)
4880 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004881 }
4882 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004883 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004884 err_code |= ERR_WARN;
4885
Willy Tarreaubaaee002006-06-26 02:48:02 +02004886 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004887 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004888 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004889 curproxy->options2 &= ~PR_O2_CHK_ANY;
4890 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004891 if (!*args[2]) { /* no argument */
4892 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4893 curproxy->check_len = strlen(DEF_CHECK_REQ);
4894 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004895 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004896 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004897 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004898 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004899 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004900 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004901 if (*args[4])
4902 reqlen += strlen(args[4]);
4903 else
4904 reqlen += strlen("HTTP/1.0");
4905
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004906 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004907 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004908 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004909 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004910 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4911 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004912 }
4913 else if (!strcmp(args[1], "ssl-hello-chk")) {
4914 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004915 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004916 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004917
Willy Tarreaua534fea2008-08-03 12:19:50 +02004918 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004919 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004920 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004921 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004922
4923 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4924 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004925 }
Willy Tarreau23677902007-05-08 23:50:35 +02004926 else if (!strcmp(args[1], "smtpchk")) {
4927 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004928 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004929 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004930 curproxy->options2 &= ~PR_O2_CHK_ANY;
4931 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004932
4933 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4934 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4935 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4936 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4937 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4938 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004939 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004940 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4941 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4942 } else {
4943 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4944 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4945 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4946 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4947 }
4948 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004949 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4950 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004951 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004952 else if (!strcmp(args[1], "pgsql-check")) {
4953 /* use PostgreSQL request to check servers' health */
4954 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4955 err_code |= ERR_WARN;
4956
4957 free(curproxy->check_req);
4958 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004959 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004960 curproxy->options2 |= PR_O2_PGSQL_CHK;
4961
4962 if (*(args[2])) {
4963 int cur_arg = 2;
4964
4965 while (*(args[cur_arg])) {
4966 if (strcmp(args[cur_arg], "user") == 0) {
4967 char * packet;
4968 uint32_t packet_len;
4969 uint32_t pv;
4970
4971 /* suboption header - needs additional argument for it */
4972 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004973 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4974 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004975 err_code |= ERR_ALERT | ERR_FATAL;
4976 goto out;
4977 }
4978
4979 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4980 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4981 pv = htonl(0x30000); /* protocol version 3.0 */
4982
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004983 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004984
4985 memcpy(packet + 4, &pv, 4);
4986
4987 /* copy "user" */
4988 memcpy(packet + 8, "user", 4);
4989
4990 /* copy username */
4991 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
4992
4993 free(curproxy->check_req);
4994 curproxy->check_req = packet;
4995 curproxy->check_len = packet_len;
4996
4997 packet_len = htonl(packet_len);
4998 memcpy(packet, &packet_len, 4);
4999 cur_arg += 2;
5000 } else {
5001 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005002 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5003 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005004 err_code |= ERR_ALERT | ERR_FATAL;
5005 goto out;
5006 }
5007 } /* end while loop */
5008 }
William Lallemanddf1425a2015-04-28 20:17:49 +02005009 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
5010 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005011 }
5012
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005013 else if (!strcmp(args[1], "redis-check")) {
5014 /* use REDIS PING request to check servers' health */
5015 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5016 err_code |= ERR_WARN;
5017
5018 free(curproxy->check_req);
5019 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005020 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005021 curproxy->options2 |= PR_O2_REDIS_CHK;
5022
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005023 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005024 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5025 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005026
5027 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5028 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005029 }
5030
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005031 else if (!strcmp(args[1], "mysql-check")) {
5032 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005033 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5034 err_code |= ERR_WARN;
5035
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005036 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005037 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005038 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005039 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005040
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005041 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005042 * const char mysql40_client_auth_pkt[] = {
5043 * "\x0e\x00\x00" // packet length
5044 * "\x01" // packet number
5045 * "\x00\x00" // client capabilities
5046 * "\x00\x00\x01" // max packet
5047 * "haproxy\x00" // username (null terminated string)
5048 * "\x00" // filler (always 0x00)
5049 * "\x01\x00\x00" // packet length
5050 * "\x00" // packet number
5051 * "\x01" // COM_QUIT command
5052 * };
5053 */
5054
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005055 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5056 * const char mysql41_client_auth_pkt[] = {
5057 * "\x0e\x00\x00\" // packet length
5058 * "\x01" // packet number
5059 * "\x00\x00\x00\x00" // client capabilities
5060 * "\x00\x00\x00\x01" // max packet
5061 * "\x21" // character set (UTF-8)
5062 * char[23] // All zeroes
5063 * "haproxy\x00" // username (null terminated string)
5064 * "\x00" // filler (always 0x00)
5065 * "\x01\x00\x00" // packet length
5066 * "\x00" // packet number
5067 * "\x01" // COM_QUIT command
5068 * };
5069 */
5070
5071
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005072 if (*(args[2])) {
5073 int cur_arg = 2;
5074
5075 while (*(args[cur_arg])) {
5076 if (strcmp(args[cur_arg], "user") == 0) {
5077 char *mysqluser;
5078 int packetlen, reqlen, userlen;
5079
5080 /* suboption header - needs additional argument for it */
5081 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005082 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5083 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005084 err_code |= ERR_ALERT | ERR_FATAL;
5085 goto out;
5086 }
5087 mysqluser = args[cur_arg + 1];
5088 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005089
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005090 if (*(args[cur_arg+2])) {
5091 if (!strcmp(args[cur_arg+2], "post-41")) {
5092 packetlen = userlen + 7 + 27;
5093 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005094
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005095 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005096 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005097 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005098
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005099 snprintf(curproxy->check_req, 4, "%c%c%c",
5100 ((unsigned char) packetlen & 0xff),
5101 ((unsigned char) (packetlen >> 8) & 0xff),
5102 ((unsigned char) (packetlen >> 16) & 0xff));
5103
5104 curproxy->check_req[3] = 1;
5105 curproxy->check_req[5] = 130;
5106 curproxy->check_req[11] = 1;
5107 curproxy->check_req[12] = 33;
5108 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5109 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5110 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5111 cur_arg += 3;
5112 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005113 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 +02005114 err_code |= ERR_ALERT | ERR_FATAL;
5115 goto out;
5116 }
5117 } else {
5118 packetlen = userlen + 7;
5119 reqlen = packetlen + 9;
5120
5121 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005122 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005123 curproxy->check_len = reqlen;
5124
5125 snprintf(curproxy->check_req, 4, "%c%c%c",
5126 ((unsigned char) packetlen & 0xff),
5127 ((unsigned char) (packetlen >> 8) & 0xff),
5128 ((unsigned char) (packetlen >> 16) & 0xff));
5129
5130 curproxy->check_req[3] = 1;
5131 curproxy->check_req[5] = 128;
5132 curproxy->check_req[8] = 1;
5133 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5134 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5135 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5136 cur_arg += 2;
5137 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005138 } else {
5139 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005140 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5141 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005142 err_code |= ERR_ALERT | ERR_FATAL;
5143 goto out;
5144 }
5145 } /* end while loop */
5146 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005147 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005148 else if (!strcmp(args[1], "ldap-check")) {
5149 /* use LDAP request to check servers' health */
5150 free(curproxy->check_req);
5151 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005152 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005153 curproxy->options2 |= PR_O2_LDAP_CHK;
5154
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005155 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005156 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5157 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005158 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5159 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005160 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005161 else if (!strcmp(args[1], "spop-check")) {
5162 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005163 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5164 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005165 err_code |= ERR_ALERT | ERR_FATAL;
5166 goto out;
5167 }
5168 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005169 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5170 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005171 err_code |= ERR_ALERT | ERR_FATAL;
5172 goto out;
5173 }
5174
5175 /* use SPOE request to check servers' health */
5176 free(curproxy->check_req);
5177 curproxy->check_req = NULL;
5178 curproxy->options2 &= ~PR_O2_CHK_ANY;
5179 curproxy->options2 |= PR_O2_SPOP_CHK;
5180
Christopher Faulet8ef75252017-02-20 22:56:03 +01005181 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005182 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005183 err_code |= ERR_ALERT | ERR_FATAL;
5184 goto out;
5185 }
5186 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5187 goto out;
5188 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005189 else if (!strcmp(args[1], "tcp-check")) {
5190 /* use raw TCPCHK send/expect to check servers' health */
5191 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5192 err_code |= ERR_WARN;
5193
5194 free(curproxy->check_req);
5195 curproxy->check_req = NULL;
5196 curproxy->options2 &= ~PR_O2_CHK_ANY;
5197 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005198 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5199 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005200 }
Simon Horman98637e52014-06-20 12:30:16 +09005201 else if (!strcmp(args[1], "external-check")) {
5202 /* excute an external command to check servers' health */
5203 free(curproxy->check_req);
5204 curproxy->check_req = NULL;
5205 curproxy->options2 &= ~PR_O2_CHK_ANY;
5206 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005207 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5208 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005209 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005210 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005211 int cur_arg;
5212
5213 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5214 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005215 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005216
Willy Tarreau87cf5142011-08-19 22:57:24 +02005217 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005218
5219 free(curproxy->fwdfor_hdr_name);
5220 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5221 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5222
5223 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5224 cur_arg = 2;
5225 while (*(args[cur_arg])) {
5226 if (!strcmp(args[cur_arg], "except")) {
5227 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005228 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005229 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5230 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005231 err_code |= ERR_ALERT | ERR_FATAL;
5232 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005233 }
5234 /* flush useless bits */
5235 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005236 cur_arg += 2;
5237 } else if (!strcmp(args[cur_arg], "header")) {
5238 /* suboption header - needs additional argument for it */
5239 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005240 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5241 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005242 err_code |= ERR_ALERT | ERR_FATAL;
5243 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005244 }
5245 free(curproxy->fwdfor_hdr_name);
5246 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5247 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5248 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005249 } else if (!strcmp(args[cur_arg], "if-none")) {
5250 curproxy->options &= ~PR_O_FF_ALWAYS;
5251 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005252 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005253 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005254 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5255 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005256 err_code |= ERR_ALERT | ERR_FATAL;
5257 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005258 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005259 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005260 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005261 else if (!strcmp(args[1], "originalto")) {
5262 int cur_arg;
5263
5264 /* insert x-original-to field, but not for the IP address listed as an except.
5265 * set default options (ie: bitfield, header name, etc)
5266 */
5267
5268 curproxy->options |= PR_O_ORGTO;
5269
5270 free(curproxy->orgto_hdr_name);
5271 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5272 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5273
Willy Tarreau87cf5142011-08-19 22:57:24 +02005274 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005275 cur_arg = 2;
5276 while (*(args[cur_arg])) {
5277 if (!strcmp(args[cur_arg], "except")) {
5278 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005279 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 +01005280 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5281 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005282 err_code |= ERR_ALERT | ERR_FATAL;
5283 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005284 }
5285 /* flush useless bits */
5286 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5287 cur_arg += 2;
5288 } else if (!strcmp(args[cur_arg], "header")) {
5289 /* suboption header - needs additional argument for it */
5290 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005291 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5292 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005293 err_code |= ERR_ALERT | ERR_FATAL;
5294 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005295 }
5296 free(curproxy->orgto_hdr_name);
5297 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5298 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5299 cur_arg += 2;
5300 } else {
5301 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005302 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5303 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005304 err_code |= ERR_ALERT | ERR_FATAL;
5305 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005306 }
5307 } /* end while loop */
5308 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005309 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005310 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005311 err_code |= ERR_ALERT | ERR_FATAL;
5312 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005313 }
Willy Tarreau93893792009-07-23 13:19:11 +02005314 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005315 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005316 else if (!strcmp(args[0], "default_backend")) {
5317 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005318 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005319
5320 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005321 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005322 err_code |= ERR_ALERT | ERR_FATAL;
5323 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005324 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005325 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005326 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005327
5328 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5329 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005330 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005331 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005332 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005333 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005334
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005335 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005336 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5337 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005338 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005339 /* enable reconnections to dispatch */
5340 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005341
5342 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5343 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005344 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005345 else if (!strcmp(args[0], "http-reuse")) {
5346 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5347 err_code |= ERR_WARN;
5348
5349 if (strcmp(args[1], "never") == 0) {
5350 /* enable a graceful server shutdown on an HTTP 404 response */
5351 curproxy->options &= ~PR_O_REUSE_MASK;
5352 curproxy->options |= PR_O_REUSE_NEVR;
5353 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5354 goto out;
5355 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005356 else if (strcmp(args[1], "safe") == 0) {
5357 /* enable a graceful server shutdown on an HTTP 404 response */
5358 curproxy->options &= ~PR_O_REUSE_MASK;
5359 curproxy->options |= PR_O_REUSE_SAFE;
5360 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5361 goto out;
5362 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005363 else if (strcmp(args[1], "aggressive") == 0) {
5364 curproxy->options &= ~PR_O_REUSE_MASK;
5365 curproxy->options |= PR_O_REUSE_AGGR;
5366 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5367 goto out;
5368 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005369 else if (strcmp(args[1], "always") == 0) {
5370 /* enable a graceful server shutdown on an HTTP 404 response */
5371 curproxy->options &= ~PR_O_REUSE_MASK;
5372 curproxy->options |= PR_O_REUSE_ALWS;
5373 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5374 goto out;
5375 }
5376 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005377 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005378 err_code |= ERR_ALERT | ERR_FATAL;
5379 goto out;
5380 }
5381 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005382 else if (!strcmp(args[0], "http-check")) {
5383 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005384 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005385
5386 if (strcmp(args[1], "disable-on-404") == 0) {
5387 /* enable a graceful server shutdown on an HTTP 404 response */
5388 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005389 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5390 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005391 }
Willy Tarreauef781042010-01-27 11:53:01 +01005392 else if (strcmp(args[1], "send-state") == 0) {
5393 /* enable emission of the apparent state of a server in HTTP checks */
5394 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005395 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5396 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005397 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005398 else if (strcmp(args[1], "expect") == 0) {
5399 const char *ptr_arg;
5400 int cur_arg;
5401
5402 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005403 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005404 err_code |= ERR_ALERT | ERR_FATAL;
5405 goto out;
5406 }
5407
5408 cur_arg = 2;
5409 /* consider exclamation marks, sole or at the beginning of a word */
5410 while (*(ptr_arg = args[cur_arg])) {
5411 while (*ptr_arg == '!') {
5412 curproxy->options2 ^= PR_O2_EXP_INV;
5413 ptr_arg++;
5414 }
5415 if (*ptr_arg)
5416 break;
5417 cur_arg++;
5418 }
5419 /* now ptr_arg points to the beginning of a word past any possible
5420 * exclamation mark, and cur_arg is the argument which holds this word.
5421 */
5422 if (strcmp(ptr_arg, "status") == 0) {
5423 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005424 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5425 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005426 err_code |= ERR_ALERT | ERR_FATAL;
5427 goto out;
5428 }
5429 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005430 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005431 curproxy->expect_str = strdup(args[cur_arg + 1]);
5432 }
5433 else if (strcmp(ptr_arg, "string") == 0) {
5434 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005435 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5436 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005437 err_code |= ERR_ALERT | ERR_FATAL;
5438 goto out;
5439 }
5440 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005441 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005442 curproxy->expect_str = strdup(args[cur_arg + 1]);
5443 }
5444 else if (strcmp(ptr_arg, "rstatus") == 0) {
5445 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005446 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5447 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005448 err_code |= ERR_ALERT | ERR_FATAL;
5449 goto out;
5450 }
5451 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005452 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005453 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005454 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005455 free(curproxy->expect_regex);
5456 curproxy->expect_regex = NULL;
5457 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005458 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005459 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5460 error = NULL;
5461 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005462 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5463 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005464 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005465 err_code |= ERR_ALERT | ERR_FATAL;
5466 goto out;
5467 }
5468 }
5469 else if (strcmp(ptr_arg, "rstring") == 0) {
5470 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005471 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5472 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005473 err_code |= ERR_ALERT | ERR_FATAL;
5474 goto out;
5475 }
5476 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005477 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005478 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005479 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005480 free(curproxy->expect_regex);
5481 curproxy->expect_regex = NULL;
5482 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005483 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005484 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5485 error = NULL;
5486 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005487 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5488 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005489 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005490 err_code |= ERR_ALERT | ERR_FATAL;
5491 goto out;
5492 }
5493 }
5494 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005495 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5496 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005497 err_code |= ERR_ALERT | ERR_FATAL;
5498 goto out;
5499 }
5500 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005501 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005502 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 +02005503 err_code |= ERR_ALERT | ERR_FATAL;
5504 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005505 }
5506 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005507 else if (!strcmp(args[0], "tcp-check")) {
5508 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5509 err_code |= ERR_WARN;
5510
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005511 if (strcmp(args[1], "comment") == 0) {
5512 int cur_arg;
5513 struct tcpcheck_rule *tcpcheck;
5514
5515 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005516 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005517 tcpcheck->action = TCPCHK_ACT_COMMENT;
5518
5519 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005520 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5521 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005522 err_code |= ERR_ALERT | ERR_FATAL;
5523 goto out;
5524 }
5525
5526 tcpcheck->comment = strdup(args[cur_arg + 1]);
5527
5528 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005529 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5530 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005531 }
5532 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005533 const char *ptr_arg;
5534 int cur_arg;
5535 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005536
5537 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005538 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5539 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5540 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5541 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5542 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005543
Willy Tarreau5581c272015-05-13 12:24:53 +02005544 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5545 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005546 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5547 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005548 err_code |= ERR_ALERT | ERR_FATAL;
5549 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005550 }
5551
5552 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005553 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005554 tcpcheck->action = TCPCHK_ACT_CONNECT;
5555
5556 /* parsing each parameters to fill up the rule */
5557 while (*(ptr_arg = args[cur_arg])) {
5558 /* tcp port */
5559 if (strcmp(args[cur_arg], "port") == 0) {
5560 if ( (atol(args[cur_arg + 1]) > 65535) ||
5561 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005562 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5563 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005564 err_code |= ERR_ALERT | ERR_FATAL;
5565 goto out;
5566 }
5567 tcpcheck->port = atol(args[cur_arg + 1]);
5568 cur_arg += 2;
5569 }
5570 /* send proxy protocol */
5571 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5572 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5573 cur_arg++;
5574 }
5575#ifdef USE_OPENSSL
5576 else if (strcmp(args[cur_arg], "ssl") == 0) {
5577 curproxy->options |= PR_O_TCPCHK_SSL;
5578 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5579 cur_arg++;
5580 }
5581#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005582 /* comment for this tcpcheck line */
5583 else if (strcmp(args[cur_arg], "comment") == 0) {
5584 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005585 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5586 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005587 err_code |= ERR_ALERT | ERR_FATAL;
5588 goto out;
5589 }
5590 tcpcheck->comment = strdup(args[cur_arg + 1]);
5591 cur_arg += 2;
5592 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005593 else {
5594#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005595 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 +01005596#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005597 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 +01005598#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005599 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005600 err_code |= ERR_ALERT | ERR_FATAL;
5601 goto out;
5602 }
5603
5604 }
5605
5606 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5607 }
5608 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005609 if (! *(args[2]) ) {
5610 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005611 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5612 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005613 err_code |= ERR_ALERT | ERR_FATAL;
5614 goto out;
5615 } else {
5616 struct tcpcheck_rule *tcpcheck;
5617
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005618 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005619
5620 tcpcheck->action = TCPCHK_ACT_SEND;
5621 tcpcheck->string_len = strlen(args[2]);
5622 tcpcheck->string = strdup(args[2]);
5623 tcpcheck->expect_regex = NULL;
5624
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005625 /* comment for this tcpcheck line */
5626 if (strcmp(args[3], "comment") == 0) {
5627 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005628 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5629 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005630 err_code |= ERR_ALERT | ERR_FATAL;
5631 goto out;
5632 }
5633 tcpcheck->comment = strdup(args[4]);
5634 }
5635
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005636 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5637 }
5638 }
5639 else if (strcmp(args[1], "send-binary") == 0) {
5640 if (! *(args[2]) ) {
5641 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005642 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5643 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005644 err_code |= ERR_ALERT | ERR_FATAL;
5645 goto out;
5646 } else {
5647 struct tcpcheck_rule *tcpcheck;
5648 char *err = NULL;
5649
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005650 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005651
5652 tcpcheck->action = TCPCHK_ACT_SEND;
5653 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005654 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5655 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005656 err_code |= ERR_ALERT | ERR_FATAL;
5657 goto out;
5658 }
5659 tcpcheck->expect_regex = NULL;
5660
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005661 /* comment for this tcpcheck line */
5662 if (strcmp(args[3], "comment") == 0) {
5663 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005664 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5665 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005666 err_code |= ERR_ALERT | ERR_FATAL;
5667 goto out;
5668 }
5669 tcpcheck->comment = strdup(args[4]);
5670 }
5671
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005672 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5673 }
5674 }
5675 else if (strcmp(args[1], "expect") == 0) {
5676 const char *ptr_arg;
5677 int cur_arg;
5678 int inverse = 0;
5679
5680 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005681 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005682 err_code |= ERR_ALERT | ERR_FATAL;
5683 goto out;
5684 }
5685
5686 cur_arg = 2;
5687 /* consider exclamation marks, sole or at the beginning of a word */
5688 while (*(ptr_arg = args[cur_arg])) {
5689 while (*ptr_arg == '!') {
5690 inverse = !inverse;
5691 ptr_arg++;
5692 }
5693 if (*ptr_arg)
5694 break;
5695 cur_arg++;
5696 }
5697 /* now ptr_arg points to the beginning of a word past any possible
5698 * exclamation mark, and cur_arg is the argument which holds this word.
5699 */
5700 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005701 struct tcpcheck_rule *tcpcheck;
5702 char *err = NULL;
5703
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005704 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005705 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5706 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005707 err_code |= ERR_ALERT | ERR_FATAL;
5708 goto out;
5709 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005710
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005711 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005712
5713 tcpcheck->action = TCPCHK_ACT_EXPECT;
5714 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005715 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5716 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005717 err_code |= ERR_ALERT | ERR_FATAL;
5718 goto out;
5719 }
5720 tcpcheck->expect_regex = NULL;
5721 tcpcheck->inverse = inverse;
5722
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005723 /* tcpcheck comment */
5724 cur_arg += 2;
5725 if (strcmp(args[cur_arg], "comment") == 0) {
5726 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005727 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5728 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005729 err_code |= ERR_ALERT | ERR_FATAL;
5730 goto out;
5731 }
5732 tcpcheck->comment = strdup(args[cur_arg + 1]);
5733 }
5734
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005735 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5736 }
5737 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005738 struct tcpcheck_rule *tcpcheck;
5739
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005740 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005741 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5742 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005743 err_code |= ERR_ALERT | ERR_FATAL;
5744 goto out;
5745 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005746
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005747 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005748
5749 tcpcheck->action = TCPCHK_ACT_EXPECT;
5750 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5751 tcpcheck->string = strdup(args[cur_arg + 1]);
5752 tcpcheck->expect_regex = NULL;
5753 tcpcheck->inverse = inverse;
5754
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005755 /* tcpcheck comment */
5756 cur_arg += 2;
5757 if (strcmp(args[cur_arg], "comment") == 0) {
5758 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005759 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5760 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005761 err_code |= ERR_ALERT | ERR_FATAL;
5762 goto out;
5763 }
5764 tcpcheck->comment = strdup(args[cur_arg + 1]);
5765 }
5766
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005767 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5768 }
5769 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005770 struct tcpcheck_rule *tcpcheck;
5771
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005772 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005773 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5774 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005775 err_code |= ERR_ALERT | ERR_FATAL;
5776 goto out;
5777 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005778
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005779 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005780
5781 tcpcheck->action = TCPCHK_ACT_EXPECT;
5782 tcpcheck->string_len = 0;
5783 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005784 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5785 error = NULL;
5786 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005787 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5788 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005789 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005790 err_code |= ERR_ALERT | ERR_FATAL;
5791 goto out;
5792 }
5793 tcpcheck->inverse = inverse;
5794
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005795 /* tcpcheck comment */
5796 cur_arg += 2;
5797 if (strcmp(args[cur_arg], "comment") == 0) {
5798 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005799 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5800 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005801 err_code |= ERR_ALERT | ERR_FATAL;
5802 goto out;
5803 }
5804 tcpcheck->comment = strdup(args[cur_arg + 1]);
5805 }
5806
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005807 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5808 }
5809 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005810 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5811 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005812 err_code |= ERR_ALERT | ERR_FATAL;
5813 goto out;
5814 }
5815 }
5816 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005817 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 +02005818 err_code |= ERR_ALERT | ERR_FATAL;
5819 goto out;
5820 }
5821 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005822 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005823 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005824 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005825 err_code |= ERR_ALERT | ERR_FATAL;
5826 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005827 }
5828
Willy Tarreaub80c2302007-11-30 20:51:32 +01005829 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005830 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005831
5832 if (strcmp(args[1], "fail") == 0) {
5833 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005834 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005835 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5836 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005837 err_code |= ERR_ALERT | ERR_FATAL;
5838 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005839 }
5840
Willy Tarreau721d8e02017-12-01 18:25:08 +01005841 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005842 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005843 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5844 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005845 err_code |= ERR_ALERT | ERR_FATAL;
5846 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005847 }
5848 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5849 }
5850 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005851 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005852 err_code |= ERR_ALERT | ERR_FATAL;
5853 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005854 }
5855 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005856#ifdef TPROXY
5857 else if (!strcmp(args[0], "transparent")) {
5858 /* enable transparent proxy connections */
5859 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005860 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5861 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005862 }
5863#endif
5864 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005865 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005866 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005867
Willy Tarreaubaaee002006-06-26 02:48:02 +02005868 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005869 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005870 err_code |= ERR_ALERT | ERR_FATAL;
5871 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005872 }
5873 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005874 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5875 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005876 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005877 else if (!strcmp(args[0], "backlog")) { /* backlog */
5878 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005879 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005880
5881 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005882 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005883 err_code |= ERR_ALERT | ERR_FATAL;
5884 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005885 }
5886 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005887 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5888 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005889 }
Willy Tarreau86034312006-12-29 00:10:33 +01005890 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005891 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005892 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005893
Willy Tarreau86034312006-12-29 00:10:33 +01005894 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005895 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005896 err_code |= ERR_ALERT | ERR_FATAL;
5897 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005898 }
5899 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005900 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5901 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005902 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005903 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5904 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005905 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005906 err_code |= ERR_ALERT | ERR_FATAL;
5907 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005908 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005909 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5910 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005911 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5912 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005913 err_code |= ERR_ALERT | ERR_FATAL;
5914 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005915 }
5916 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005917 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5918 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005919 }
5920 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005921 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005922 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005923 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005924
Willy Tarreaubaaee002006-06-26 02:48:02 +02005925 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005926 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005927 err_code |= ERR_ALERT | ERR_FATAL;
5928 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005929 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005930 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005931 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005932
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005933 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005934 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005935 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005936 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005937 goto out;
5938 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005939
5940 proto = protocol_by_family(sk->ss_family);
5941 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005942 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5943 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005944 err_code |= ERR_ALERT | ERR_FATAL;
5945 goto out;
5946 }
5947
5948 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005949 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5950 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005951 err_code |= ERR_ALERT | ERR_FATAL;
5952 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005953 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005954
5955 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005956 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5957 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005958 err_code |= ERR_ALERT | ERR_FATAL;
5959 goto out;
5960 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005961
William Lallemanddf1425a2015-04-28 20:17:49 +02005962 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5963 goto out;
5964
Willy Tarreaud5191e72010-02-09 20:50:45 +01005965 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005966 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005967 }
5968 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005969 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005970 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005971
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005972 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005973 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005974 err_code |= ERR_ALERT | ERR_FATAL;
5975 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005976 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005977 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005978 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005979 /**
5980 * The syntax for hash-type config element is
5981 * hash-type {map-based|consistent} [[<algo>] avalanche]
5982 *
5983 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5984 */
5985 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005986
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005987 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5988 err_code |= ERR_WARN;
5989
5990 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005991 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
5992 }
5993 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005994 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
5995 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005996 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005997 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 -05005998 err_code |= ERR_ALERT | ERR_FATAL;
5999 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01006000 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006001 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006002 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006003 err_code |= ERR_ALERT | ERR_FATAL;
6004 goto out;
6005 }
Bhaskar98634f02013-10-29 23:30:51 -04006006
6007 /* set the hash function to use */
6008 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006009 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04006010 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006011
6012 /* if consistent with no argument, then avalanche modifier is also applied */
6013 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6014 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006015 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006016 /* set the hash function */
6017 if (!strcmp(args[2], "sdbm")) {
6018 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6019 }
6020 else if (!strcmp(args[2], "djb2")) {
6021 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006022 }
6023 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006024 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006025 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006026 else if (!strcmp(args[2], "crc32")) {
6027 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6028 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006029 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006030 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 -05006031 err_code |= ERR_ALERT | ERR_FATAL;
6032 goto out;
6033 }
6034
6035 /* set the hash modifier */
6036 if (!strcmp(args[3], "avalanche")) {
6037 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6038 }
6039 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006040 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 -05006041 err_code |= ERR_ALERT | ERR_FATAL;
6042 goto out;
6043 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006044 }
William Lallemanda73203e2012-03-12 12:48:57 +01006045 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006046 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6047 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006048 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006049 err_code |= ERR_ALERT | ERR_FATAL;
6050 goto out;
6051 }
6052 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6053 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006054 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 -04006055 err_code |= ERR_ALERT | ERR_FATAL;
6056 goto out;
6057 }
6058 }
William Lallemanda73203e2012-03-12 12:48:57 +01006059 else if (strcmp(args[0], "unique-id-format") == 0) {
6060 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006061 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006062 err_code |= ERR_ALERT | ERR_FATAL;
6063 goto out;
6064 }
William Lallemand3203ff42012-11-11 17:30:56 +01006065 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006066 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 +01006067 err_code |= ERR_ALERT | ERR_FATAL;
6068 goto out;
6069 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006070 free(curproxy->conf.uniqueid_format_string);
6071 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006072
Willy Tarreau62a61232013-04-12 18:13:46 +02006073 free(curproxy->conf.uif_file);
6074 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6075 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006076 }
William Lallemanda73203e2012-03-12 12:48:57 +01006077
6078 else if (strcmp(args[0], "unique-id-header") == 0) {
6079 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006080 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006081 err_code |= ERR_ALERT | ERR_FATAL;
6082 goto out;
6083 }
6084 free(curproxy->header_unique_id);
6085 curproxy->header_unique_id = strdup(args[1]);
6086 }
6087
William Lallemand723b73a2012-02-08 16:37:49 +01006088 else if (strcmp(args[0], "log-format") == 0) {
6089 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006090 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006091 err_code |= ERR_ALERT | ERR_FATAL;
6092 goto out;
6093 }
William Lallemand3203ff42012-11-11 17:30:56 +01006094 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006095 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 +01006096 err_code |= ERR_ALERT | ERR_FATAL;
6097 goto out;
6098 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006099 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6100 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006101
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006102 if (curproxy->conf.logformat_string == default_http_log_format)
6103 oldlogformat = "option httplog";
6104 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6105 oldlogformat = "option tcplog";
6106 else if (curproxy->conf.logformat_string == clf_http_log_format)
6107 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006108 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6109 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006110 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006111 if (curproxy->conf.logformat_string != default_http_log_format &&
6112 curproxy->conf.logformat_string != default_tcp_log_format &&
6113 curproxy->conf.logformat_string != clf_http_log_format)
6114 free(curproxy->conf.logformat_string);
6115 curproxy->conf.logformat_string = strdup(args[1]);
6116
6117 free(curproxy->conf.lfs_file);
6118 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6119 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006120
6121 /* get a chance to improve log-format error reporting by
6122 * reporting the correct line-number when possible.
6123 */
6124 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006125 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6126 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006127 err_code |= ERR_WARN;
6128 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006129 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006130 else if (!strcmp(args[0], "log-format-sd")) {
6131 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006132 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006133 err_code |= ERR_ALERT | ERR_FATAL;
6134 goto out;
6135 }
6136 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006137 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 +02006138 err_code |= ERR_ALERT | ERR_FATAL;
6139 goto out;
6140 }
6141
6142 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6143 free(curproxy->conf.logformat_sd_string);
6144 curproxy->conf.logformat_sd_string = strdup(args[1]);
6145
6146 free(curproxy->conf.lfsd_file);
6147 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6148 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6149
6150 /* get a chance to improve log-format-sd error reporting by
6151 * reporting the correct line-number when possible.
6152 */
6153 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006154 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6155 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006156 err_code |= ERR_WARN;
6157 }
6158 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006159 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6160 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006161 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 +01006162 err_code |= ERR_ALERT | ERR_FATAL;
6163 goto out;
6164 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006165 chunk_destroy(&curproxy->log_tag);
6166 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006167 }
William Lallemand0f99e342011-10-12 17:50:54 +02006168 else if (!strcmp(args[0], "log") && kwm == KWM_NO) {
6169 /* delete previous herited or defined syslog servers */
6170 struct logsrv *back;
6171
6172 if (*(args[1]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006173 ha_alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
William Lallemand0f99e342011-10-12 17:50:54 +02006174 err_code |= ERR_ALERT | ERR_FATAL;
6175 goto out;
6176 }
6177
William Lallemand723b73a2012-02-08 16:37:49 +01006178 list_for_each_entry_safe(tmplogsrv, back, &curproxy->logsrvs, list) {
6179 LIST_DEL(&tmplogsrv->list);
6180 free(tmplogsrv);
William Lallemand0f99e342011-10-12 17:50:54 +02006181 }
6182 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006183 else if (!strcmp(args[0], "log")) { /* syslog server address */
William Lallemand0f99e342011-10-12 17:50:54 +02006184 struct logsrv *logsrv;
6185
Willy Tarreaubaaee002006-06-26 02:48:02 +02006186 if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
William Lallemand0f99e342011-10-12 17:50:54 +02006187 /* copy global.logrsvs linked list to the end of curproxy->logsrvs */
William Lallemand723b73a2012-02-08 16:37:49 +01006188 list_for_each_entry(tmplogsrv, &global.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02006189 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01006190 memcpy(node, tmplogsrv, sizeof(struct logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02006191 LIST_INIT(&node->list);
6192 LIST_ADDQ(&curproxy->logsrvs, &node->list);
6193 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006194 }
6195 else if (*(args[1]) && *(args[2])) {
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006196 struct sockaddr_storage *sk;
6197 int port1, port2;
Willy Tarreau18324f52014-06-27 18:10:07 +02006198 int arg = 0;
6199 int len = 0;
William Lallemand0f99e342011-10-12 17:50:54 +02006200
Vincent Bernat02779b62016-04-03 13:48:43 +02006201 logsrv = calloc(1, sizeof(*logsrv));
Willy Tarreaubaaee002006-06-26 02:48:02 +02006202
Willy Tarreau18324f52014-06-27 18:10:07 +02006203 /* just after the address, a length may be specified */
6204 if (strcmp(args[arg+2], "len") == 0) {
6205 len = atoi(args[arg+3]);
6206 if (len < 80 || len > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006207 ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
6208 file, linenum, args[arg+3]);
Willy Tarreau18324f52014-06-27 18:10:07 +02006209 err_code |= ERR_ALERT | ERR_FATAL;
6210 goto out;
6211 }
6212 logsrv->maxlen = len;
6213
6214 /* skip these two args */
6215 arg += 2;
6216 }
6217 else
6218 logsrv->maxlen = MAX_SYSLOG_LEN;
6219
Christopher Faulet084aa962017-08-29 16:54:41 +02006220 if (logsrv->maxlen > global.max_syslog_len)
Willy Tarreau18324f52014-06-27 18:10:07 +02006221 global.max_syslog_len = logsrv->maxlen;
Willy Tarreau18324f52014-06-27 18:10:07 +02006222
Dragan Dosen1322d092015-09-22 16:05:32 +02006223 /* after the length, a format may be specified */
6224 if (strcmp(args[arg+2], "format") == 0) {
6225 logsrv->format = get_log_format(args[arg+3]);
6226 if (logsrv->format < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006227 ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
Dragan Dosen1322d092015-09-22 16:05:32 +02006228 err_code |= ERR_ALERT | ERR_FATAL;
6229 goto out;
6230 }
6231
6232 /* skip these two args */
6233 arg += 2;
6234 }
6235
William Lallemanddf1425a2015-04-28 20:17:49 +02006236 if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code))
6237 goto out;
6238
Willy Tarreau18324f52014-06-27 18:10:07 +02006239 logsrv->facility = get_log_facility(args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02006240 if (logsrv->facility < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006241 ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02006242 err_code |= ERR_ALERT | ERR_FATAL;
6243 goto out;
6244
Willy Tarreaubaaee002006-06-26 02:48:02 +02006245 }
6246
William Lallemand0f99e342011-10-12 17:50:54 +02006247 logsrv->level = 7; /* max syslog level = debug */
Willy Tarreau18324f52014-06-27 18:10:07 +02006248 if (*(args[arg+3])) {
6249 logsrv->level = get_log_level(args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02006250 if (logsrv->level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006251 ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02006252 err_code |= ERR_ALERT | ERR_FATAL;
6253 goto out;
6254
Willy Tarreaubaaee002006-06-26 02:48:02 +02006255 }
6256 }
6257
William Lallemand0f99e342011-10-12 17:50:54 +02006258 logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
Willy Tarreau18324f52014-06-27 18:10:07 +02006259 if (*(args[arg+4])) {
6260 logsrv->minlvl = get_log_level(args[arg+4]);
Willy Tarreauf7f057b2013-01-24 00:31:24 +01006261 if (logsrv->minlvl < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006262 ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
William Lallemand0f99e342011-10-12 17:50:54 +02006263 err_code |= ERR_ALERT | ERR_FATAL;
6264 goto out;
6265
Willy Tarreauf7edefa2009-05-10 17:20:05 +02006266 }
6267 }
6268
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006269 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006270 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006271 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006272 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006273 goto out;
6274 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006275
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006276 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006277
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006278 if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006279 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006280 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6281 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006282 err_code |= ERR_ALERT | ERR_FATAL;
6283 goto out;
6284 }
6285
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006286 if (!port1)
William Lallemand0f99e342011-10-12 17:50:54 +02006287 set_host_port(&logsrv->addr, SYSLOG_PORT);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006288 }
William Lallemand0f99e342011-10-12 17:50:54 +02006289
6290 LIST_ADDQ(&curproxy->logsrvs, &logsrv->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006291 }
6292 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006293 ha_alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
6294 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02006295 err_code |= ERR_ALERT | ERR_FATAL;
6296 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006297 }
6298 }
6299 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006300 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006301 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006302 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006303 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006304
Willy Tarreau977b8e42006-12-29 14:19:17 +01006305 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006306 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006307
Willy Tarreaubaaee002006-06-26 02:48:02 +02006308 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006309 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6310 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006311 err_code |= ERR_ALERT | ERR_FATAL;
6312 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006313 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006314
6315 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006316 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6317 free(curproxy->conn_src.iface_name);
6318 curproxy->conn_src.iface_name = NULL;
6319 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006320
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006321 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006322 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006323 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6324 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006325 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006326 goto out;
6327 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006328
6329 proto = protocol_by_family(sk->ss_family);
6330 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006331 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6332 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006333 err_code |= ERR_ALERT | ERR_FATAL;
6334 goto out;
6335 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006336
6337 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006338 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6339 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006340 err_code |= ERR_ALERT | ERR_FATAL;
6341 goto out;
6342 }
6343
Willy Tarreauef9a3602012-12-08 22:29:20 +01006344 curproxy->conn_src.source_addr = *sk;
6345 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006346
6347 cur_arg = 2;
6348 while (*(args[cur_arg])) {
6349 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006350#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006351 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006352 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6353 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006354 err_code |= ERR_ALERT | ERR_FATAL;
6355 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006356 }
6357
6358 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006359 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6360 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006361 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006362 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6363 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006364 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6365 char *name, *end;
6366
6367 name = args[cur_arg+1] + 7;
6368 while (isspace(*name))
6369 name++;
6370
6371 end = name;
6372 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6373 end++;
6374
Willy Tarreauef9a3602012-12-08 22:29:20 +01006375 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6376 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6377 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6378 curproxy->conn_src.bind_hdr_len = end - name;
6379 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6380 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6381 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006382
6383 /* now look for an occurrence number */
6384 while (isspace(*end))
6385 end++;
6386 if (*end == ',') {
6387 end++;
6388 name = end;
6389 if (*end == '-')
6390 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006391 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006392 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006393 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006394 }
6395
Willy Tarreauef9a3602012-12-08 22:29:20 +01006396 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006397 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6398 " occurrences values smaller than %d.\n",
6399 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006400 err_code |= ERR_ALERT | ERR_FATAL;
6401 goto out;
6402 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006403 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006404 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006405
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006406 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006407 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006408 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6409 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006410 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006411 goto out;
6412 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006413
6414 proto = protocol_by_family(sk->ss_family);
6415 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006416 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6417 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006418 err_code |= ERR_ALERT | ERR_FATAL;
6419 goto out;
6420 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006421
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006422 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006423 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6424 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006425 err_code |= ERR_ALERT | ERR_FATAL;
6426 goto out;
6427 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006428 curproxy->conn_src.tproxy_addr = *sk;
6429 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006430 }
6431 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006432#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006433 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6434 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006435 err_code |= ERR_ALERT | ERR_FATAL;
6436 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006437#endif
6438 cur_arg += 2;
6439 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006440 }
6441
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006442 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6443#ifdef SO_BINDTODEVICE
6444 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006445 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6446 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006447 err_code |= ERR_ALERT | ERR_FATAL;
6448 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006449 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006450 free(curproxy->conn_src.iface_name);
6451 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6452 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006453 global.last_checks |= LSTCHK_NETADM;
6454#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006455 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6456 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006457 err_code |= ERR_ALERT | ERR_FATAL;
6458 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006459#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006460 cur_arg += 2;
6461 continue;
6462 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006463 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6464 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006465 err_code |= ERR_ALERT | ERR_FATAL;
6466 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006467 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006468 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006469 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006470 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6471 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006472 err_code |= ERR_ALERT | ERR_FATAL;
6473 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006474 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006475 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006476 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006477 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6478 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006479 err_code |= ERR_ALERT | ERR_FATAL;
6480 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006481 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006482
6483 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006484 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006485 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006486 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006487 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006488 }
6489 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006490 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006491 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006492 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006493 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006494 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006495 }
6496 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006497 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006498 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006499 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006500 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006501 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006502 }
6503 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006504 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006505 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006506 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006507 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006508 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006509 }
6510 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006511 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006512 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006513 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006514 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006515 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006516 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006517 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006518 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006519 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006520 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006521 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006522 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006523 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006524 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006525 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006526 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6527 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006528 err_code |= ERR_ALERT | ERR_FATAL;
6529 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006530 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006531
6532 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006533 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006534 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006535 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006536 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006537 }
6538 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006539 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006540 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006541 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006542 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006543 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006544 }
6545 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006546 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006547 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006548 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006549 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006550 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006551 }
6552 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006553 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006554 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006555 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006556 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006557 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006558 }
6559 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006560 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006561 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006562 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006563 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006564 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006565 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006566 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006567 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006568 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006569 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006570 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006571 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006572 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006573 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006574 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006575
Willy Tarreaubaaee002006-06-26 02:48:02 +02006576 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006577 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006578 err_code |= ERR_ALERT | ERR_FATAL;
6579 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006580 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006581 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006582 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006583
Willy Tarreaubaaee002006-06-26 02:48:02 +02006584 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006585 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006586 err_code |= ERR_ALERT | ERR_FATAL;
6587 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006588 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006589
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006590 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006591 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006592 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6593 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006594 err_code |= ERR_ALERT | ERR_FATAL;
6595 goto out;
6596 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006597 err_code |= warnif_cond_conflicts(cond,
6598 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6599 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006600 }
6601 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006602 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6603 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006604 err_code |= ERR_ALERT | ERR_FATAL;
6605 goto out;
6606 }
6607
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006608 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006609 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006610 wl->s = strdup(args[1]);
6611 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006612 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006613 }
6614 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006615 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006616 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6617 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006618 err_code |= ERR_ALERT | ERR_FATAL;
6619 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006620 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006621
Willy Tarreauade5ec42010-01-28 19:33:49 +01006622 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006623 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006624 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006625 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006626 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006627 }
6628 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006629 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006630 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006631 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006632 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006633 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006634 }
6635 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006636 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006637 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006638 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006639 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006640 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006641 }
6642 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006643 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006644 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6645 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006646 err_code |= ERR_ALERT | ERR_FATAL;
6647 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006648 }
6649
Willy Tarreauade5ec42010-01-28 19:33:49 +01006650 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006651 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006652 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006653 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006654 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006655 }
6656 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006657 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006658 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006659 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006660 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006661 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006662 }
6663 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006664 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006665 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006666 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006667 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006668 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006669 }
6670 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006671 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006672
Willy Tarreaubaaee002006-06-26 02:48:02 +02006673 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006674 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006675 err_code |= ERR_ALERT | ERR_FATAL;
6676 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006677 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006678 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006679 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006680
Willy Tarreaubaaee002006-06-26 02:48:02 +02006681 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006682 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006683 err_code |= ERR_ALERT | ERR_FATAL;
6684 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006685 }
6686
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006687 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006688 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006689 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6690 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006691 err_code |= ERR_ALERT | ERR_FATAL;
6692 goto out;
6693 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006694 err_code |= warnif_cond_conflicts(cond,
6695 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6696 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006697 }
6698 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006699 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6700 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006701 err_code |= ERR_ALERT | ERR_FATAL;
6702 goto out;
6703 }
6704
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006705 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006706 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006707 wl->s = strdup(args[1]);
6708 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006709 }
6710 else if (!strcmp(args[0], "errorloc") ||
6711 !strcmp(args[0], "errorloc302") ||
6712 !strcmp(args[0], "errorloc303")) { /* error location */
6713 int errnum, errlen;
6714 char *err;
6715
Willy Tarreau977b8e42006-12-29 14:19:17 +01006716 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006717 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006718
Willy Tarreaubaaee002006-06-26 02:48:02 +02006719 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006720 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 +02006721 err_code |= ERR_ALERT | ERR_FATAL;
6722 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006723 }
6724
6725 errnum = atol(args[1]);
6726 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006727 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6728 err = malloc(errlen);
6729 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006730 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006731 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6732 err = malloc(errlen);
6733 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006734 }
6735
Willy Tarreau0f772532006-12-23 20:51:41 +01006736 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6737 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006738 chunk_destroy(&curproxy->errmsg[rc]);
6739 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006740 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006741 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006742 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006743
6744 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006745 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6746 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006747 free(err);
6748 }
6749 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006750 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6751 int errnum, errlen, fd;
6752 char *err;
6753 struct stat stat;
6754
6755 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006756 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006757
6758 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006759 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 +02006760 err_code |= ERR_ALERT | ERR_FATAL;
6761 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006762 }
6763
6764 fd = open(args[2], O_RDONLY);
6765 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006766 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6767 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006768 if (fd >= 0)
6769 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006770 err_code |= ERR_ALERT | ERR_FATAL;
6771 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006772 }
6773
Willy Tarreau27a674e2009-08-17 07:23:33 +02006774 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006775 errlen = stat.st_size;
6776 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006777 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6778 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006779 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006780 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006781 }
6782
6783 err = malloc(errlen); /* malloc() must succeed during parsing */
6784 errnum = read(fd, err, errlen);
6785 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006786 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6787 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006788 close(fd);
6789 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006790 err_code |= ERR_ALERT | ERR_FATAL;
6791 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006792 }
6793 close(fd);
6794
6795 errnum = atol(args[1]);
6796 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6797 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006798 chunk_destroy(&curproxy->errmsg[rc]);
6799 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006800 break;
6801 }
6802 }
6803
6804 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006805 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6806 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006807 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006808 free(err);
6809 }
6810 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006811 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006812 struct cfg_kw_list *kwl;
6813 int index;
6814
6815 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6816 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6817 if (kwl->kw[index].section != CFG_LISTEN)
6818 continue;
6819 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6820 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006821 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006822 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006823 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006824 err_code |= ERR_ALERT | ERR_FATAL;
6825 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006826 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006827 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006828 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006829 err_code |= ERR_WARN;
6830 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006831 }
Willy Tarreau93893792009-07-23 13:19:11 +02006832 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006833 }
6834 }
6835 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006836
Christopher Faulet767a84b2017-11-24 16:50:31 +01006837 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006838 err_code |= ERR_ALERT | ERR_FATAL;
6839 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006840 }
Willy Tarreau93893792009-07-23 13:19:11 +02006841 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006842 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006843 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006844}
6845
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006846int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006847cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6848{
6849#ifdef CONFIG_HAP_NS
6850 const char *err;
6851 const char *item = args[0];
6852
6853 if (!strcmp(item, "namespace_list")) {
6854 return 0;
6855 }
6856 else if (!strcmp(item, "namespace")) {
6857 size_t idx = 1;
6858 const char *current;
6859 while (*(current = args[idx++])) {
6860 err = invalid_char(current);
6861 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006862 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6863 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006864 return ERR_ALERT | ERR_FATAL;
6865 }
6866
6867 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006868 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6869 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006870 return ERR_ALERT | ERR_FATAL;
6871 }
6872 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006873 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6874 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006875 return ERR_ALERT | ERR_FATAL;
6876 }
6877 }
6878 }
6879
6880 return 0;
6881#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006882 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6883 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006884 return ERR_ALERT | ERR_FATAL;
6885#endif
6886}
6887
6888int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006889cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6890{
6891
6892 int err_code = 0;
6893 const char *err;
6894
6895 if (!strcmp(args[0], "userlist")) { /* new userlist */
6896 struct userlist *newul;
6897
6898 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006899 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6900 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006901 err_code |= ERR_ALERT | ERR_FATAL;
6902 goto out;
6903 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006904 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6905 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006906
6907 err = invalid_char(args[1]);
6908 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006909 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6910 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006911 err_code |= ERR_ALERT | ERR_FATAL;
6912 goto out;
6913 }
6914
6915 for (newul = userlist; newul; newul = newul->next)
6916 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006917 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6918 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006919 err_code |= ERR_WARN;
6920 goto out;
6921 }
6922
Vincent Bernat02779b62016-04-03 13:48:43 +02006923 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006924 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006925 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006926 err_code |= ERR_ALERT | ERR_ABORT;
6927 goto out;
6928 }
6929
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006930 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006931 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006932 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006933 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006934 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006935 goto out;
6936 }
6937
6938 newul->next = userlist;
6939 userlist = newul;
6940
6941 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006942 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006943 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006944 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006945
6946 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006947 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6948 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006949 err_code |= ERR_ALERT | ERR_FATAL;
6950 goto out;
6951 }
6952
6953 err = invalid_char(args[1]);
6954 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006955 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6956 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006957 err_code |= ERR_ALERT | ERR_FATAL;
6958 goto out;
6959 }
6960
William Lallemand4ac9f542015-05-28 18:03:51 +02006961 if (!userlist)
6962 goto out;
6963
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006964 for (ag = userlist->groups; ag; ag = ag->next)
6965 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006966 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6967 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006968 err_code |= ERR_ALERT;
6969 goto out;
6970 }
6971
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006972 ag = calloc(1, sizeof(*ag));
6973 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006974 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006975 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006976 goto out;
6977 }
6978
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006979 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006980 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006981 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006982 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006983 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006984 goto out;
6985 }
6986
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006987 cur_arg = 2;
6988
6989 while (*args[cur_arg]) {
6990 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006991 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006992 cur_arg += 2;
6993 continue;
6994 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006995 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6996 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006997 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006998 free(ag->groupusers);
6999 free(ag->name);
7000 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007001 goto out;
7002 }
7003 }
7004
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007005 ag->next = userlist->groups;
7006 userlist->groups = ag;
7007
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007008 } else if (!strcmp(args[0], "user")) { /* new user */
7009 struct auth_users *newuser;
7010 int cur_arg;
7011
7012 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007013 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
7014 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007015 err_code |= ERR_ALERT | ERR_FATAL;
7016 goto out;
7017 }
William Lallemand4ac9f542015-05-28 18:03:51 +02007018 if (!userlist)
7019 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007020
7021 for (newuser = userlist->users; newuser; newuser = newuser->next)
7022 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007023 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
7024 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007025 err_code |= ERR_ALERT;
7026 goto out;
7027 }
7028
Vincent Bernat02779b62016-04-03 13:48:43 +02007029 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007030 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007031 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007032 err_code |= ERR_ALERT | ERR_ABORT;
7033 goto out;
7034 }
7035
7036 newuser->user = strdup(args[1]);
7037
7038 newuser->next = userlist->users;
7039 userlist->users = newuser;
7040
7041 cur_arg = 2;
7042
7043 while (*args[cur_arg]) {
7044 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02007045#ifdef CONFIG_HAP_CRYPT
7046 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007047 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
7048 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02007049 err_code |= ERR_ALERT | ERR_FATAL;
7050 goto out;
7051 }
7052#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01007053 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
7054 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007055 err_code |= ERR_ALERT;
7056#endif
7057 newuser->pass = strdup(args[cur_arg + 1]);
7058 cur_arg += 2;
7059 continue;
7060 } else if (!strcmp(args[cur_arg], "insecure-password")) {
7061 newuser->pass = strdup(args[cur_arg + 1]);
7062 newuser->flags |= AU_O_INSECURE;
7063 cur_arg += 2;
7064 continue;
7065 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007066 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007067 cur_arg += 2;
7068 continue;
7069 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007070 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
7071 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007072 err_code |= ERR_ALERT | ERR_FATAL;
7073 goto out;
7074 }
7075 }
7076 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007077 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 +01007078 err_code |= ERR_ALERT | ERR_FATAL;
7079 }
7080
7081out:
7082 return err_code;
7083}
Willy Tarreaubaaee002006-06-26 02:48:02 +02007084
Christopher Faulet79bdef32016-11-04 22:36:15 +01007085int
7086cfg_parse_scope(const char *file, int linenum, char *line)
7087{
7088 char *beg, *end, *scope = NULL;
7089 int err_code = 0;
7090 const char *err;
7091
7092 beg = line + 1;
7093 end = strchr(beg, ']');
7094
7095 /* Detect end of scope declaration */
7096 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007097 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
7098 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007099 err_code |= ERR_ALERT | ERR_FATAL;
7100 goto out;
7101 }
7102
7103 /* Get scope name and check its validity */
7104 scope = my_strndup(beg, end-beg);
7105 err = invalid_char(scope);
7106 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007107 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
7108 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007109 err_code |= ERR_ALERT | ERR_ABORT;
7110 goto out;
7111 }
7112
7113 /* Be sure to have a scope declaration alone on its line */
7114 line = end+1;
7115 while (isspace((unsigned char)*line))
7116 line++;
7117 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007118 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7119 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007120 err_code |= ERR_ALERT | ERR_ABORT;
7121 goto out;
7122 }
7123
7124 /* We have a valid scope declaration, save it */
7125 free(cfg_scope);
7126 cfg_scope = scope;
7127 scope = NULL;
7128
7129 out:
7130 free(scope);
7131 return err_code;
7132}
7133
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01007134int
7135cfg_parse_track_sc_num(unsigned int *track_sc_num,
7136 const char *arg, const char *end, char **errmsg)
7137{
7138 const char *p;
7139 unsigned int num;
7140
7141 p = arg;
7142 num = read_uint64(&arg, end);
7143
7144 if (arg != end) {
7145 memprintf(errmsg, "Wrong track-sc number '%s'", p);
7146 return -1;
7147 }
7148
7149 if (num >= MAX_SESS_STKCTR) {
7150 memprintf(errmsg, "%u track-sc number exceeding "
7151 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
7152 return -1;
7153 }
7154
7155 *track_sc_num = num;
7156 return 0;
7157}
7158
Willy Tarreaubaaee002006-06-26 02:48:02 +02007159/*
7160 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007161 * Returns the error code, 0 if OK, or any combination of :
7162 * - ERR_ABORT: must abort ASAP
7163 * - ERR_FATAL: we can continue parsing but not start the service
7164 * - ERR_WARN: a warning has been emitted
7165 * - ERR_ALERT: an alert has been emitted
7166 * Only the two first ones can stop processing, the two others are just
7167 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007168 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007169int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007170{
William Lallemand64e84512015-05-12 14:25:37 +02007171 char *thisline;
7172 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007173 FILE *f;
7174 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007175 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007176 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007177 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007178 int readbytes = 0;
7179
7180 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007181 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007182 return -1;
7183 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007184
David Carlier97880bb2016-04-08 10:35:26 +01007185 if ((f=fopen(file,"r")) == NULL) {
7186 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007187 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007188 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007189
William Lallemandb2f07452015-05-12 14:27:13 +02007190next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007191 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007192 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007193 char *end;
7194 char *args[MAX_LINE_ARGS + 1];
7195 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007196 int dquote = 0; /* double quote */
7197 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007198
Willy Tarreaubaaee002006-06-26 02:48:02 +02007199 linenum++;
7200
7201 end = line + strlen(line);
7202
William Lallemand64e84512015-05-12 14:25:37 +02007203 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007204 /* Check if we reached the limit and the last char is not \n.
7205 * Watch out for the last line without the terminating '\n'!
7206 */
William Lallemand64e84512015-05-12 14:25:37 +02007207 char *newline;
7208 int newlinesize = linesize * 2;
7209
7210 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7211 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007212 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7213 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007214 err_code |= ERR_ALERT | ERR_FATAL;
7215 continue;
7216 }
7217
7218 readbytes = linesize - 1;
7219 linesize = newlinesize;
7220 thisline = newline;
7221 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007222 }
7223
William Lallemand64e84512015-05-12 14:25:37 +02007224 readbytes = 0;
7225
Willy Tarreaubaaee002006-06-26 02:48:02 +02007226 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007227 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007228 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007229
Christopher Faulet79bdef32016-11-04 22:36:15 +01007230
7231 if (*line == '[') {/* This is the begining if a scope */
7232 err_code |= cfg_parse_scope(file, linenum, line);
7233 goto next_line;
7234 }
7235
Willy Tarreaubaaee002006-06-26 02:48:02 +02007236 arg = 0;
7237 args[arg] = line;
7238
7239 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007240 if (*line == '"' && !squote) { /* double quote outside single quotes */
7241 if (dquote)
7242 dquote = 0;
7243 else
7244 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007245 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007246 end--;
7247 }
7248 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7249 if (squote)
7250 squote = 0;
7251 else
7252 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007253 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007254 end--;
7255 }
7256 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007257 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7258 * C equivalent value. Other combinations left unchanged (eg: \1).
7259 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007260 int skip = 0;
7261 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7262 *line = line[1];
7263 skip = 1;
7264 }
7265 else if (line[1] == 'r') {
7266 *line = '\r';
7267 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007268 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007269 else if (line[1] == 'n') {
7270 *line = '\n';
7271 skip = 1;
7272 }
7273 else if (line[1] == 't') {
7274 *line = '\t';
7275 skip = 1;
7276 }
7277 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007278 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007279 unsigned char hex1, hex2;
7280 hex1 = toupper(line[2]) - '0';
7281 hex2 = toupper(line[3]) - '0';
7282 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7283 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7284 *line = (hex1<<4) + hex2;
7285 skip = 3;
7286 }
7287 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007288 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007289 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007290 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007291 } else if (line[1] == '"') {
7292 *line = '"';
7293 skip = 1;
7294 } else if (line[1] == '\'') {
7295 *line = '\'';
7296 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007297 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7298 *line = '$';
7299 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007300 }
7301 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007302 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007303 end -= skip;
7304 }
7305 line++;
7306 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007307 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007308 /* end of string, end of loop */
7309 *line = 0;
7310 break;
7311 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007312 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007313 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007314 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007315 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007316 line++;
7317 args[++arg] = line;
7318 }
William Lallemandb2f07452015-05-12 14:27:13 +02007319 else if (dquote && *line == '$') {
7320 /* environment variables are evaluated inside double quotes */
7321 char *var_beg;
7322 char *var_end;
7323 char save_char;
7324 char *value;
7325 int val_len;
7326 int newlinesize;
7327 int braces = 0;
7328
7329 var_beg = line + 1;
7330 var_end = var_beg;
7331
7332 if (*var_beg == '{') {
7333 var_beg++;
7334 var_end++;
7335 braces = 1;
7336 }
7337
7338 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007339 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 +02007340 err_code |= ERR_ALERT | ERR_FATAL;
7341 goto next_line; /* skip current line */
7342 }
7343
7344 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7345 var_end++;
7346
7347 save_char = *var_end;
7348 *var_end = '\0';
7349 value = getenv(var_beg);
7350 *var_end = save_char;
7351 val_len = value ? strlen(value) : 0;
7352
7353 if (braces) {
7354 if (*var_end == '}') {
7355 var_end++;
7356 braces = 0;
7357 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007358 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007359 err_code |= ERR_ALERT | ERR_FATAL;
7360 goto next_line; /* skip current line */
7361 }
7362 }
7363
7364 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7365
7366 /* if not enough space in thisline */
7367 if (newlinesize > linesize) {
7368 char *newline;
7369
7370 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7371 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007372 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007373 err_code |= ERR_ALERT | ERR_FATAL;
7374 goto next_line; /* slip current line */
7375 }
7376 /* recompute pointers if realloc returns a new pointer */
7377 if (newline != thisline) {
7378 int i;
7379 int diff;
7380
7381 for (i = 0; i <= arg; i++) {
7382 diff = args[i] - thisline;
7383 args[i] = newline + diff;
7384 }
7385
7386 diff = var_end - thisline;
7387 var_end = newline + diff;
7388 diff = end - thisline;
7389 end = newline + diff;
7390 diff = line - thisline;
7391 line = newline + diff;
7392 thisline = newline;
7393 }
7394 linesize = newlinesize;
7395 }
7396
7397 /* insert value inside the line */
7398 memmove(line + val_len, var_end, end - var_end + 1);
7399 memcpy(line, value, val_len);
7400 end += val_len - (var_end - line);
7401 line += val_len;
7402 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007403 else {
7404 line++;
7405 }
7406 }
William Lallemandb2f07452015-05-12 14:27:13 +02007407
William Lallemandf9873ba2015-05-05 17:37:14 +02007408 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007409 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007410 err_code |= ERR_ALERT | ERR_FATAL;
7411 }
7412
7413 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007414 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007415 err_code |= ERR_ALERT | ERR_FATAL;
7416 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007417
7418 /* empty line */
7419 if (!**args)
7420 continue;
7421
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007422 if (*line) {
7423 /* we had to stop due to too many args.
7424 * Let's terminate the string, print the offending part then cut the
7425 * last arg.
7426 */
7427 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7428 line++;
7429 *line = '\0';
7430
Christopher Faulet767a84b2017-11-24 16:50:31 +01007431 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7432 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007433 err_code |= ERR_ALERT | ERR_FATAL;
7434 args[arg] = line;
7435 }
7436
Willy Tarreau540abe42007-05-02 20:50:16 +02007437 /* zero out remaining args and ensure that at least one entry
7438 * is zeroed out.
7439 */
7440 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007441 args[arg] = line;
7442 }
7443
Willy Tarreau3842f002009-06-14 11:39:52 +02007444 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007445 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007446 char *tmp;
7447
Willy Tarreau3842f002009-06-14 11:39:52 +02007448 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007449 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007450 for (arg=0; *args[arg+1]; arg++)
7451 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007452 *tmp = '\0'; // fix the next arg to \0
7453 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007454 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007455 else if (!strcmp(args[0], "default")) {
7456 kwm = KWM_DEF;
7457 for (arg=0; *args[arg+1]; arg++)
7458 args[arg] = args[arg+1]; // shift args after inversion
7459 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007460
William Lallemand0f99e342011-10-12 17:50:54 +02007461 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7462 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007463 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007464 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007465 }
7466
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007467 /* detect section start */
7468 list_for_each_entry(ics, &sections, list) {
7469 if (strcmp(args[0], ics->section_name) == 0) {
7470 cursection = ics->section_name;
7471 cs = ics;
7472 break;
7473 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007474 }
7475
William Lallemandd2ff56d2017-10-16 11:06:50 +02007476 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007477 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007478 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007479 } else {
7480 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007481
William Lallemandd2ff56d2017-10-16 11:06:50 +02007482 if (pcs != cs && pcs && pcs->post_section_parser) {
7483 err_code |= pcs->post_section_parser();
7484 if (err_code & ERR_ABORT)
7485 goto err;
7486 }
7487
7488 err_code |= cs->section_parser(file, linenum, args, kwm);
7489 if (err_code & ERR_ABORT)
7490 goto err;
7491 }
7492 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007493 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007494
7495 if (pcs == cs && pcs && pcs->post_section_parser)
7496 err_code |= pcs->post_section_parser();
7497
7498err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007499 free(cfg_scope);
7500 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007501 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007502 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007503 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007504 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007505}
7506
Willy Tarreau64ab6072014-09-16 12:17:36 +02007507/* This function propagates processes from frontend <from> to backend <to> so
7508 * that it is always guaranteed that a backend pointed to by a frontend is
7509 * bound to all of its processes. After that, if the target is a "listen"
7510 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007511 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007512 * checked first to ensure that <to> is already bound to all processes of
7513 * <from>, there is no risk of looping and we ensure to follow the shortest
7514 * path to the destination.
7515 *
7516 * It is possible to set <to> to NULL for the first call so that the function
7517 * takes care of visiting the initial frontend in <from>.
7518 *
7519 * It is important to note that the function relies on the fact that all names
7520 * have already been resolved.
7521 */
7522void propagate_processes(struct proxy *from, struct proxy *to)
7523{
7524 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007525
7526 if (to) {
7527 /* check whether we need to go down */
7528 if (from->bind_proc &&
7529 (from->bind_proc & to->bind_proc) == from->bind_proc)
7530 return;
7531
7532 if (!from->bind_proc && !to->bind_proc)
7533 return;
7534
7535 to->bind_proc = from->bind_proc ?
7536 (to->bind_proc | from->bind_proc) : 0;
7537
7538 /* now propagate down */
7539 from = to;
7540 }
7541
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007542 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007543 return;
7544
Willy Tarreauf6b70012014-12-18 14:00:43 +01007545 if (from->state == PR_STSTOPPED)
7546 return;
7547
Willy Tarreau64ab6072014-09-16 12:17:36 +02007548 /* default_backend */
7549 if (from->defbe.be)
7550 propagate_processes(from, from->defbe.be);
7551
7552 /* use_backend */
7553 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007554 if (rule->dynamic)
7555 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007556 to = rule->be.backend;
7557 propagate_processes(from, to);
7558 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007559}
7560
Willy Tarreaubb925012009-07-23 13:36:36 +02007561/*
7562 * Returns the error code, 0 if OK, or any combination of :
7563 * - ERR_ABORT: must abort ASAP
7564 * - ERR_FATAL: we can continue parsing but not start the service
7565 * - ERR_WARN: a warning has been emitted
7566 * - ERR_ALERT: an alert has been emitted
7567 * Only the two first ones can stop processing, the two others are just
7568 * indicators.
7569 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007570int check_config_validity()
7571{
7572 int cfgerr = 0;
7573 struct proxy *curproxy = NULL;
7574 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007575 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007576 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007577 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007578 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007579 struct cfg_postparser *postparser;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007580
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007581 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007582 /*
7583 * Now, check for the integrity of all that we have collected.
7584 */
7585
7586 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007587 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007588
Willy Tarreau193b8c62012-11-22 00:17:38 +01007589 if (!global.tune.max_http_hdr)
7590 global.tune.max_http_hdr = MAX_HTTP_HDR;
7591
7592 if (!global.tune.cookie_len)
7593 global.tune.cookie_len = CAPTURE_LEN;
7594
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007595 if (!global.tune.requri_len)
7596 global.tune.requri_len = REQURI_LEN;
7597
Willy Tarreaubafbe012017-11-24 17:34:44 +01007598 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007599
Willy Tarreaubafbe012017-11-24 17:34:44 +01007600 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007601
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007602 /* Post initialisation of the users and groups lists. */
7603 err_code = userlist_postinit();
7604 if (err_code != ERR_NONE)
7605 goto out;
7606
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007607 /* first, we will invert the proxy list order */
7608 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007609 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007610 struct proxy *next;
7611
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007612 next = proxies_list->next;
7613 proxies_list->next = curproxy;
7614 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007615 if (!next)
7616 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007617 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007618 }
7619
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007620 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007621 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007622 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007623 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007624 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007625 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007626 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007627 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007628
Willy Tarreau050536d2012-10-04 08:47:34 +02007629 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007630 /* proxy ID not set, use automatic numbering with first
7631 * spare entry starting with next_pxid.
7632 */
7633 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7634 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7635 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007636 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007637 next_pxid++;
7638
Willy Tarreau55ea7572007-06-17 19:56:27 +02007639
Willy Tarreaubaaee002006-06-26 02:48:02 +02007640 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007641 /* ensure we don't keep listeners uselessly bound */
7642 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007643 free((void *)curproxy->table.peers.name);
7644 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007645 continue;
7646 }
7647
Willy Tarreau102df612014-05-07 23:56:38 +02007648 /* Check multi-process mode compatibility for the current proxy */
7649
7650 if (curproxy->bind_proc) {
7651 /* an explicit bind-process was specified, let's check how many
7652 * processes remain.
7653 */
David Carliere6c39412015-07-02 07:00:17 +00007654 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007655
7656 curproxy->bind_proc &= nbits(global.nbproc);
7657 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007658 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 +02007659 curproxy->bind_proc = 1;
7660 }
7661 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007662 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 +02007663 curproxy->bind_proc = 0;
7664 }
7665 }
7666
Willy Tarreau3d209582014-05-09 17:06:11 +02007667 /* check and reduce the bind-proc of each listener */
7668 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7669 unsigned long mask;
7670
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007671 /* HTTP frontends with "h2" as ALPN/NPN will work in
7672 * HTTP/2 and absolutely require buffers 16kB or larger.
7673 */
7674#ifdef USE_OPENSSL
7675 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7676#ifdef OPENSSL_NPN_NEGOTIATED
7677 /* check NPN */
7678 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007679 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",
7680 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007681 cfgerr++;
7682 }
7683#endif
7684#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7685 /* check ALPN */
7686 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007687 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",
7688 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007689 cfgerr++;
7690 }
7691#endif
7692 } /* HTTP && bufsize < 16384 */
7693#endif
7694
Willy Tarreau3d209582014-05-09 17:06:11 +02007695 if (!bind_conf->bind_proc)
7696 continue;
7697
7698 mask = nbits(global.nbproc);
7699 if (curproxy->bind_proc)
7700 mask &= curproxy->bind_proc;
7701 /* mask cannot be null here thanks to the previous checks */
7702
David Carliere6c39412015-07-02 07:00:17 +00007703 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007704 bind_conf->bind_proc &= mask;
7705
7706 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007707 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",
7708 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007709 bind_conf->bind_proc = mask & ~(mask - 1);
7710 }
7711 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007712 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",
7713 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007714 bind_conf->bind_proc = 0;
7715 }
7716 }
7717
Willy Tarreauff01a212009-03-15 13:46:16 +01007718 switch (curproxy->mode) {
7719 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007720 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007721 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007722 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7723 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007724 cfgerr++;
7725 }
7726
7727 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007728 ha_warning("config : servers will be ignored for %s '%s'.\n",
7729 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007730 break;
7731
7732 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007733 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007734 break;
7735
7736 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007737 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007738 break;
7739 }
7740
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007741 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007742 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7743 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007744 err_code |= ERR_WARN;
7745 }
7746
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007747 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007748 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007749 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007750 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7751 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007752 cfgerr++;
7753 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007754#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007755 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007756 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7757 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007758 cfgerr++;
7759 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007760#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007761 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007762 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7763 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007764 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007765 }
7766 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007767 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007768 /* If no LB algo is set in a backend, and we're not in
7769 * transparent mode, dispatch mode nor proxy mode, we
7770 * want to use balance roundrobin by default.
7771 */
7772 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7773 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007774 }
7775 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007776
Willy Tarreau1620ec32011-08-06 17:05:02 +02007777 if (curproxy->options & PR_O_DISPATCH)
7778 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7779 else if (curproxy->options & PR_O_HTTP_PROXY)
7780 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7781 else if (curproxy->options & PR_O_TRANSP)
7782 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007783
Willy Tarreau1620ec32011-08-06 17:05:02 +02007784 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7785 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007786 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7787 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007788 err_code |= ERR_WARN;
7789 curproxy->options &= ~PR_O_DISABLE404;
7790 }
7791 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007792 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7793 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007794 err_code |= ERR_WARN;
7795 curproxy->options &= ~PR_O2_CHK_SNDST;
7796 }
Willy Tarreauef781042010-01-27 11:53:01 +01007797 }
7798
Simon Horman98637e52014-06-20 12:30:16 +09007799 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7800 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007801 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7802 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007803 cfgerr++;
7804 }
7805 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007806 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7807 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007808 cfgerr++;
7809 }
7810 }
7811
Simon Horman64e34162015-02-06 11:11:57 +09007812 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007813 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007814 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7815 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7816 "'email-alert myhostname', or 'email-alert to' "
7817 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7818 "to be present).\n",
7819 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007820 err_code |= ERR_WARN;
7821 free_email_alert(curproxy);
7822 }
7823 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007824 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007825 }
7826
Simon Horman98637e52014-06-20 12:30:16 +09007827 if (curproxy->check_command) {
7828 int clear = 0;
7829 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007830 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7831 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007832 err_code |= ERR_WARN;
7833 clear = 1;
7834 }
7835 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007836 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7837 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007838 cfgerr++;
7839 }
7840 if (clear) {
7841 free(curproxy->check_command);
7842 curproxy->check_command = NULL;
7843 }
7844 }
7845
7846 if (curproxy->check_path) {
7847 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007848 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7849 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007850 err_code |= ERR_WARN;
7851 free(curproxy->check_path);
7852 curproxy->check_path = NULL;
7853 }
7854 }
7855
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007856 /* if a default backend was specified, let's find it */
7857 if (curproxy->defbe.name) {
7858 struct proxy *target;
7859
Willy Tarreauafb39922015-05-26 12:04:09 +02007860 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007861 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007862 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7863 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007864 cfgerr++;
7865 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007866 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7867 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007868 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007869 } else if (target->mode != curproxy->mode &&
7870 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7871
Christopher Faulet767a84b2017-11-24 16:50:31 +01007872 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7873 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7874 curproxy->conf.file, curproxy->conf.line,
7875 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7876 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007877 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007878 } else {
7879 free(curproxy->defbe.name);
7880 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007881 /* Update tot_fe_maxconn for a further fullconn's computation */
7882 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007883 /* Emit a warning if this proxy also has some servers */
7884 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007885 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7886 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007887 err_code |= ERR_WARN;
7888 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007889 }
7890 }
7891
Emeric Brun3f783572017-01-12 11:21:28 +01007892 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7893 /* Case of listen without default backend
7894 * The curproxy will be its own default backend
7895 * so we update tot_fe_maxconn for a further
7896 * fullconn's computation */
7897 curproxy->tot_fe_maxconn += curproxy->maxconn;
7898 }
7899
Willy Tarreau55ea7572007-06-17 19:56:27 +02007900 /* find the target proxy for 'use_backend' rules */
7901 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007902 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007903 struct logformat_node *node;
7904 char *pxname;
7905
7906 /* Try to parse the string as a log format expression. If the result
7907 * of the parsing is only one entry containing a simple string, then
7908 * it's a standard string corresponding to a static rule, thus the
7909 * parsing is cancelled and be.name is restored to be resolved.
7910 */
7911 pxname = rule->be.name;
7912 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007913 curproxy->conf.args.ctx = ARGC_UBK;
7914 curproxy->conf.args.file = rule->file;
7915 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007916 err = NULL;
7917 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007918 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7919 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007920 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007921 cfgerr++;
7922 continue;
7923 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007924 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7925
7926 if (!LIST_ISEMPTY(&rule->be.expr)) {
7927 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7928 rule->dynamic = 1;
7929 free(pxname);
7930 continue;
7931 }
7932 /* simple string: free the expression and fall back to static rule */
7933 free(node->arg);
7934 free(node);
7935 }
7936
7937 rule->dynamic = 0;
7938 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007939
Willy Tarreauafb39922015-05-26 12:04:09 +02007940 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007941 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007942 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7943 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007944 cfgerr++;
7945 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007946 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7947 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007948 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007949 } else if (target->mode != curproxy->mode &&
7950 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7951
Christopher Faulet767a84b2017-11-24 16:50:31 +01007952 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7953 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7954 curproxy->conf.file, curproxy->conf.line,
7955 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7956 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007957 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007958 } else {
7959 free((void *)rule->be.name);
7960 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007961 /* For each target of switching rules, we update
7962 * their tot_fe_maxconn, except if a previous rule point
7963 * on the same backend or on the default backend */
7964 if (rule->be.backend != curproxy->defbe.be) {
7965 struct switching_rule *swrule;
7966
7967 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7968 if (rule == swrule) {
7969 target->tot_fe_maxconn += curproxy->maxconn;
7970 break;
7971 }
7972 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7973 /* there is multiple ref of this backend */
7974 break;
7975 }
7976 }
7977 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007978 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007979 }
7980
Willy Tarreau64ab6072014-09-16 12:17:36 +02007981 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007982 list_for_each_entry(srule, &curproxy->server_rules, list) {
7983 struct server *target = findserver(curproxy, srule->srv.name);
7984
7985 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007986 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7987 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007988 cfgerr++;
7989 continue;
7990 }
7991 free((void *)srule->srv.name);
7992 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007993 }
7994
Emeric Brunb982a3d2010-01-04 15:45:53 +01007995 /* find the target table for 'stick' rules */
7996 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7997 struct proxy *target;
7998
Emeric Brun1d33b292010-01-04 15:47:17 +01007999 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
8000 if (mrule->flags & STK_IS_STORE)
8001 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
8002
Emeric Brunb982a3d2010-01-04 15:45:53 +01008003 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008004 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008005 else
8006 target = curproxy;
8007
8008 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008009 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
8010 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008011 cfgerr++;
8012 }
8013 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008014 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
8015 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008016 cfgerr++;
8017 }
Willy Tarreau12785782012-04-27 21:37:17 +02008018 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008019 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
8020 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008021 cfgerr++;
8022 }
8023 else {
8024 free((void *)mrule->table.name);
8025 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02008026 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008027 }
8028 }
8029
8030 /* find the target table for 'store response' rules */
8031 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
8032 struct proxy *target;
8033
Emeric Brun1d33b292010-01-04 15:47:17 +01008034 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
8035
Emeric Brunb982a3d2010-01-04 15:45:53 +01008036 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008037 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008038 else
8039 target = curproxy;
8040
8041 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008042 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
8043 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008044 cfgerr++;
8045 }
8046 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008047 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
8048 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008049 cfgerr++;
8050 }
Willy Tarreau12785782012-04-27 21:37:17 +02008051 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008052 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
8053 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008054 cfgerr++;
8055 }
8056 else {
8057 free((void *)mrule->table.name);
8058 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02008059 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008060 }
8061 }
8062
Christopher Faulete4e830d2017-09-18 14:51:41 +02008063 /* check validity for 'tcp-request' layer 4 rules */
8064 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
8065 err = NULL;
8066 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008067 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008068 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01008069 cfgerr++;
8070 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02008071 }
8072
Christopher Faulete4e830d2017-09-18 14:51:41 +02008073 /* check validity for 'tcp-request' layer 5 rules */
8074 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
8075 err = NULL;
8076 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008077 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008078 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008079 cfgerr++;
8080 }
8081 }
8082
Christopher Faulete4e830d2017-09-18 14:51:41 +02008083 /* check validity for 'tcp-request' layer 6 rules */
8084 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8085 err = NULL;
8086 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008087 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008088 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008089 cfgerr++;
8090 }
8091 }
8092
Christopher Faulete4e830d2017-09-18 14:51:41 +02008093 /* check validity for 'http-request' layer 7 rules */
8094 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
8095 err = NULL;
8096 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008097 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008098 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008099 cfgerr++;
8100 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008101 }
8102
Christopher Faulete4e830d2017-09-18 14:51:41 +02008103 /* check validity for 'http-response' layer 7 rules */
8104 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
8105 err = NULL;
8106 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008107 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008108 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02008109 cfgerr++;
8110 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008111 }
8112
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008113 /* move any "block" rules at the beginning of the http-request rules */
8114 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8115 /* insert block_rules into http_req_rules at the beginning */
8116 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8117 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8118 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8119 curproxy->http_req_rules.n = curproxy->block_rules.n;
8120 LIST_INIT(&curproxy->block_rules);
8121 }
8122
Emeric Brun32da3c42010-09-23 18:39:19 +02008123 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008124 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008125
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008126 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008127 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8128 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008129 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008130 break;
8131 }
8132 }
8133
8134 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008135 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8136 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008137 free((void *)curproxy->table.peers.name);
8138 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008139 cfgerr++;
8140 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008141 else if (curpeers->state == PR_STSTOPPED) {
8142 /* silently disable this peers section */
8143 curproxy->table.peers.p = NULL;
8144 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008145 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008146 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8147 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008148 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008149 cfgerr++;
8150 }
8151 }
8152
Simon Horman9dc49962015-01-30 11:22:59 +09008153
8154 if (curproxy->email_alert.mailers.name) {
8155 struct mailers *curmailers = mailers;
8156
8157 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008158 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008159 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008160 }
Simon Horman9dc49962015-01-30 11:22:59 +09008161 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008162 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8163 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008164 free_email_alert(curproxy);
8165 cfgerr++;
8166 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008167 else {
8168 err = NULL;
8169 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008170 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008171 free(err);
8172 cfgerr++;
8173 }
8174 }
Simon Horman9dc49962015-01-30 11:22:59 +09008175 }
8176
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008177 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008178 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008179 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008180 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8181 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008182 cfgerr++;
8183 goto out_uri_auth_compat;
8184 }
8185
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008186 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008187 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008188 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008189 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008190
Willy Tarreau95fa4692010-02-01 13:05:50 +01008191 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8192 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008193
8194 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008195 uri_auth_compat_req[i++] = "realm";
8196 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8197 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008198
Willy Tarreau95fa4692010-02-01 13:05:50 +01008199 uri_auth_compat_req[i++] = "unless";
8200 uri_auth_compat_req[i++] = "{";
8201 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8202 uri_auth_compat_req[i++] = "}";
8203 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008204
Willy Tarreauff011f22011-01-06 17:51:27 +01008205 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8206 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008207 cfgerr++;
8208 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008209 }
8210
Willy Tarreauff011f22011-01-06 17:51:27 +01008211 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008212
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008213 if (curproxy->uri_auth->auth_realm) {
8214 free(curproxy->uri_auth->auth_realm);
8215 curproxy->uri_auth->auth_realm = NULL;
8216 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008217
8218 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008219 }
8220out_uri_auth_compat:
8221
Dragan Dosen43885c72015-10-01 13:18:13 +02008222 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008223 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008224 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8225 if (!curproxy->conf.logformat_sd_string) {
8226 /* set the default logformat_sd_string */
8227 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8228 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008229 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008230 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008231 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008232
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008233 /* compile the log format */
8234 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008235 if (curproxy->conf.logformat_string != default_http_log_format &&
8236 curproxy->conf.logformat_string != default_tcp_log_format &&
8237 curproxy->conf.logformat_string != clf_http_log_format)
8238 free(curproxy->conf.logformat_string);
8239 curproxy->conf.logformat_string = NULL;
8240 free(curproxy->conf.lfs_file);
8241 curproxy->conf.lfs_file = NULL;
8242 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008243
8244 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8245 free(curproxy->conf.logformat_sd_string);
8246 curproxy->conf.logformat_sd_string = NULL;
8247 free(curproxy->conf.lfsd_file);
8248 curproxy->conf.lfsd_file = NULL;
8249 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008250 }
8251
Willy Tarreau62a61232013-04-12 18:13:46 +02008252 if (curproxy->conf.logformat_string) {
8253 curproxy->conf.args.ctx = ARGC_LOG;
8254 curproxy->conf.args.file = curproxy->conf.lfs_file;
8255 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008256 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008257 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008258 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008259 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8260 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008261 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008262 cfgerr++;
8263 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008264 curproxy->conf.args.file = NULL;
8265 curproxy->conf.args.line = 0;
8266 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008267
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008268 if (curproxy->conf.logformat_sd_string) {
8269 curproxy->conf.args.ctx = ARGC_LOGSD;
8270 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8271 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008272 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008273 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 +01008274 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008275 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8276 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008277 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008278 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008279 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008280 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8281 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008282 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008283 cfgerr++;
8284 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008285 curproxy->conf.args.file = NULL;
8286 curproxy->conf.args.line = 0;
8287 }
8288
Willy Tarreau62a61232013-04-12 18:13:46 +02008289 if (curproxy->conf.uniqueid_format_string) {
8290 curproxy->conf.args.ctx = ARGC_UIF;
8291 curproxy->conf.args.file = curproxy->conf.uif_file;
8292 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008293 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008294 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 +01008295 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008296 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8297 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008298 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008299 cfgerr++;
8300 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008301 curproxy->conf.args.file = NULL;
8302 curproxy->conf.args.line = 0;
8303 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008304
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008305 /* only now we can check if some args remain unresolved.
8306 * This must be done after the users and groups resolution.
8307 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008308 cfgerr += smp_resolve_args(curproxy);
8309 if (!cfgerr)
8310 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008311
Willy Tarreau2738a142006-07-08 17:28:09 +02008312 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008313 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008314 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008315 (!curproxy->timeout.connect ||
8316 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008317 ha_warning("config : missing timeouts for %s '%s'.\n"
8318 " | While not properly invalid, you will certainly encounter various problems\n"
8319 " | with such a configuration. To fix this, please ensure that all following\n"
8320 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8321 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008322 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008323 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008324
Willy Tarreau1fa31262007-12-03 00:36:16 +01008325 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8326 * We must still support older configurations, so let's find out whether those
8327 * parameters have been set or must be copied from contimeouts.
8328 */
8329 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008330 if (!curproxy->timeout.tarpit ||
8331 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008332 /* tarpit timeout not set. We search in the following order:
8333 * default.tarpit, curr.connect, default.connect.
8334 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008335 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008336 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008337 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008338 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008339 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008340 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008341 }
8342 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008343 (!curproxy->timeout.queue ||
8344 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008345 /* queue timeout not set. We search in the following order:
8346 * default.queue, curr.connect, default.connect.
8347 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008348 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008349 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008350 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008351 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008352 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008353 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008354 }
8355 }
8356
Willy Tarreau1620ec32011-08-06 17:05:02 +02008357 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008358 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008359 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008360 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008361 }
8362
Willy Tarreau215663d2014-06-13 18:30:23 +02008363 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8364 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008365 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8366 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008367 err_code |= ERR_WARN;
8368 }
8369
Willy Tarreau193b8c62012-11-22 00:17:38 +01008370 /* ensure that cookie capture length is not too large */
8371 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008372 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8373 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008374 err_code |= ERR_WARN;
8375 curproxy->capture_len = global.tune.cookie_len - 1;
8376 }
8377
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008378 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008379 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008380 curproxy->req_cap_pool = create_pool("ptrcap",
8381 curproxy->nb_req_cap * sizeof(char *),
8382 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008383 }
8384
8385 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008386 curproxy->rsp_cap_pool = create_pool("ptrcap",
8387 curproxy->nb_rsp_cap * sizeof(char *),
8388 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008389 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008390
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008391 switch (curproxy->load_server_state_from_file) {
8392 case PR_SRV_STATE_FILE_UNSPEC:
8393 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8394 break;
8395 case PR_SRV_STATE_FILE_GLOBAL:
8396 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008397 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",
8398 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008399 err_code |= ERR_WARN;
8400 }
8401 break;
8402 }
8403
Willy Tarreaubaaee002006-06-26 02:48:02 +02008404 /* first, we will invert the servers list order */
8405 newsrv = NULL;
8406 while (curproxy->srv) {
8407 struct server *next;
8408
8409 next = curproxy->srv->next;
8410 curproxy->srv->next = newsrv;
8411 newsrv = curproxy->srv;
8412 if (!next)
8413 break;
8414 curproxy->srv = next;
8415 }
8416
Willy Tarreau17edc812014-01-03 12:14:34 +01008417 /* Check that no server name conflicts. This causes trouble in the stats.
8418 * We only emit a warning for the first conflict affecting each server,
8419 * in order to avoid combinatory explosion if all servers have the same
8420 * name. We do that only for servers which do not have an explicit ID,
8421 * because these IDs were made also for distinguishing them and we don't
8422 * want to annoy people who correctly manage them.
8423 */
8424 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8425 struct server *other_srv;
8426
8427 if (newsrv->puid)
8428 continue;
8429
8430 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8431 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008432 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",
8433 newsrv->conf.file, newsrv->conf.line,
8434 proxy_type_str(curproxy), curproxy->id,
8435 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008436 break;
8437 }
8438 }
8439 }
8440
Willy Tarreaudd701652010-05-25 23:03:02 +02008441 /* assign automatic UIDs to servers which don't have one yet */
8442 next_id = 1;
8443 newsrv = curproxy->srv;
8444 while (newsrv != NULL) {
8445 if (!newsrv->puid) {
8446 /* server ID not set, use automatic numbering with first
8447 * spare entry starting with next_svid.
8448 */
8449 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8450 newsrv->conf.id.key = newsrv->puid = next_id;
8451 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8452 }
8453 next_id++;
8454 newsrv = newsrv->next;
8455 }
8456
Willy Tarreau20697042007-11-15 23:26:18 +01008457 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008458 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008459
Willy Tarreau62c3be22012-01-20 13:12:32 +01008460 /*
8461 * If this server supports a maxconn parameter, it needs a dedicated
8462 * tasks to fill the emptied slots when a connection leaves.
8463 * Also, resolve deferred tracking dependency if needed.
8464 */
8465 newsrv = curproxy->srv;
8466 while (newsrv != NULL) {
8467 if (newsrv->minconn > newsrv->maxconn) {
8468 /* Only 'minconn' was specified, or it was higher than or equal
8469 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8470 * this will avoid further useless expensive computations.
8471 */
8472 newsrv->maxconn = newsrv->minconn;
8473 } else if (newsrv->maxconn && !newsrv->minconn) {
8474 /* minconn was not specified, so we set it to maxconn */
8475 newsrv->minconn = newsrv->maxconn;
8476 }
8477
Willy Tarreau17d45382016-12-22 21:16:08 +01008478 /* this will also properly set the transport layer for prod and checks */
8479 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8480 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8481 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8482 }
Emeric Brun94324a42012-10-11 14:00:19 +02008483
Willy Tarreau2f075e92013-12-03 11:11:34 +01008484 /* set the check type on the server */
8485 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8486
Willy Tarreau62c3be22012-01-20 13:12:32 +01008487 if (newsrv->trackit) {
8488 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008489 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008490 char *pname, *sname;
8491
8492 pname = newsrv->trackit;
8493 sname = strrchr(pname, '/');
8494
8495 if (sname)
8496 *sname++ = '\0';
8497 else {
8498 sname = pname;
8499 pname = NULL;
8500 }
8501
8502 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008503 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008504 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008505 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8506 proxy_type_str(curproxy), curproxy->id,
8507 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008508 cfgerr++;
8509 goto next_srv;
8510 }
8511 } else
8512 px = curproxy;
8513
8514 srv = findserver(px, sname);
8515 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008516 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8517 proxy_type_str(curproxy), curproxy->id,
8518 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008519 cfgerr++;
8520 goto next_srv;
8521 }
8522
Willy Tarreau32091232014-05-16 13:52:00 +02008523 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8524 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8525 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008526 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8527 "tracking as it does not have any check nor agent enabled.\n",
8528 proxy_type_str(curproxy), curproxy->id,
8529 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008530 cfgerr++;
8531 goto next_srv;
8532 }
8533
8534 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8535
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008536 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008537 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8538 "belongs to a tracking chain looping back to %s/%s.\n",
8539 proxy_type_str(curproxy), curproxy->id,
8540 newsrv->id, px->id, srv->id, px->id,
8541 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008542 cfgerr++;
8543 goto next_srv;
8544 }
8545
8546 if (curproxy != px &&
8547 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008548 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8549 "tracking: disable-on-404 option inconsistency.\n",
8550 proxy_type_str(curproxy), curproxy->id,
8551 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008552 cfgerr++;
8553 goto next_srv;
8554 }
8555
Willy Tarreau62c3be22012-01-20 13:12:32 +01008556 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008557 newsrv->tracknext = srv->trackers;
8558 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008559
8560 free(newsrv->trackit);
8561 newsrv->trackit = NULL;
8562 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008563
Willy Tarreau62c3be22012-01-20 13:12:32 +01008564 next_srv:
8565 newsrv = newsrv->next;
8566 }
8567
Olivier Houchard4e694042017-03-14 20:01:29 +01008568 /*
8569 * Try to generate dynamic cookies for servers now.
8570 * It couldn't be done earlier, since at the time we parsed
8571 * the server line, we may not have known yet that we
8572 * should use dynamic cookies, or the secret key may not
8573 * have been provided yet.
8574 */
8575 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8576 newsrv = curproxy->srv;
8577 while (newsrv != NULL) {
8578 srv_set_dyncookie(newsrv);
8579 newsrv = newsrv->next;
8580 }
8581
8582 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008583 /* We have to initialize the server lookup mechanism depending
8584 * on what LB algorithm was choosen.
8585 */
8586
8587 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8588 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8589 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008590 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8591 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8592 init_server_map(curproxy);
8593 } else {
8594 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8595 fwrr_init_server_groups(curproxy);
8596 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008597 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008598
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008599 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008600 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8601 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8602 fwlc_init_server_tree(curproxy);
8603 } else {
8604 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8605 fas_init_server_tree(curproxy);
8606 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008607 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008608
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008609 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008610 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8611 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8612 chash_init_server_tree(curproxy);
8613 } else {
8614 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8615 init_server_map(curproxy);
8616 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008617 break;
8618 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008619 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008620
8621 if (curproxy->options & PR_O_LOGASAP)
8622 curproxy->to_log &= ~LW_BYTES;
8623
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008624 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008625 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8626 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008627 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8628 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008629 err_code |= ERR_WARN;
8630 }
8631
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008632 if (curproxy->mode != PR_MODE_HTTP) {
8633 int optnum;
8634
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008635 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008636 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8637 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008638 err_code |= ERR_WARN;
8639 curproxy->uri_auth = NULL;
8640 }
8641
Willy Tarreaude7dc882017-03-10 11:49:21 +01008642 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008643 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8644 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008645 err_code |= ERR_WARN;
8646 }
8647
8648 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008649 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8650 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008651 err_code |= ERR_WARN;
8652 }
8653
8654 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008655 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8656 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008657 err_code |= ERR_WARN;
8658 }
8659
8660 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008661 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8662 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008663 err_code |= ERR_WARN;
8664 }
8665
8666 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008667 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8668 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008669 err_code |= ERR_WARN;
8670 }
8671
Willy Tarreau87cf5142011-08-19 22:57:24 +02008672 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008673 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8674 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008675 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008676 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008677 }
8678
8679 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008680 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8681 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008682 err_code |= ERR_WARN;
8683 curproxy->options &= ~PR_O_ORGTO;
8684 }
8685
8686 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8687 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8688 (curproxy->cap & cfg_opts[optnum].cap) &&
8689 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008690 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8691 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008692 err_code |= ERR_WARN;
8693 curproxy->options &= ~cfg_opts[optnum].val;
8694 }
8695 }
8696
8697 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8698 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8699 (curproxy->cap & cfg_opts2[optnum].cap) &&
8700 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008701 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8702 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008703 err_code |= ERR_WARN;
8704 curproxy->options2 &= ~cfg_opts2[optnum].val;
8705 }
8706 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008707
Willy Tarreau29fbe512015-08-20 19:35:14 +02008708#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008709 if (curproxy->conn_src.bind_hdr_occ) {
8710 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008711 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8712 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008713 err_code |= ERR_WARN;
8714 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008715#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008716 }
8717
Willy Tarreaubaaee002006-06-26 02:48:02 +02008718 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008719 * ensure that we're not cross-dressing a TCP server into HTTP.
8720 */
8721 newsrv = curproxy->srv;
8722 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008723 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008724 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8725 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008726 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008727 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008728
Willy Tarreau0cec3312011-10-31 13:49:26 +01008729 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008730 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8731 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008732 err_code |= ERR_WARN;
8733 }
8734
Willy Tarreauc93cd162014-05-13 15:54:22 +02008735 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008736 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8737 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008738 err_code |= ERR_WARN;
8739 }
8740
Willy Tarreau29fbe512015-08-20 19:35:14 +02008741#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008742 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8743 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008744 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8745 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008746 err_code |= ERR_WARN;
8747 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008748#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008749
8750 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8751 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8752 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8753 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8754 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008755 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",
8756 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008757 err_code |= ERR_WARN;
8758 }
8759
8760
8761 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008762 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",
8763 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008764 err_code |= ERR_WARN;
8765 }
8766 }
8767
Willy Tarreau21d2af32008-02-14 20:25:24 +01008768 newsrv = newsrv->next;
8769 }
8770
Willy Tarreaue42bd962014-09-16 16:21:19 +02008771 /* check if we have a frontend with "tcp-request content" looking at L7
8772 * with no inspect-delay
8773 */
8774 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008775 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8776 if (arule->action == ACT_TCP_CAPTURE &&
8777 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008778 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008779 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8780 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008781 break;
8782 }
8783
Christopher Faulete4e830d2017-09-18 14:51:41 +02008784 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008785 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8786 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8787 " This means that these rules will randomly find their contents. This can be fixed by"
8788 " setting the tcp-request inspect-delay.\n",
8789 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008790 err_code |= ERR_WARN;
8791 }
8792 }
8793
Christopher Fauletd7c91962015-04-30 11:48:27 +02008794 /* Check filter configuration, if any */
8795 cfgerr += flt_check(curproxy);
8796
Willy Tarreauc1a21672009-08-16 22:37:44 +02008797 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008798 if (!curproxy->accept)
8799 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008800
Willy Tarreauc1a21672009-08-16 22:37:44 +02008801 if (curproxy->tcp_req.inspect_delay ||
8802 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008803 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008804
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008805 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008806 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008807 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008808 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008809
8810 /* both TCP and HTTP must check switching rules */
8811 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008812
8813 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008814 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008815 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8816 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 +01008817 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008818 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8819 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008820 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008821 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008822 }
8823
8824 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008825 if (curproxy->tcp_req.inspect_delay ||
8826 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8827 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8828
Emeric Brun97679e72010-09-23 17:56:44 +02008829 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8830 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8831
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008832 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008833 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008834 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008835 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008836
8837 /* If the backend does requires RDP cookie persistence, we have to
8838 * enable the corresponding analyser.
8839 */
8840 if (curproxy->options2 & PR_O2_RDPC_PRST)
8841 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008842
8843 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008844 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008845 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8846 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 +01008847 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008848 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8849 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008850 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008851 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008852 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008853 }
8854
8855 /***********************************************************/
8856 /* At this point, target names have already been resolved. */
8857 /***********************************************************/
8858
8859 /* Check multi-process mode compatibility */
8860
8861 if (global.nbproc > 1 && global.stats_fe) {
8862 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8863 unsigned long mask;
8864
8865 mask = nbits(global.nbproc);
8866 if (global.stats_fe->bind_proc)
8867 mask &= global.stats_fe->bind_proc;
8868
8869 if (bind_conf->bind_proc)
8870 mask &= bind_conf->bind_proc;
8871
8872 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008873 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008874 break;
8875 }
8876 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008877 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 +02008878 }
8879 }
8880
8881 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008882 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008883 if (curproxy->bind_proc)
8884 continue;
8885
8886 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8887 unsigned long mask;
8888
Willy Tarreaue428b082015-05-04 21:57:58 +02008889 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008890 curproxy->bind_proc |= mask;
8891 }
8892
8893 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008894 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008895 }
8896
8897 if (global.stats_fe) {
8898 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8899 unsigned long mask;
8900
Cyril Bonté06181952016-02-24 00:14:54 +01008901 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008902 global.stats_fe->bind_proc |= mask;
8903 }
8904 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008905 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008906 }
8907
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008908 /* propagate bindings from frontends to backends. Don't do it if there
8909 * are any fatal errors as we must not call it with unresolved proxies.
8910 */
8911 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008912 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008913 if (curproxy->cap & PR_CAP_FE)
8914 propagate_processes(curproxy, NULL);
8915 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008916 }
8917
8918 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008919 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008920 if (curproxy->bind_proc)
8921 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008922 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008923 }
8924
8925 /*******************************************************/
8926 /* At this step, all proxies have a non-null bind_proc */
8927 /*******************************************************/
8928
8929 /* perform the final checks before creating tasks */
8930
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008931 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008932 struct listener *listener;
8933 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008934
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008935 /* Configure SSL for each bind line.
8936 * Note: if configuration fails at some point, the ->ctx member
8937 * remains NULL so that listeners can later detach.
8938 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008939 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008940 if (bind_conf->xprt->prepare_bind_conf &&
8941 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008942 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008943 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008944
Willy Tarreaue6b98942007-10-29 01:09:36 +01008945 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008946 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008947 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008948 int nbproc;
8949
8950 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008951 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008952 nbits(global.nbproc));
8953
8954 if (!nbproc) /* no intersection between listener and frontend */
8955 nbproc = 1;
8956
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008957 if (!listener->luid) {
8958 /* listener ID not set, use automatic numbering with first
8959 * spare entry starting with next_luid.
8960 */
8961 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8962 listener->conf.id.key = listener->luid = next_id;
8963 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008964 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008965 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008966
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008967 /* enable separate counters */
8968 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008969 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008970 if (!listener->name)
8971 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008972 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008973
Willy Tarreaue6b98942007-10-29 01:09:36 +01008974 if (curproxy->options & PR_O_TCP_NOLING)
8975 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008976 if (!listener->maxconn)
8977 listener->maxconn = curproxy->maxconn;
8978 if (!listener->backlog)
8979 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008980 if (!listener->maxaccept)
8981 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8982
8983 /* we want to have an optimal behaviour on single process mode to
8984 * maximize the work at once, but in multi-process we want to keep
8985 * some fairness between processes, so we target half of the max
8986 * number of events to be balanced over all the processes the proxy
8987 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8988 * used to disable the limit.
8989 */
8990 if (listener->maxaccept > 0) {
8991 if (nbproc > 1)
8992 listener->maxaccept = (listener->maxaccept + 1) / 2;
8993 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8994 }
8995
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008996 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008997 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008998 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008999
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02009000 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02009001 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02009002
Willy Tarreau620408f2016-10-21 16:37:51 +02009003 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
9004 listener->options |= LI_O_TCP_L5_RULES;
9005
Willy Tarreaude3041d2010-05-31 10:56:17 +02009006 if (curproxy->mon_mask.s_addr)
9007 listener->options |= LI_O_CHK_MONNET;
9008
Willy Tarreau9ea05a72009-06-14 12:07:01 +02009009 /* smart accept mode is automatic in HTTP mode */
9010 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02009011 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02009012 !(curproxy->no_options2 & PR_O2_SMARTACC)))
9013 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01009014 }
9015
Willy Tarreau2a65ff02012-09-13 17:54:29 +02009016 /* Release unused SSL configs */
9017 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01009018 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
9019 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02009020 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02009021
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02009022 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02009023 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02009024 int count, maxproc = 0;
9025
9026 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00009027 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02009028 if (count > maxproc)
9029 maxproc = count;
9030 }
9031 /* backends have 0, frontends have 1 or more */
9032 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01009033 ha_warning("Proxy '%s': in multi-process mode, stats will be"
9034 " limited to process assigned to the current request.\n",
9035 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02009036
Willy Tarreau102df612014-05-07 23:56:38 +02009037 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009038 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
9039 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009040 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009041 }
Willy Tarreau102df612014-05-07 23:56:38 +02009042 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009043 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
9044 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009045 }
9046 }
Willy Tarreau918ff602011-07-25 16:33:49 +02009047
9048 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02009049 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02009050 if (curproxy->task) {
9051 curproxy->task->context = curproxy;
9052 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02009053 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009054 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
9055 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02009056 cfgerr++;
9057 }
Willy Tarreaub369a042014-09-16 13:21:03 +02009058 }
9059
Willy Tarreaufbb78422011-06-05 15:38:35 +02009060 /* automatically compute fullconn if not set. We must not do it in the
9061 * loop above because cross-references are not yet fully resolved.
9062 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009063 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009064 /* If <fullconn> is not set, let's set it to 10% of the sum of
9065 * the possible incoming frontend's maxconns.
9066 */
9067 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009068 /* we have the sum of the maxconns in <total>. We only
9069 * keep 10% of that sum to set the default fullconn, with
9070 * a hard minimum of 1 (to avoid a divide by zero).
9071 */
Emeric Brun3f783572017-01-12 11:21:28 +01009072 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02009073 if (!curproxy->fullconn)
9074 curproxy->fullconn = 1;
9075 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01009076 }
9077
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009078 /*
9079 * Recount currently required checks.
9080 */
9081
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009082 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009083 int optnum;
9084
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009085 for (optnum = 0; cfg_opts[optnum].name; optnum++)
9086 if (curproxy->options & cfg_opts[optnum].val)
9087 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009088
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009089 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
9090 if (curproxy->options2 & cfg_opts2[optnum].val)
9091 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009092 }
9093
Willy Tarreau0fca4832015-05-01 19:12:05 +02009094 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009095 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02009096 if (curproxy->table.peers.p)
9097 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
9098
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009099 if (cfg_peers) {
9100 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02009101 struct peer *p, *pb;
9102
Willy Tarreau1e273012015-05-01 19:15:17 +02009103 /* Remove all peers sections which don't have a valid listener,
9104 * which are not used by any table, or which are bound to more
9105 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009106 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009107 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009108 while (*last) {
9109 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009110
9111 if (curpeers->state == PR_STSTOPPED) {
9112 /* the "disabled" keyword was present */
9113 if (curpeers->peers_fe)
9114 stop_proxy(curpeers->peers_fe);
9115 curpeers->peers_fe = NULL;
9116 }
9117 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009118 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9119 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009120 }
David Carliere6c39412015-07-02 07:00:17 +00009121 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009122 /* either it's totally stopped or too much used */
9123 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009124 ha_alert("Peers section '%s': peers referenced by sections "
9125 "running in different processes (%d different ones). "
9126 "Check global.nbproc and all tables' bind-process "
9127 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009128 cfgerr++;
9129 }
9130 stop_proxy(curpeers->peers_fe);
9131 curpeers->peers_fe = NULL;
9132 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009133 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009134 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009135 last = &curpeers->next;
9136 continue;
9137 }
9138
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009139 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009140 p = curpeers->remote;
9141 while (p) {
9142 pb = p->next;
9143 free(p->id);
9144 free(p);
9145 p = pb;
9146 }
9147
9148 /* Destroy and unlink this curpeers section.
9149 * Note: curpeers is backed up into *last.
9150 */
9151 free(curpeers->id);
9152 curpeers = curpeers->next;
9153 free(*last);
9154 *last = curpeers;
9155 }
9156 }
9157
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009158 /* initialize stick-tables on backend capable proxies. This must not
9159 * be done earlier because the data size may be discovered while parsing
9160 * other proxies.
9161 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009162 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009163 if (curproxy->state == PR_STSTOPPED)
9164 continue;
9165
9166 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009167 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009168 cfgerr++;
9169 }
9170 }
9171
Simon Horman0d16a402015-01-30 11:22:58 +09009172 if (mailers) {
9173 struct mailers *curmailers = mailers, **last;
9174 struct mailer *m, *mb;
9175
9176 /* Remove all mailers sections which don't have a valid listener.
9177 * This can happen when a mailers section is never referenced.
9178 */
9179 last = &mailers;
9180 while (*last) {
9181 curmailers = *last;
9182 if (curmailers->users) {
9183 last = &curmailers->next;
9184 continue;
9185 }
9186
Christopher Faulet767a84b2017-11-24 16:50:31 +01009187 ha_warning("Removing incomplete section 'mailers %s'.\n",
9188 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009189
9190 m = curmailers->mailer_list;
9191 while (m) {
9192 mb = m->next;
9193 free(m->id);
9194 free(m);
9195 m = mb;
9196 }
9197
9198 /* Destroy and unlink this curmailers section.
9199 * Note: curmailers is backed up into *last.
9200 */
9201 free(curmailers->id);
9202 curmailers = curmailers->next;
9203 free(*last);
9204 *last = curmailers;
9205 }
9206 }
9207
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009208 /* Update server_state_file_name to backend name if backend is supposed to use
9209 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009210 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009211 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9212 curproxy->server_state_file_name == NULL)
9213 curproxy->server_state_file_name = strdup(curproxy->id);
9214 }
9215
Willy Tarreaubafbe012017-11-24 17:34:44 +01009216 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009217 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009218 MEM_F_SHARED);
9219
William Lallemand48b4bb42017-10-23 14:36:34 +02009220 list_for_each_entry(postparser, &postparsers, list) {
9221 if (postparser->func)
9222 cfgerr += postparser->func();
9223 }
9224
Willy Tarreaubb925012009-07-23 13:36:36 +02009225 if (cfgerr > 0)
9226 err_code |= ERR_ALERT | ERR_FATAL;
9227 out:
9228 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009229}
9230
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009231/*
9232 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9233 * parsing sessions.
9234 */
9235void cfg_register_keywords(struct cfg_kw_list *kwl)
9236{
9237 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9238}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009239
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009240/*
9241 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9242 */
9243void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9244{
9245 LIST_DEL(&kwl->list);
9246 LIST_INIT(&kwl->list);
9247}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009248
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009249/* this function register new section in the haproxy configuration file.
9250 * <section_name> is the name of this new section and <section_parser>
9251 * is the called parser. If two section declaration have the same name,
9252 * only the first declared is used.
9253 */
9254int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009255 int (*section_parser)(const char *, int, char **, int),
9256 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009257{
9258 struct cfg_section *cs;
9259
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009260 list_for_each_entry(cs, &sections, list) {
9261 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009262 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009263 return 0;
9264 }
9265 }
9266
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009267 cs = calloc(1, sizeof(*cs));
9268 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009269 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009270 return 0;
9271 }
9272
9273 cs->section_name = section_name;
9274 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009275 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009276
9277 LIST_ADDQ(&sections, &cs->list);
9278
9279 return 1;
9280}
9281
William Lallemand48b4bb42017-10-23 14:36:34 +02009282/* this function register a new function which will be called once the haproxy
9283 * configuration file has been parsed. It's useful to check dependencies
9284 * between sections or to resolve items once everything is parsed.
9285 */
9286int cfg_register_postparser(char *name, int (*func)())
9287{
9288 struct cfg_postparser *cp;
9289
9290 cp = calloc(1, sizeof(*cp));
9291 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009292 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009293 return 0;
9294 }
9295 cp->name = name;
9296 cp->func = func;
9297
9298 LIST_ADDQ(&postparsers, &cp->list);
9299
9300 return 1;
9301}
9302
Willy Tarreaubaaee002006-06-26 02:48:02 +02009303/*
David Carlier845efb52015-09-25 11:49:18 +01009304 * free all config section entries
9305 */
9306void cfg_unregister_sections(void)
9307{
9308 struct cfg_section *cs, *ics;
9309
9310 list_for_each_entry_safe(cs, ics, &sections, list) {
9311 LIST_DEL(&cs->list);
9312 free(cs);
9313 }
9314}
9315
Christopher Faulet7110b402016-10-26 11:09:44 +02009316void cfg_backup_sections(struct list *backup_sections)
9317{
9318 struct cfg_section *cs, *ics;
9319
9320 list_for_each_entry_safe(cs, ics, &sections, list) {
9321 LIST_DEL(&cs->list);
9322 LIST_ADDQ(backup_sections, &cs->list);
9323 }
9324}
9325
9326void cfg_restore_sections(struct list *backup_sections)
9327{
9328 struct cfg_section *cs, *ics;
9329
9330 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9331 LIST_DEL(&cs->list);
9332 LIST_ADDQ(&sections, &cs->list);
9333 }
9334}
9335
Willy Tarreau659fbf02016-05-26 17:55:28 +02009336__attribute__((constructor))
9337static void cfgparse_init(void)
9338{
9339 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009340 cfg_register_section("listen", cfg_parse_listen, NULL);
9341 cfg_register_section("frontend", cfg_parse_listen, NULL);
9342 cfg_register_section("backend", cfg_parse_listen, NULL);
9343 cfg_register_section("defaults", cfg_parse_listen, NULL);
9344 cfg_register_section("global", cfg_parse_global, NULL);
9345 cfg_register_section("userlist", cfg_parse_users, NULL);
9346 cfg_register_section("peers", cfg_parse_peers, NULL);
9347 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9348 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9349 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009350}
9351
David Carlier845efb52015-09-25 11:49:18 +01009352/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009353 * Local variables:
9354 * c-indent-level: 8
9355 * c-basic-offset: 8
9356 * End:
9357 */