blob: baf9e60f749b7da783afdb60fc5a8136287b0a1c [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
665 end:
Christopher Faulet5ab51772017-11-22 11:21:58 +0100666 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200667}
668
David Carlier7e351ee2017-12-01 09:14:02 +0000669#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200670/* Parse cpu sets. Each CPU set is either a unique number between 0 and
671 * <LONGBITS> or a range with two such numbers delimited by a dash
672 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
673 * returns 0. otherwise it returns 1 with an error message in <err>.
674 */
675static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
676{
677 int cur_arg = 0;
678
679 *cpu_set = 0;
680 while (*args[cur_arg]) {
681 char *dash;
682 unsigned int low, high;
683
684 if (!isdigit((int)*args[cur_arg])) {
685 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
686 return -1;
687 }
688
689 low = high = str2uic(args[cur_arg]);
690 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100691 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200692
693 if (high < low) {
694 unsigned int swap = low;
695 low = high;
696 high = swap;
697 }
698
699 if (high >= LONGBITS) {
700 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
701 return 1;
702 }
703
704 while (low <= high)
705 *cpu_set |= 1UL << low++;
706
707 cur_arg++;
708 }
709 return 0;
710}
David Carlier7e351ee2017-12-01 09:14:02 +0000711#endif
712
Willy Tarreaubaaee002006-06-26 02:48:02 +0200713/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200714 * parse a line in a <global> section. Returns the error code, 0 if OK, or
715 * any combination of :
716 * - ERR_ABORT: must abort ASAP
717 * - ERR_FATAL: we can continue parsing but not start the service
718 * - ERR_WARN: a warning has been emitted
719 * - ERR_ALERT: an alert has been emitted
720 * Only the two first ones can stop processing, the two others are just
721 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200722 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200723int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200724{
Willy Tarreau058e9072009-07-20 09:30:05 +0200725 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200726 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200727
728 if (!strcmp(args[0], "global")) { /* new section */
729 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200730 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200731 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200732 }
733 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200734 if (alertif_too_many_args(0, file, linenum, args, &err_code))
735 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200736 global.mode |= MODE_DAEMON;
737 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200738 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200739 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200740 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200741 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100742 if (!strcmp(args[1], "no-exit-on-failure")) {
743 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200744 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100745 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
William Lallemand69f9b3b2017-06-01 17:38:54 +0200746 err_code |= ERR_ALERT | ERR_FATAL;
747 goto out;
748 }
749 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200750 global.mode |= MODE_MWORKER;
751 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200752 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200753 if (alertif_too_many_args(0, file, linenum, args, &err_code))
754 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200755 global.mode |= MODE_DEBUG;
756 }
757 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200758 if (alertif_too_many_args(0, file, linenum, args, &err_code))
759 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100760 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200761 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200762 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200763 if (alertif_too_many_args(0, file, linenum, args, &err_code))
764 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100765 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200766 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200767 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200768 if (alertif_too_many_args(0, file, linenum, args, &err_code))
769 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100770 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200771 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100772 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200773 if (alertif_too_many_args(0, file, linenum, args, &err_code))
774 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100775 global.tune.options &= ~GTUNE_USE_SPLICE;
776 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200777 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200778 if (alertif_too_many_args(0, file, linenum, args, &err_code))
779 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200780 global.tune.options &= ~GTUNE_USE_GAI;
781 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000782 else if (!strcmp(args[0], "noreuseport")) {
783 if (alertif_too_many_args(0, file, linenum, args, &err_code))
784 goto out;
785 global.tune.options &= ~GTUNE_USE_REUSEPORT;
786 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200787 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200788 if (alertif_too_many_args(0, file, linenum, args, &err_code))
789 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200790 global.mode |= MODE_QUIET;
791 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200792 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200793 if (alertif_too_many_args(1, file, linenum, args, &err_code))
794 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200795 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100796 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200797 err_code |= ERR_ALERT;
798 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200799 }
800 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100801 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200802 err_code |= ERR_ALERT | ERR_FATAL;
803 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200804 }
805 global.tune.maxpollevents = atol(args[1]);
806 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100807 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200808 if (alertif_too_many_args(1, file, linenum, args, &err_code))
809 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100810 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100811 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200812 err_code |= ERR_ALERT;
813 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100814 }
815 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100816 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200817 err_code |= ERR_ALERT | ERR_FATAL;
818 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100819 }
820 global.tune.maxaccept = atol(args[1]);
821 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200822 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200823 if (alertif_too_many_args(1, file, linenum, args, &err_code))
824 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200825 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100826 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200827 err_code |= ERR_ALERT | ERR_FATAL;
828 goto out;
829 }
830 global.tune.chksize = atol(args[1]);
831 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100832 else if (!strcmp(args[0], "tune.recv_enough")) {
833 if (alertif_too_many_args(1, file, linenum, args, &err_code))
834 goto out;
835 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100836 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100837 err_code |= ERR_ALERT | ERR_FATAL;
838 goto out;
839 }
840 global.tune.recv_enough = atol(args[1]);
841 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100842 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200843 if (alertif_too_many_args(1, file, linenum, args, &err_code))
844 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100845 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100846 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100847 err_code |= ERR_ALERT | ERR_FATAL;
848 goto out;
849 }
850 global.tune.buf_limit = atol(args[1]);
851 if (global.tune.buf_limit) {
852 if (global.tune.buf_limit < 3)
853 global.tune.buf_limit = 3;
854 if (global.tune.buf_limit <= global.tune.reserved_bufs)
855 global.tune.buf_limit = global.tune.reserved_bufs + 1;
856 }
857 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100858 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200859 if (alertif_too_many_args(1, file, linenum, args, &err_code))
860 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100861 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100862 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100863 err_code |= ERR_ALERT | ERR_FATAL;
864 goto out;
865 }
866 global.tune.reserved_bufs = atol(args[1]);
867 if (global.tune.reserved_bufs < 2)
868 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100869 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
870 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100871 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200872 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200873 if (alertif_too_many_args(1, file, linenum, args, &err_code))
874 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200875 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100876 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200877 err_code |= ERR_ALERT | ERR_FATAL;
878 goto out;
879 }
880 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200881 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100882 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200883 err_code |= ERR_ALERT | ERR_FATAL;
884 goto out;
885 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200886 }
887 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200888 if (alertif_too_many_args(1, file, linenum, args, &err_code))
889 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200890 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100891 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200892 err_code |= ERR_ALERT | ERR_FATAL;
893 goto out;
894 }
895 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200896 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100897 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200898 err_code |= ERR_ALERT | ERR_FATAL;
899 goto out;
900 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200901 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100902 else if (!strcmp(args[0], "tune.idletimer")) {
903 unsigned int idle;
904 const char *res;
905
William Lallemand1a748ae2015-05-19 16:37:23 +0200906 if (alertif_too_many_args(1, file, linenum, args, &err_code))
907 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100908 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100909 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 +0100910 err_code |= ERR_ALERT | ERR_FATAL;
911 goto out;
912 }
913
914 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
915 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100916 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100917 file, linenum, *res, args[0]);
918 err_code |= ERR_ALERT | ERR_FATAL;
919 goto out;
920 }
921
922 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100923 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 +0100924 err_code |= ERR_ALERT | ERR_FATAL;
925 goto out;
926 }
927 global.tune.idle_timer = idle;
928 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100929 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200930 if (alertif_too_many_args(1, file, linenum, args, &err_code))
931 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100932 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100933 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100934 err_code |= ERR_ALERT;
935 goto out;
936 }
937 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100938 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100939 err_code |= ERR_ALERT | ERR_FATAL;
940 goto out;
941 }
942 global.tune.client_rcvbuf = atol(args[1]);
943 }
944 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200945 if (alertif_too_many_args(1, file, linenum, args, &err_code))
946 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100947 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100948 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100949 err_code |= ERR_ALERT;
950 goto out;
951 }
952 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100953 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100954 err_code |= ERR_ALERT | ERR_FATAL;
955 goto out;
956 }
957 global.tune.server_rcvbuf = atol(args[1]);
958 }
959 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200960 if (alertif_too_many_args(1, file, linenum, args, &err_code))
961 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100962 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100963 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100964 err_code |= ERR_ALERT;
965 goto out;
966 }
967 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100968 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100969 err_code |= ERR_ALERT | ERR_FATAL;
970 goto out;
971 }
972 global.tune.client_sndbuf = atol(args[1]);
973 }
974 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200975 if (alertif_too_many_args(1, file, linenum, args, &err_code))
976 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100977 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100978 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100979 err_code |= ERR_ALERT;
980 goto out;
981 }
982 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100983 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100984 err_code |= ERR_ALERT | ERR_FATAL;
985 goto out;
986 }
987 global.tune.server_sndbuf = atol(args[1]);
988 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200989 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200990 if (alertif_too_many_args(1, file, linenum, args, &err_code))
991 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200992 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100993 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200994 err_code |= ERR_ALERT | ERR_FATAL;
995 goto out;
996 }
997 global.tune.pipesize = atol(args[1]);
998 }
Willy Tarreau193b8c62012-11-22 00:17:38 +0100999 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001000 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1001 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001002 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001003 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001004 err_code |= ERR_ALERT | ERR_FATAL;
1005 goto out;
1006 }
1007 global.tune.cookie_len = atol(args[1]) + 1;
1008 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001009 else if (!strcmp(args[0], "tune.http.logurilen")) {
1010 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1011 goto out;
1012 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001013 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001014 err_code |= ERR_ALERT | ERR_FATAL;
1015 goto out;
1016 }
1017 global.tune.requri_len = atol(args[1]) + 1;
1018 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001019 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001020 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1021 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001022 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001023 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001024 err_code |= ERR_ALERT | ERR_FATAL;
1025 goto out;
1026 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001027 global.tune.max_http_hdr = atoi(args[1]);
1028 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001029 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1030 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001031 err_code |= ERR_ALERT | ERR_FATAL;
1032 goto out;
1033 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001034 }
William Lallemandf3747832012-11-09 12:33:10 +01001035 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001036 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1037 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001038 if (*args[1]) {
1039 global.tune.comp_maxlevel = atoi(args[1]);
1040 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001041 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1042 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001043 err_code |= ERR_ALERT | ERR_FATAL;
1044 goto out;
1045 }
1046 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001047 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1048 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001049 err_code |= ERR_ALERT | ERR_FATAL;
1050 goto out;
1051 }
1052 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001053 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1054 if (*args[1]) {
1055 global.tune.pattern_cache = atoi(args[1]);
1056 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001057 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1058 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001059 err_code |= ERR_ALERT | ERR_FATAL;
1060 goto out;
1061 }
1062 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001063 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1064 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001065 err_code |= ERR_ALERT | ERR_FATAL;
1066 goto out;
1067 }
1068 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001069 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001070 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1071 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001072 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001073 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001074 err_code |= ERR_ALERT;
1075 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001076 }
1077 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001078 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001079 err_code |= ERR_ALERT | ERR_FATAL;
1080 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001081 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001082 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001083 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 +01001084 err_code |= ERR_WARN;
1085 goto out;
1086 }
1087
Willy Tarreaubaaee002006-06-26 02:48:02 +02001088 }
1089 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001090 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1091 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001092 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001093 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001094 err_code |= ERR_ALERT;
1095 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001096 }
1097 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001098 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001099 err_code |= ERR_ALERT | ERR_FATAL;
1100 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001101 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001102 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001103 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 +01001104 err_code |= ERR_WARN;
1105 goto out;
1106 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001107 }
Simon Horman98637e52014-06-20 12:30:16 +09001108 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001109 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1110 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001111 global.external_check = 1;
1112 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001113 /* user/group name handling */
1114 else if (!strcmp(args[0], "user")) {
1115 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001116 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1117 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001118 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001119 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001120 err_code |= ERR_ALERT;
1121 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001122 }
1123 errno = 0;
1124 ha_user = getpwnam(args[1]);
1125 if (ha_user != NULL) {
1126 global.uid = (int)ha_user->pw_uid;
1127 }
1128 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001129 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 +02001130 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001131 }
1132 }
1133 else if (!strcmp(args[0], "group")) {
1134 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001135 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1136 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001137 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001138 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001139 err_code |= ERR_ALERT;
1140 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001141 }
1142 errno = 0;
1143 ha_group = getgrnam(args[1]);
1144 if (ha_group != NULL) {
1145 global.gid = (int)ha_group->gr_gid;
1146 }
1147 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001148 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 +02001149 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001150 }
1151 }
1152 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001153 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001154 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1155 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001156 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001157 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001158 err_code |= ERR_ALERT | ERR_FATAL;
1159 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001160 }
1161 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001162 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001163 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1164 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001165 err_code |= ERR_ALERT | ERR_FATAL;
1166 goto out;
1167 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001168 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001169 else if (!strcmp(args[0], "nbthread")) {
1170 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1171 goto out;
1172 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001173 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001174 err_code |= ERR_ALERT | ERR_FATAL;
1175 goto out;
1176 }
1177 global.nbthread = atol(args[1]);
1178 if (global.nbthread < 1 || global.nbthread > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1180 file, linenum, args[0], LONGBITS, global.nbthread);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001181 err_code |= ERR_ALERT | ERR_FATAL;
1182 goto out;
1183 }
1184#ifndef USE_THREAD
1185 if (global.nbthread > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001186 ha_alert("HAProxy is not compiled with threads support, please check build options for USE_THREAD.\n");
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001187 global.nbthread = 1;
1188 err_code |= ERR_ALERT | ERR_FATAL;
1189 goto out;
1190 }
1191#endif
1192 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001193 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001194 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1195 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001196 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001197 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001198 err_code |= ERR_ALERT;
1199 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001200 }
1201 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001202 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001203 err_code |= ERR_ALERT | ERR_FATAL;
1204 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001205 }
1206 global.maxconn = atol(args[1]);
1207#ifdef SYSTEM_MAXCONN
1208 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001209 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 +02001210 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001211 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001212 }
1213#endif /* SYSTEM_MAXCONN */
1214 }
Emeric Brun850efd52014-01-29 12:24:34 +01001215 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001216 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1217 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001218 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001219 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001220 err_code |= ERR_ALERT | ERR_FATAL;
1221 goto out;
1222 }
1223 if (strcmp(args[1],"none") == 0)
1224 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1225 else if (strcmp(args[1],"required") == 0)
1226 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1227 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001228 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001229 err_code |= ERR_ALERT | ERR_FATAL;
1230 goto out;
1231 }
1232 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001233 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001234 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1235 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001236 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001237 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001238 err_code |= ERR_ALERT;
1239 goto out;
1240 }
1241 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001242 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001243 err_code |= ERR_ALERT | ERR_FATAL;
1244 goto out;
1245 }
1246 global.cps_lim = atol(args[1]);
1247 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001248 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001249 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1250 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001251 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001252 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001253 err_code |= ERR_ALERT;
1254 goto out;
1255 }
1256 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001257 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001258 err_code |= ERR_ALERT | ERR_FATAL;
1259 goto out;
1260 }
1261 global.sps_lim = atol(args[1]);
1262 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001263 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001264 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1265 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001266 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001267 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001268 err_code |= ERR_ALERT;
1269 goto out;
1270 }
1271 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001272 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001273 err_code |= ERR_ALERT | ERR_FATAL;
1274 goto out;
1275 }
1276 global.ssl_lim = atol(args[1]);
1277 }
William Lallemandd85f9172012-11-09 17:05:39 +01001278 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001279 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1280 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001281 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001282 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 +01001283 err_code |= ERR_ALERT | ERR_FATAL;
1284 goto out;
1285 }
1286 global.comp_rate_lim = atoi(args[1]) * 1024;
1287 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001288 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001289 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1290 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001291 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001292 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001293 err_code |= ERR_ALERT;
1294 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001295 }
1296 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001297 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001298 err_code |= ERR_ALERT | ERR_FATAL;
1299 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001300 }
1301 global.maxpipes = atol(args[1]);
1302 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001303 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001304 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1305 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001306 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001307 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001308 err_code |= ERR_ALERT | ERR_FATAL;
1309 goto out;
1310 }
William Lallemande3a7d992012-11-20 11:25:20 +01001311 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001312 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001313 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001314 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1315 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001316 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001317 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 +01001318 err_code |= ERR_ALERT | ERR_FATAL;
1319 goto out;
1320 }
1321 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001322 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001323 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 +01001324 err_code |= ERR_ALERT | ERR_FATAL;
1325 goto out;
1326 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001327 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001328
Willy Tarreaubaaee002006-06-26 02:48:02 +02001329 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001330 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1331 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001332 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001333 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001334 err_code |= ERR_ALERT;
1335 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001336 }
1337 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001338 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001339 err_code |= ERR_ALERT | ERR_FATAL;
1340 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001341 }
1342 global.rlimit_nofile = atol(args[1]);
1343 }
1344 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001345 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1346 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001347 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001348 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001349 err_code |= ERR_ALERT;
1350 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001351 }
1352 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001353 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001354 err_code |= ERR_ALERT | ERR_FATAL;
1355 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001356 }
1357 global.chroot = strdup(args[1]);
1358 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001359 else if (!strcmp(args[0], "description")) {
1360 int i, len=0;
1361 char *d;
1362
1363 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001364 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1365 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001366 err_code |= ERR_ALERT | ERR_FATAL;
1367 goto out;
1368 }
1369
Willy Tarreau348acfe2014-04-14 15:00:39 +02001370 for (i = 1; *args[i]; i++)
1371 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001372
1373 if (global.desc)
1374 free(global.desc);
1375
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001376 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001377
Willy Tarreau348acfe2014-04-14 15:00:39 +02001378 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1379 for (i = 2; *args[i]; i++)
1380 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001381 }
1382 else if (!strcmp(args[0], "node")) {
1383 int i;
1384 char c;
1385
William Lallemand1a748ae2015-05-19 16:37:23 +02001386 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1387 goto out;
1388
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001389 for (i=0; args[1][i]; i++) {
1390 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001391 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1392 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001393 break;
1394 }
1395
1396 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001397 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1398 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1399 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001400 err_code |= ERR_ALERT | ERR_FATAL;
1401 goto out;
1402 }
1403
1404 if (global.node)
1405 free(global.node);
1406
1407 global.node = strdup(args[1]);
1408 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001409 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001410 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1411 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001412 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001413 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001414 err_code |= ERR_ALERT;
1415 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001416 }
1417 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001418 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 +02001419 err_code |= ERR_ALERT | ERR_FATAL;
1420 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001421 }
1422 global.pidfile = strdup(args[1]);
1423 }
Emeric Bruned760922010-10-22 17:59:25 +02001424 else if (!strcmp(args[0], "unix-bind")) {
1425 int cur_arg = 1;
1426 while (*(args[cur_arg])) {
1427 if (!strcmp(args[cur_arg], "prefix")) {
1428 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001429 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001430 err_code |= ERR_ALERT;
1431 cur_arg += 2;
1432 continue;
1433 }
1434
1435 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001436 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 +02001437 err_code |= ERR_ALERT | ERR_FATAL;
1438 goto out;
1439 }
1440 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1441 cur_arg += 2;
1442 continue;
1443 }
1444
1445 if (!strcmp(args[cur_arg], "mode")) {
1446
1447 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1448 cur_arg += 2;
1449 continue;
1450 }
1451
1452 if (!strcmp(args[cur_arg], "uid")) {
1453
1454 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1455 cur_arg += 2;
1456 continue;
1457 }
1458
1459 if (!strcmp(args[cur_arg], "gid")) {
1460
1461 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1462 cur_arg += 2;
1463 continue;
1464 }
1465
1466 if (!strcmp(args[cur_arg], "user")) {
1467 struct passwd *user;
1468
1469 user = getpwnam(args[cur_arg + 1]);
1470 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001471 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1472 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001473 err_code |= ERR_ALERT | ERR_FATAL;
1474 goto out;
1475 }
1476
1477 global.unix_bind.ux.uid = user->pw_uid;
1478 cur_arg += 2;
1479 continue;
1480 }
1481
1482 if (!strcmp(args[cur_arg], "group")) {
1483 struct group *group;
1484
1485 group = getgrnam(args[cur_arg + 1]);
1486 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001487 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1488 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001489 err_code |= ERR_ALERT | ERR_FATAL;
1490 goto out;
1491 }
1492
1493 global.unix_bind.ux.gid = group->gr_gid;
1494 cur_arg += 2;
1495 continue;
1496 }
1497
Christopher Faulet767a84b2017-11-24 16:50:31 +01001498 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1499 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001500 err_code |= ERR_ALERT | ERR_FATAL;
1501 goto out;
1502 }
1503 }
William Lallemand0f99e342011-10-12 17:50:54 +02001504 else if (!strcmp(args[0], "log") && kwm == KWM_NO) { /* no log */
1505 /* delete previous herited or defined syslog servers */
1506 struct logsrv *back;
1507 struct logsrv *tmp;
1508
1509 if (*(args[1]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001510 ha_alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
William Lallemand0f99e342011-10-12 17:50:54 +02001511 err_code |= ERR_ALERT | ERR_FATAL;
1512 goto out;
1513 }
1514
1515 list_for_each_entry_safe(tmp, back, &global.logsrvs, list) {
1516 LIST_DEL(&tmp->list);
1517 free(tmp);
1518 }
1519 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001520 else if (!strcmp(args[0], "log")) { /* syslog server address */
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001521 struct sockaddr_storage *sk;
1522 int port1, port2;
William Lallemand0f99e342011-10-12 17:50:54 +02001523 struct logsrv *logsrv;
Willy Tarreau18324f52014-06-27 18:10:07 +02001524 int arg = 0;
1525 int len = 0;
William Lallemand0f99e342011-10-12 17:50:54 +02001526
William Lallemand1a748ae2015-05-19 16:37:23 +02001527 if (alertif_too_many_args(8, file, linenum, args, &err_code)) /* does not strictly check optional arguments */
1528 goto out;
1529
Willy Tarreaubaaee002006-06-26 02:48:02 +02001530 if (*(args[1]) == 0 || *(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001531 ha_alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001532 err_code |= ERR_ALERT | ERR_FATAL;
1533 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001534 }
William Lallemand0f99e342011-10-12 17:50:54 +02001535
Vincent Bernat02779b62016-04-03 13:48:43 +02001536 logsrv = calloc(1, sizeof(*logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02001537
Willy Tarreau18324f52014-06-27 18:10:07 +02001538 /* just after the address, a length may be specified */
1539 if (strcmp(args[arg+2], "len") == 0) {
1540 len = atoi(args[arg+3]);
1541 if (len < 80 || len > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001542 ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
1543 file, linenum, args[arg+3]);
Willy Tarreau18324f52014-06-27 18:10:07 +02001544 err_code |= ERR_ALERT | ERR_FATAL;
1545 goto out;
1546 }
1547 logsrv->maxlen = len;
1548
1549 /* skip these two args */
1550 arg += 2;
1551 }
1552 else
1553 logsrv->maxlen = MAX_SYSLOG_LEN;
1554
Christopher Faulet084aa962017-08-29 16:54:41 +02001555 if (logsrv->maxlen > global.max_syslog_len)
Willy Tarreau18324f52014-06-27 18:10:07 +02001556 global.max_syslog_len = logsrv->maxlen;
Willy Tarreau18324f52014-06-27 18:10:07 +02001557
Dragan Dosen1322d092015-09-22 16:05:32 +02001558 /* after the length, a format may be specified */
1559 if (strcmp(args[arg+2], "format") == 0) {
1560 logsrv->format = get_log_format(args[arg+3]);
1561 if (logsrv->format < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001562 ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
Dragan Dosen1322d092015-09-22 16:05:32 +02001563 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01001564 free(logsrv);
Dragan Dosen1322d092015-09-22 16:05:32 +02001565 goto out;
1566 }
1567
1568 /* skip these two args */
1569 arg += 2;
1570 }
1571
David Carlier97880bb2016-04-08 10:35:26 +01001572 if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code)) {
1573 free(logsrv);
William Lallemand1a748ae2015-05-19 16:37:23 +02001574 goto out;
David Carlier97880bb2016-04-08 10:35:26 +01001575 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001576
Willy Tarreau18324f52014-06-27 18:10:07 +02001577 logsrv->facility = get_log_facility(args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02001578 if (logsrv->facility < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001579 ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001580 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001581 logsrv->facility = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001582 }
1583
William Lallemand0f99e342011-10-12 17:50:54 +02001584 logsrv->level = 7; /* max syslog level = debug */
Willy Tarreau18324f52014-06-27 18:10:07 +02001585 if (*(args[arg+3])) {
1586 logsrv->level = get_log_level(args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02001587 if (logsrv->level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001588 ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001589 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001590 logsrv->level = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001591 }
1592 }
1593
William Lallemand0f99e342011-10-12 17:50:54 +02001594 logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
Willy Tarreau18324f52014-06-27 18:10:07 +02001595 if (*(args[arg+4])) {
1596 logsrv->minlvl = get_log_level(args[arg+4]);
William Lallemand0f99e342011-10-12 17:50:54 +02001597 if (logsrv->minlvl < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001598 ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001599 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001600 logsrv->minlvl = 0;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02001601 }
1602 }
1603
Willy Tarreau48ef4c92017-01-06 18:32:38 +01001604 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001605 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001606 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001607 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001608 free(logsrv);
1609 goto out;
1610 }
1611 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001612
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001613 if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001614 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001615 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
1616 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01001617 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001618 free(logsrv);
Willy Tarreaud5191e72010-02-09 20:50:45 +01001619 goto out;
1620 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001621
William Lallemand0f99e342011-10-12 17:50:54 +02001622 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001623 if (!port1)
William Lallemand0f99e342011-10-12 17:50:54 +02001624 set_host_port(&logsrv->addr, SYSLOG_PORT);
Robert Tsai81ae1952007-12-05 10:47:29 +01001625 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001626
William Lallemand0f99e342011-10-12 17:50:54 +02001627 LIST_ADDQ(&global.logsrvs, &logsrv->list);
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001628 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001629 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1630 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001631
1632 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001633 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001634 err_code |= ERR_ALERT;
1635 goto out;
1636 }
1637
1638 if (*(args[1]))
1639 name = args[1];
1640 else
1641 name = hostname;
1642
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001643 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001644 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001645 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001646 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1647 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001648 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001649 err_code |= ERR_ALERT;
1650 goto out;
1651 }
1652
1653 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001654 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001655 err_code |= ERR_FATAL;
1656 goto out;
1657 }
1658
1659 global.server_state_base = strdup(args[1]);
1660 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001661 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1662 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001663 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001664 err_code |= ERR_ALERT;
1665 goto out;
1666 }
1667
1668 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001669 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001670 err_code |= ERR_FATAL;
1671 goto out;
1672 }
1673
1674 global.server_state_file = strdup(args[1]);
1675 }
Kevinm48936af2010-12-22 16:08:21 +00001676 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001677 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1678 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001679 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001680 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001681 err_code |= ERR_ALERT | ERR_FATAL;
1682 goto out;
1683 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001684 chunk_destroy(&global.log_tag);
1685 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001686 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001687 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001688 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1689 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001690 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001691 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001692 err_code |= ERR_ALERT;
1693 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001694 }
1695 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001696 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001697 err_code |= ERR_ALERT | ERR_FATAL;
1698 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001699 }
1700 global.spread_checks = atol(args[1]);
1701 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001702 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 +02001703 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001704 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001705 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001706 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1707 const char *err;
1708 unsigned int val;
1709
William Lallemand1a748ae2015-05-19 16:37:23 +02001710 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1711 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001712 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001713 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001714 err_code |= ERR_ALERT | ERR_FATAL;
1715 goto out;
1716 }
1717
1718 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1719 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001720 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 +02001721 err_code |= ERR_ALERT | ERR_FATAL;
1722 }
1723 global.max_spread_checks = val;
1724 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001725 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001726 err_code |= ERR_ALERT | ERR_FATAL;
1727 }
1728 }
Christopher Faulet62519022017-10-16 15:49:32 +02001729 else if (strcmp(args[0], "cpu-map") == 0) {
1730 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001731#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001732 char *slash;
1733 unsigned long proc = 0, thread = 0, cpus;
1734 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001735
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001736 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001737 ha_alert("parsing [%s:%d] : %s expects a process number "
1738 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1739 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1740 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001741 err_code |= ERR_ALERT | ERR_FATAL;
1742 goto out;
1743 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001744
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001745 if ((slash = strchr(args[1], '/')) != NULL)
1746 *slash = 0;
1747
Christopher Faulet26028f62017-11-22 15:01:51 +01001748 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001749 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001750 err_code |= ERR_ALERT | ERR_FATAL;
1751 goto out;
1752 }
1753
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001754 if (slash) {
1755 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001756 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001757 err_code |= ERR_ALERT | ERR_FATAL;
1758 goto out;
1759 }
1760 *slash = '/';
1761
1762 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001763 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1764 "a process range _AND_ a thread range\n",
1765 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001766 err_code |= ERR_ALERT | ERR_FATAL;
1767 goto out;
1768 }
1769 }
1770
Christopher Faulet62519022017-10-16 15:49:32 +02001771 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001772 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001773 err_code |= ERR_ALERT | ERR_FATAL;
1774 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001775 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001776
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001777 if (autoinc &&
1778 my_popcountl(proc) != my_popcountl(cpus) &&
1779 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001780 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1781 "must have the same size to be automatically bound\n",
1782 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001783 err_code |= ERR_ALERT | ERR_FATAL;
1784 goto out;
1785 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001786
Christopher Faulet26028f62017-11-22 15:01:51 +01001787 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001788 /* No mapping for this process */
1789 if (!(proc & (1UL << i)))
1790 continue;
1791
1792 /* Mapping at the process level */
1793 if (!thread) {
1794 if (!autoinc)
1795 global.cpu_map.proc[i] = cpus;
1796 else {
1797 n += my_ffsl(cpus >> n);
1798 global.cpu_map.proc[i] = (1UL << (n-1));
1799 }
1800 continue;
1801 }
1802
1803 /* Mapping at the thread level */
1804 for (j = 0; j < LONGBITS; j++) {
1805 /* Np mapping for this thread */
1806 if (!(thread & (1UL << j)))
1807 continue;
1808
1809 if (!autoinc)
1810 global.cpu_map.thread[i][j] = cpus;
1811 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001812 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001813 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001814 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001815 }
1816 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001817#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001818 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1819 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001820 err_code |= ERR_ALERT | ERR_FATAL;
1821 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001822#endif /* ! USE_CPU_AFFINITY */
1823 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001824 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1825 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1826 goto out;
1827
1828 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001829 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001830 err_code |= ERR_ALERT | ERR_FATAL;
1831 goto out;
1832 }
1833
1834 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1835 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001836 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 +01001837 err_code |= ERR_ALERT | ERR_FATAL;
1838 goto out;
1839 }
1840 }
1841 else if (!strcmp(args[0], "unsetenv")) {
1842 int arg;
1843
1844 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001845 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001846 err_code |= ERR_ALERT | ERR_FATAL;
1847 goto out;
1848 }
1849
1850 for (arg = 1; *args[arg]; arg++) {
1851 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001852 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 +01001853 err_code |= ERR_ALERT | ERR_FATAL;
1854 goto out;
1855 }
1856 }
1857 }
1858 else if (!strcmp(args[0], "resetenv")) {
1859 extern char **environ;
1860 char **env = environ;
1861
1862 /* args contain variable names to keep, one per argument */
1863 while (*env) {
1864 int arg;
1865
1866 /* look for current variable in among all those we want to keep */
1867 for (arg = 1; *args[arg]; arg++) {
1868 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1869 (*env)[strlen(args[arg])] == '=')
1870 break;
1871 }
1872
1873 /* delete this variable */
1874 if (!*args[arg]) {
1875 char *delim = strchr(*env, '=');
1876
1877 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001878 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 +01001879 err_code |= ERR_ALERT | ERR_FATAL;
1880 goto out;
1881 }
1882
1883 memcpy(trash.str, *env, delim - *env);
1884 trash.str[delim - *env] = 0;
1885
1886 if (unsetenv(trash.str) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001887 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 +01001888 err_code |= ERR_ALERT | ERR_FATAL;
1889 goto out;
1890 }
1891 }
1892 else
1893 env++;
1894 }
1895 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001896 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001897 struct cfg_kw_list *kwl;
1898 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001899 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001900
1901 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1902 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1903 if (kwl->kw[index].section != CFG_GLOBAL)
1904 continue;
1905 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001906 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001907 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001908 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001909 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001910 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001911 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001912 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001913 err_code |= ERR_WARN;
1914 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001915 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001916 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001917 }
1918 }
1919 }
1920
Christopher Faulet767a84b2017-11-24 16:50:31 +01001921 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001922 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001923 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001924
Willy Tarreau058e9072009-07-20 09:30:05 +02001925 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001926 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001927 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001928}
1929
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001930void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001931{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001932 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001933 defproxy.mode = PR_MODE_TCP;
1934 defproxy.state = PR_STNEW;
1935 defproxy.maxconn = cfg_maxpconn;
1936 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001937 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001938 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001939
Simon Horman66183002013-02-23 10:16:43 +09001940 defproxy.defsrv.check.inter = DEF_CHKINTR;
1941 defproxy.defsrv.check.fastinter = 0;
1942 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001943 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1944 defproxy.defsrv.agent.fastinter = 0;
1945 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001946 defproxy.defsrv.check.rise = DEF_RISETIME;
1947 defproxy.defsrv.check.fall = DEF_FALLTIME;
1948 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1949 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001950 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001951 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001952 defproxy.defsrv.maxqueue = 0;
1953 defproxy.defsrv.minconn = 0;
1954 defproxy.defsrv.maxconn = 0;
1955 defproxy.defsrv.slowstart = 0;
1956 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1957 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1958 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001959
1960 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001961 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001962}
1963
Willy Tarreauade5ec42010-01-28 19:33:49 +01001964
Willy Tarreau63af98d2014-05-18 08:11:41 +02001965/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1966 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1967 * ERR_FATAL in case of error.
1968 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001969static int create_cond_regex_rule(const char *file, int line,
1970 struct proxy *px, int dir, int action, int flags,
1971 const char *cmd, const char *reg, const char *repl,
1972 const char **cond_start)
1973{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001974 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001975 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001976 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001977 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001978 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001979 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001980 int cs;
1981 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001982
1983 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001984 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001985 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001986 goto err;
1987 }
1988
1989 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001990 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001991 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001992 goto err;
1993 }
1994
Christopher Faulet898566e2016-10-26 11:06:28 +02001995 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001996 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001997
Willy Tarreau5321c422010-01-28 20:35:13 +01001998 if (cond_start &&
1999 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02002000 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002001 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
2002 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002003 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01002004 goto err;
2005 }
2006 }
2007 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002008 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
2009 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002010 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01002011 goto err;
2012 }
2013
Willy Tarreau63af98d2014-05-18 08:11:41 +02002014 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01002015 (dir == SMP_OPT_DIR_REQ) ?
2016 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
2017 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
2018 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01002019
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002020 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01002021 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002022 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002023 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002024 goto err;
2025 }
2026
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002027 cs = !(flags & REG_ICASE);
2028 cap = !(flags & REG_NOSUB);
2029 error = NULL;
2030 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002031 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002032 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002033 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002034 goto err;
2035 }
2036
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02002037 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01002038 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01002039 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002040 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
2041 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002042 ret_code |= ERR_ALERT | ERR_FATAL;
2043 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002044 }
2045
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02002046 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02002047 ret_code |= ERR_WARN;
2048
2049 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002050
Willy Tarreau63af98d2014-05-18 08:11:41 +02002051 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002052 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01002053 err:
2054 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002055 free(errmsg);
2056 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002057}
2058
Willy Tarreaubaaee002006-06-26 02:48:02 +02002059/*
William Lallemand51097192015-04-14 16:35:22 +02002060 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02002061 * Returns the error code, 0 if OK, or any combination of :
2062 * - ERR_ABORT: must abort ASAP
2063 * - ERR_FATAL: we can continue parsing but not start the service
2064 * - ERR_WARN: a warning has been emitted
2065 * - ERR_ALERT: an alert has been emitted
2066 * Only the two first ones can stop processing, the two others are just
2067 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02002068 */
Emeric Brun32da3c42010-09-23 18:39:19 +02002069int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
2070{
2071 static struct peers *curpeers = NULL;
2072 struct peer *newpeer = NULL;
2073 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002074 struct bind_conf *bind_conf;
2075 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02002076 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01002077 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002078
2079 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002080 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002081 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01002082 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002083 goto out;
2084 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002085
William Lallemand6e62fb62015-04-28 16:55:23 +02002086 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2087 goto out;
2088
Emeric Brun32da3c42010-09-23 18:39:19 +02002089 err = invalid_char(args[1]);
2090 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002091 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2092 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01002093 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002094 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002095 }
2096
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002097 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02002098 /*
2099 * If there are two proxies with the same name only following
2100 * combinations are allowed:
2101 */
2102 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002103 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2104 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002105 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002106 }
2107 }
2108
Vincent Bernat02779b62016-04-03 13:48:43 +02002109 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002110 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002111 err_code |= ERR_ALERT | ERR_ABORT;
2112 goto out;
2113 }
2114
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002115 curpeers->next = cfg_peers;
2116 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002117 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002118 curpeers->conf.line = linenum;
2119 curpeers->last_change = now.tv_sec;
2120 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002121 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002122 }
2123 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002124 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002125 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002126 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002127
2128 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002129 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2130 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002131 err_code |= ERR_ALERT | ERR_FATAL;
2132 goto out;
2133 }
2134
2135 err = invalid_char(args[1]);
2136 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002137 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2138 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002139 err_code |= ERR_ALERT | ERR_FATAL;
2140 goto out;
2141 }
2142
Vincent Bernat02779b62016-04-03 13:48:43 +02002143 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002144 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002145 err_code |= ERR_ALERT | ERR_ABORT;
2146 goto out;
2147 }
2148
2149 /* the peers are linked backwards first */
2150 curpeers->count++;
2151 newpeer->next = curpeers->remote;
2152 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002153 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002154 newpeer->conf.line = linenum;
2155
2156 newpeer->last_change = now.tv_sec;
2157 newpeer->id = strdup(args[1]);
2158
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002159 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002160 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002161 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002162 err_code |= ERR_ALERT | ERR_FATAL;
2163 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002164 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002165
2166 proto = protocol_by_family(sk->ss_family);
2167 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002168 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2169 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002170 err_code |= ERR_ALERT | ERR_FATAL;
2171 goto out;
2172 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002173
2174 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002175 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2176 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002177 err_code |= ERR_ALERT | ERR_FATAL;
2178 goto out;
2179 }
2180
Willy Tarreau2aa38802013-02-20 19:20:59 +01002181 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002182 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2183 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002184 err_code |= ERR_ALERT | ERR_FATAL;
2185 goto out;
2186 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002187
Emeric Brun32da3c42010-09-23 18:39:19 +02002188 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002189 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002190 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002191 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002192 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002193
Emeric Brun32da3c42010-09-23 18:39:19 +02002194 if (strcmp(newpeer->id, localpeer) == 0) {
2195 /* Current is local peer, it define a frontend */
2196 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002197 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002198
2199 if (!curpeers->peers_fe) {
2200 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002201 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002202 err_code |= ERR_ALERT | ERR_ABORT;
2203 goto out;
2204 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002205
Willy Tarreau237250c2011-07-29 01:49:03 +02002206 init_new_proxy(curpeers->peers_fe);
2207 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002208 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002209 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2210 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002211 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002212
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002213 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002214
Willy Tarreau902636f2013-03-10 19:44:48 +01002215 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2216 if (errmsg && *errmsg) {
2217 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002218 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002219 }
2220 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002221 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2222 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002223 err_code |= ERR_FATAL;
2224 goto out;
2225 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002226
2227 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002228 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002229 l->maxconn = curpeers->peers_fe->maxconn;
2230 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002231 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002232 l->analysers |= curpeers->peers_fe->fe_req_ana;
2233 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002234 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2235 global.maxsock += l->maxconn;
2236 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002237 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002238 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002239 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2240 file, linenum, args[0], args[1],
2241 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002242 err_code |= ERR_FATAL;
2243 goto out;
2244 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002245 }
2246 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002247 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2248 curpeers->state = PR_STSTOPPED;
2249 }
2250 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2251 curpeers->state = PR_STNEW;
2252 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002253 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002254 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002255 err_code |= ERR_ALERT | ERR_FATAL;
2256 goto out;
2257 }
2258
2259out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002260 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002261 return err_code;
2262}
2263
Baptiste Assmann325137d2015-04-13 23:40:55 +02002264/*
2265 * Parse a <resolvers> section.
2266 * Returns the error code, 0 if OK, or any combination of :
2267 * - ERR_ABORT: must abort ASAP
2268 * - ERR_FATAL: we can continue parsing but not start the service
2269 * - ERR_WARN: a warning has been emitted
2270 * - ERR_ALERT: an alert has been emitted
2271 * Only the two first ones can stop processing, the two others are just
2272 * indicators.
2273 */
2274int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2275{
2276 static struct dns_resolvers *curr_resolvers = NULL;
2277 struct dns_nameserver *newnameserver = NULL;
2278 const char *err;
2279 int err_code = 0;
2280 char *errmsg = NULL;
2281
2282 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2283 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002284 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002285 err_code |= ERR_ALERT | ERR_ABORT;
2286 goto out;
2287 }
2288
2289 err = invalid_char(args[1]);
2290 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002291 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2292 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002293 err_code |= ERR_ALERT | ERR_ABORT;
2294 goto out;
2295 }
2296
2297 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2298 /* Error if two resolvers owns the same name */
2299 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002300 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2301 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002302 err_code |= ERR_ALERT | ERR_ABORT;
2303 }
2304 }
2305
Vincent Bernat02779b62016-04-03 13:48:43 +02002306 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002307 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002308 err_code |= ERR_ALERT | ERR_ABORT;
2309 goto out;
2310 }
2311
2312 /* default values */
2313 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2314 curr_resolvers->conf.file = strdup(file);
2315 curr_resolvers->conf.line = linenum;
2316 curr_resolvers->id = strdup(args[1]);
2317 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002318 /* default maximum response size */
2319 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002320 /* default hold period for nx, other, refuse and timeout is 30s */
2321 curr_resolvers->hold.nx = 30000;
2322 curr_resolvers->hold.other = 30000;
2323 curr_resolvers->hold.refused = 30000;
2324 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002325 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002326 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002327 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002328 curr_resolvers->timeout.resolve = 1000;
2329 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002330 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002331 curr_resolvers->nb_nameservers = 0;
2332 LIST_INIT(&curr_resolvers->nameservers);
2333 LIST_INIT(&curr_resolvers->resolutions.curr);
2334 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002335 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002336 }
2337 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2338 struct sockaddr_storage *sk;
2339 int port1, port2;
2340 struct protocol *proto;
2341
2342 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002343 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2344 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002345 err_code |= ERR_ALERT | ERR_FATAL;
2346 goto out;
2347 }
2348
2349 err = invalid_char(args[1]);
2350 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002351 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2352 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002353 err_code |= ERR_ALERT | ERR_FATAL;
2354 goto out;
2355 }
2356
Christopher Faulet67957bd2017-09-27 11:00:59 +02002357 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002358 /* Error if two resolvers owns the same name */
2359 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002360 ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
2361 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002362 err_code |= ERR_ALERT | ERR_FATAL;
2363 }
2364 }
2365
Vincent Bernat02779b62016-04-03 13:48:43 +02002366 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002367 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002368 err_code |= ERR_ALERT | ERR_ABORT;
2369 goto out;
2370 }
2371
2372 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002373 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002374 newnameserver->resolvers = curr_resolvers;
2375 newnameserver->conf.file = strdup(file);
2376 newnameserver->conf.line = linenum;
2377 newnameserver->id = strdup(args[1]);
2378
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002379 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002380 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002381 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002382 err_code |= ERR_ALERT | ERR_FATAL;
2383 goto out;
2384 }
2385
2386 proto = protocol_by_family(sk->ss_family);
2387 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002388 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002389 file, linenum, args[0], args[1]);
2390 err_code |= ERR_ALERT | ERR_FATAL;
2391 goto out;
2392 }
2393
2394 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002395 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2396 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002397 err_code |= ERR_ALERT | ERR_FATAL;
2398 goto out;
2399 }
2400
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002401 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002402 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2403 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002404 err_code |= ERR_ALERT | ERR_FATAL;
2405 goto out;
2406 }
2407
Baptiste Assmann325137d2015-04-13 23:40:55 +02002408 newnameserver->addr = *sk;
2409 }
2410 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2411 const char *res;
2412 unsigned int time;
2413
2414 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002415 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2416 file, linenum, args[0]);
2417 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002418 err_code |= ERR_ALERT | ERR_FATAL;
2419 goto out;
2420 }
2421 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2422 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002423 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2424 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002425 err_code |= ERR_ALERT | ERR_FATAL;
2426 goto out;
2427 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002428 if (strcmp(args[1], "nx") == 0)
2429 curr_resolvers->hold.nx = time;
2430 else if (strcmp(args[1], "other") == 0)
2431 curr_resolvers->hold.other = time;
2432 else if (strcmp(args[1], "refused") == 0)
2433 curr_resolvers->hold.refused = time;
2434 else if (strcmp(args[1], "timeout") == 0)
2435 curr_resolvers->hold.timeout = time;
2436 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002437 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002438 else if (strcmp(args[1], "obsolete") == 0)
2439 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002440 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002441 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2442 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002443 err_code |= ERR_ALERT | ERR_FATAL;
2444 goto out;
2445 }
2446
2447 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002448 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002449 int i = 0;
2450
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002451 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002452 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2453 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002454 err_code |= ERR_ALERT | ERR_FATAL;
2455 goto out;
2456 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002457
2458 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002459 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002460 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2461 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002462 err_code |= ERR_ALERT | ERR_FATAL;
2463 goto out;
2464 }
2465
2466 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002467 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002468 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002469 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2470 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002471 err_code |= ERR_WARN;
2472 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002473 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002474 else if (strcmp(args[0], "resolve_retries") == 0) {
2475 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002476 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2477 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002478 err_code |= ERR_ALERT | ERR_FATAL;
2479 goto out;
2480 }
2481 curr_resolvers->resolve_retries = atoi(args[1]);
2482 }
2483 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002484 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002485 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2486 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002487 err_code |= ERR_ALERT | ERR_FATAL;
2488 goto out;
2489 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002490 else if (strcmp(args[1], "retry") == 0 ||
2491 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002492 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002493 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002494
2495 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002496 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2497 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002498 err_code |= ERR_ALERT | ERR_FATAL;
2499 goto out;
2500 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002501 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002502 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002503 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2504 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002505 err_code |= ERR_ALERT | ERR_FATAL;
2506 goto out;
2507 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002508 if (args[1][2] == 't')
2509 curr_resolvers->timeout.retry = tout;
2510 else
2511 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002512 }
2513 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002514 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2515 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002516 err_code |= ERR_ALERT | ERR_FATAL;
2517 goto out;
2518 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002519 } /* neither "nameserver" nor "resolvers" */
2520 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002521 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002522 err_code |= ERR_ALERT | ERR_FATAL;
2523 goto out;
2524 }
2525
2526 out:
2527 free(errmsg);
2528 return err_code;
2529}
Simon Horman0d16a402015-01-30 11:22:58 +09002530
2531/*
William Lallemand51097192015-04-14 16:35:22 +02002532 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002533 * Returns the error code, 0 if OK, or any combination of :
2534 * - ERR_ABORT: must abort ASAP
2535 * - ERR_FATAL: we can continue parsing but not start the service
2536 * - ERR_WARN: a warning has been emitted
2537 * - ERR_ALERT: an alert has been emitted
2538 * Only the two first ones can stop processing, the two others are just
2539 * indicators.
2540 */
2541int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2542{
2543 static struct mailers *curmailers = NULL;
2544 struct mailer *newmailer = NULL;
2545 const char *err;
2546 int err_code = 0;
2547 char *errmsg = NULL;
2548
2549 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2550 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002551 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002552 err_code |= ERR_ALERT | ERR_ABORT;
2553 goto out;
2554 }
2555
2556 err = invalid_char(args[1]);
2557 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002558 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2559 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002560 err_code |= ERR_ALERT | ERR_ABORT;
2561 goto out;
2562 }
2563
2564 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2565 /*
2566 * If there are two proxies with the same name only following
2567 * combinations are allowed:
2568 */
2569 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002570 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2571 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002572 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002573 }
2574 }
2575
Vincent Bernat02779b62016-04-03 13:48:43 +02002576 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002577 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002578 err_code |= ERR_ALERT | ERR_ABORT;
2579 goto out;
2580 }
2581
2582 curmailers->next = mailers;
2583 mailers = curmailers;
2584 curmailers->conf.file = strdup(file);
2585 curmailers->conf.line = linenum;
2586 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002587 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2588 * But need enough time so that timeouts don't occur
2589 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002590 }
2591 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2592 struct sockaddr_storage *sk;
2593 int port1, port2;
2594 struct protocol *proto;
2595
2596 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002597 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2598 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002599 err_code |= ERR_ALERT | ERR_FATAL;
2600 goto out;
2601 }
2602
2603 err = invalid_char(args[1]);
2604 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002605 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2606 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002607 err_code |= ERR_ALERT | ERR_FATAL;
2608 goto out;
2609 }
2610
Vincent Bernat02779b62016-04-03 13:48:43 +02002611 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002612 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002613 err_code |= ERR_ALERT | ERR_ABORT;
2614 goto out;
2615 }
2616
2617 /* the mailers are linked backwards first */
2618 curmailers->count++;
2619 newmailer->next = curmailers->mailer_list;
2620 curmailers->mailer_list = newmailer;
2621 newmailer->mailers = curmailers;
2622 newmailer->conf.file = strdup(file);
2623 newmailer->conf.line = linenum;
2624
2625 newmailer->id = strdup(args[1]);
2626
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002627 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002628 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002629 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002630 err_code |= ERR_ALERT | ERR_FATAL;
2631 goto out;
2632 }
2633
2634 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002635 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002636 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2637 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002638 err_code |= ERR_ALERT | ERR_FATAL;
2639 goto out;
2640 }
2641
2642 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002643 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2644 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002645 err_code |= ERR_ALERT | ERR_FATAL;
2646 goto out;
2647 }
2648
2649 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002650 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2651 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002652 err_code |= ERR_ALERT | ERR_FATAL;
2653 goto out;
2654 }
2655
2656 newmailer->addr = *sk;
2657 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002658 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002659 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002660 }
2661 else if (strcmp(args[0], "timeout") == 0) {
2662 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002663 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2664 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002665 err_code |= ERR_ALERT | ERR_FATAL;
2666 goto out;
2667 }
2668 else if (strcmp(args[1], "mail") == 0) {
2669 const char *res;
2670 unsigned int timeout_mail;
2671 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002672 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2673 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002674 err_code |= ERR_ALERT | ERR_FATAL;
2675 goto out;
2676 }
2677 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2678 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002679 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2680 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002681 err_code |= ERR_ALERT | ERR_FATAL;
2682 goto out;
2683 }
2684 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002685 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 +01002686 err_code |= ERR_ALERT | ERR_FATAL;
2687 goto out;
2688 }
2689 curmailers->timeout.mail = timeout_mail;
2690 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002691 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002692 file, linenum, args[0], args[1]);
2693 err_code |= ERR_ALERT | ERR_FATAL;
2694 goto out;
2695 }
2696 }
Simon Horman0d16a402015-01-30 11:22:58 +09002697 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002698 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002699 err_code |= ERR_ALERT | ERR_FATAL;
2700 goto out;
2701 }
2702
2703out:
2704 free(errmsg);
2705 return err_code;
2706}
2707
Simon Horman9dc49962015-01-30 11:22:59 +09002708static void free_email_alert(struct proxy *p)
2709{
2710 free(p->email_alert.mailers.name);
2711 p->email_alert.mailers.name = NULL;
2712 free(p->email_alert.from);
2713 p->email_alert.from = NULL;
2714 free(p->email_alert.to);
2715 p->email_alert.to = NULL;
2716 free(p->email_alert.myhostname);
2717 p->email_alert.myhostname = NULL;
2718}
2719
Willy Tarreau3842f002009-06-14 11:39:52 +02002720int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002721{
2722 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002723 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002724 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002725 int rc;
2726 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002727 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002728 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002729 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002730 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002731 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002732
Willy Tarreau977b8e42006-12-29 14:19:17 +01002733 if (!strcmp(args[0], "listen"))
2734 rc = PR_CAP_LISTEN;
2735 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002736 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002737 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002738 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002739 else
2740 rc = PR_CAP_NONE;
2741
2742 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002743 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002744 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2745 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2746 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002747 err_code |= ERR_ALERT | ERR_ABORT;
2748 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002749 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002750
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002751 err = invalid_char(args[1]);
2752 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002753 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2754 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002755 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002756 }
2757
Willy Tarreau8f50b682015-05-26 11:45:02 +02002758 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2759 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002760 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2761 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2762 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002763 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002764 }
2765
Vincent Bernat02779b62016-04-03 13:48:43 +02002766 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002767 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002768 err_code |= ERR_ALERT | ERR_ABORT;
2769 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002770 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002771
Willy Tarreau97cb7802010-01-03 20:23:58 +01002772 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002773 curproxy->next = proxies_list;
2774 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002775 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2776 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002777 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002778 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002779 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002780 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002781
William Lallemand6e62fb62015-04-28 16:55:23 +02002782 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2783 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002784 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002785 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002786 }
2787
2788 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002789 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002790 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002791
Willy Tarreaubaaee002006-06-26 02:48:02 +02002792 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002793 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002794 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002795 curproxy->no_options = defproxy.no_options;
2796 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002797 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002798 curproxy->except_net = defproxy.except_net;
2799 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002800 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002801 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002802
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002803 if (defproxy.fwdfor_hdr_len) {
2804 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2805 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2806 }
2807
Willy Tarreaub86db342009-11-30 11:50:16 +01002808 if (defproxy.orgto_hdr_len) {
2809 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2810 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2811 }
2812
Mark Lamourinec2247f02012-01-04 13:02:01 -05002813 if (defproxy.server_id_hdr_len) {
2814 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2815 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2816 }
2817
Willy Tarreau977b8e42006-12-29 14:19:17 +01002818 if (curproxy->cap & PR_CAP_FE) {
2819 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002820 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002821 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002822
2823 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002824 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2825 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002826
2827 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2828 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002829
Willy Tarreau977b8e42006-12-29 14:19:17 +01002830 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002831 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002832 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002833 curproxy->fullconn = defproxy.fullconn;
2834 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002835 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002836 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002837
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002838 if (defproxy.check_req) {
2839 curproxy->check_req = calloc(1, defproxy.check_len);
2840 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2841 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002842 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002843
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002844 if (defproxy.expect_str) {
2845 curproxy->expect_str = strdup(defproxy.expect_str);
2846 if (defproxy.expect_regex) {
2847 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002848 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2849 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002850 }
2851 }
2852
Willy Tarreau67402132012-05-31 20:40:20 +02002853 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002854 if (defproxy.cookie_name)
2855 curproxy->cookie_name = strdup(defproxy.cookie_name);
2856 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002857
2858 if (defproxy.dyncookie_key)
2859 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002860 if (defproxy.cookie_domain)
2861 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002862
Willy Tarreau31936852010-10-06 16:59:56 +02002863 if (defproxy.cookie_maxidle)
2864 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2865
2866 if (defproxy.cookie_maxlife)
2867 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2868
Emeric Brun647caf12009-06-30 17:57:00 +02002869 if (defproxy.rdp_cookie_name)
2870 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2871 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2872
Willy Tarreau01732802007-11-01 22:48:15 +01002873 if (defproxy.url_param_name)
2874 curproxy->url_param_name = strdup(defproxy.url_param_name);
2875 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002876
Benoitaffb4812009-03-25 13:02:10 +01002877 if (defproxy.hh_name)
2878 curproxy->hh_name = strdup(defproxy.hh_name);
2879 curproxy->hh_len = defproxy.hh_len;
2880 curproxy->hh_match_domain = defproxy.hh_match_domain;
2881
Willy Tarreauef9a3602012-12-08 22:29:20 +01002882 if (defproxy.conn_src.iface_name)
2883 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2884 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002885 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002886#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002887 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002888#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002889 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002890 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002891
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002892 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002893 if (defproxy.capture_name)
2894 curproxy->capture_name = strdup(defproxy.capture_name);
2895 curproxy->capture_namelen = defproxy.capture_namelen;
2896 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002897 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002898
Willy Tarreau977b8e42006-12-29 14:19:17 +01002899 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002900 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002901 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002902 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002903 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002904 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002905 curproxy->mon_net = defproxy.mon_net;
2906 curproxy->mon_mask = defproxy.mon_mask;
2907 if (defproxy.monitor_uri)
2908 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2909 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002910 if (defproxy.defbe.name)
2911 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002912
2913 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002914 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2915 if (curproxy->conf.logformat_string &&
2916 curproxy->conf.logformat_string != default_http_log_format &&
2917 curproxy->conf.logformat_string != default_tcp_log_format &&
2918 curproxy->conf.logformat_string != clf_http_log_format)
2919 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2920
2921 if (defproxy.conf.lfs_file) {
2922 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2923 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2924 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002925
2926 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2927 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2928 if (curproxy->conf.logformat_sd_string &&
2929 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2930 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2931
2932 if (defproxy.conf.lfsd_file) {
2933 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2934 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2935 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002936 }
2937
2938 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002939 curproxy->timeout.connect = defproxy.timeout.connect;
2940 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002941 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002942 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002943 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002944 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002945 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002946 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002947 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002948 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002949 }
2950
Willy Tarreaubaaee002006-06-26 02:48:02 +02002951 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002952 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002953
2954 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002955 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002956 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002957 memcpy(node, tmplogsrv, sizeof(struct logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02002958 LIST_INIT(&node->list);
2959 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2960 }
2961
Willy Tarreau62a61232013-04-12 18:13:46 +02002962 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2963 if (curproxy->conf.uniqueid_format_string)
2964 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2965
Dragan Dosen43885c72015-10-01 13:18:13 +02002966 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002967
Willy Tarreau62a61232013-04-12 18:13:46 +02002968 if (defproxy.conf.uif_file) {
2969 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2970 curproxy->conf.uif_line = defproxy.conf.uif_line;
2971 }
William Lallemanda73203e2012-03-12 12:48:57 +01002972
2973 /* copy default header unique id */
2974 if (defproxy.header_unique_id)
2975 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2976
William Lallemand82fe75c2012-10-23 10:25:10 +02002977 /* default compression options */
2978 if (defproxy.comp != NULL) {
2979 curproxy->comp = calloc(1, sizeof(struct comp));
2980 curproxy->comp->algos = defproxy.comp->algos;
2981 curproxy->comp->types = defproxy.comp->types;
2982 }
2983
Willy Tarreaubaaee002006-06-26 02:48:02 +02002984 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002985 curproxy->conf.used_listener_id = EB_ROOT;
2986 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002987
Simon Horman98637e52014-06-20 12:30:16 +09002988 if (defproxy.check_path)
2989 curproxy->check_path = strdup(defproxy.check_path);
2990 if (defproxy.check_command)
2991 curproxy->check_command = strdup(defproxy.check_command);
2992
Simon Horman9dc49962015-01-30 11:22:59 +09002993 if (defproxy.email_alert.mailers.name)
2994 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
2995 if (defproxy.email_alert.from)
2996 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
2997 if (defproxy.email_alert.to)
2998 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
2999 if (defproxy.email_alert.myhostname)
3000 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003001 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003002 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003003
Willy Tarreau93893792009-07-23 13:19:11 +02003004 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003005 }
3006 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3007 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003008 /* FIXME-20070101: we should do this too at the end of the
3009 * config parsing to free all default values.
3010 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003011 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3012 err_code |= ERR_ABORT;
3013 goto out;
3014 }
3015
Willy Tarreaua534fea2008-08-03 12:19:50 +02003016 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003017 free(defproxy.check_command);
3018 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003019 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003020 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003021 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003022 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003023 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003024 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003025 free(defproxy.capture_name);
3026 free(defproxy.monitor_uri);
3027 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003028 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003029 free(defproxy.fwdfor_hdr_name);
3030 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003031 free(defproxy.orgto_hdr_name);
3032 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003033 free(defproxy.server_id_hdr_name);
3034 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003035 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003036 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003037 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003038 free(defproxy.expect_regex);
3039 defproxy.expect_regex = NULL;
3040 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003041
Willy Tarreau62a61232013-04-12 18:13:46 +02003042 if (defproxy.conf.logformat_string != default_http_log_format &&
3043 defproxy.conf.logformat_string != default_tcp_log_format &&
3044 defproxy.conf.logformat_string != clf_http_log_format)
3045 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003046
Willy Tarreau62a61232013-04-12 18:13:46 +02003047 free(defproxy.conf.uniqueid_format_string);
3048 free(defproxy.conf.lfs_file);
3049 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003050 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003051 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003052
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003053 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3054 free(defproxy.conf.logformat_sd_string);
3055 free(defproxy.conf.lfsd_file);
3056
Willy Tarreaua534fea2008-08-03 12:19:50 +02003057 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003058 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003059
Willy Tarreaubaaee002006-06-26 02:48:02 +02003060 /* we cannot free uri_auth because it might already be used */
3061 init_default_instance();
3062 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003063 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3064 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003065 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003066 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003067 }
3068 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003069 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003070 err_code |= ERR_ALERT | ERR_FATAL;
3071 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003072 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003073
3074 /* update the current file and line being parsed */
3075 curproxy->conf.args.file = curproxy->conf.file;
3076 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003077
3078 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003079 if (!strcmp(args[0], "server") ||
3080 !strcmp(args[0], "default-server") ||
3081 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003082 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3083 if (err_code & ERR_FATAL)
3084 goto out;
3085 }
3086 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003087 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003088 int cur_arg;
3089
Willy Tarreaubaaee002006-06-26 02:48:02 +02003090 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003091 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003092 err_code |= ERR_ALERT | ERR_FATAL;
3093 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003094 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003095 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003096 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003097
Willy Tarreau24709282013-03-10 21:32:12 +01003098 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003099 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3100 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003101 err_code |= ERR_ALERT | ERR_FATAL;
3102 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003103 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003104
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003105 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003106
3107 /* use default settings for unix sockets */
3108 bind_conf->ux.uid = global.unix_bind.ux.uid;
3109 bind_conf->ux.gid = global.unix_bind.ux.gid;
3110 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003111
3112 /* NOTE: the following line might create several listeners if there
3113 * are comma-separated IPs or port ranges. So all further processing
3114 * will have to be applied to all listeners created after last_listen.
3115 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003116 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3117 if (errmsg && *errmsg) {
3118 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003119 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003120 }
3121 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003122 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3123 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003124 err_code |= ERR_ALERT | ERR_FATAL;
3125 goto out;
3126 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003127
Willy Tarreau4348fad2012-09-20 16:48:07 +02003128 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3129 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003130 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003131 }
3132
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003133 cur_arg = 2;
3134 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003135 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003136 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003137 char *err;
3138
Willy Tarreau26982662012-09-12 23:17:10 +02003139 kw = bind_find_kw(args[cur_arg]);
3140 if (kw) {
3141 char *err = NULL;
3142 int code;
3143
3144 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003145 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3146 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003147 cur_arg += 1 + kw->skip ;
3148 err_code |= ERR_ALERT | ERR_FATAL;
3149 goto out;
3150 }
3151
Willy Tarreau4348fad2012-09-20 16:48:07 +02003152 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003153 err_code |= code;
3154
3155 if (code) {
3156 if (err && *err) {
3157 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003158 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003159 }
3160 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003161 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3162 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003163 if (code & ERR_FATAL) {
3164 free(err);
3165 cur_arg += 1 + kw->skip;
3166 goto out;
3167 }
3168 }
3169 free(err);
3170 cur_arg += 1 + kw->skip;
3171 continue;
3172 }
3173
Willy Tarreau8638f482012-09-18 18:01:17 +02003174 err = NULL;
3175 if (!bind_dumped) {
3176 bind_dump_kws(&err);
3177 indent_msg(&err, 4);
3178 bind_dumped = 1;
3179 }
3180
Christopher Faulet767a84b2017-11-24 16:50:31 +01003181 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3182 file, linenum, args[0], args[1], args[cur_arg],
3183 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003184 free(err);
3185
Willy Tarreau93893792009-07-23 13:19:11 +02003186 err_code |= ERR_ALERT | ERR_FATAL;
3187 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003188 }
Willy Tarreau93893792009-07-23 13:19:11 +02003189 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003190 }
3191 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003192 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003193 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3194 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003195 err_code |= ERR_ALERT | ERR_FATAL;
3196 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003197 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003198 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003199 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003200
Willy Tarreaubaaee002006-06-26 02:48:02 +02003201 /* flush useless bits */
3202 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003203 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003204 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003205 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003206 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003207 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003208
William Lallemanddf1425a2015-04-28 20:17:49 +02003209 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3210 goto out;
3211
Willy Tarreau1c47f852006-07-09 08:22:27 +02003212 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003213 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3214 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003215 err_code |= ERR_ALERT | ERR_FATAL;
3216 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003217 }
3218
Willy Tarreaua534fea2008-08-03 12:19:50 +02003219 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003220 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003221 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003222 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003223 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3224
Willy Tarreau93893792009-07-23 13:19:11 +02003225 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003226 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003227 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003228 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3229 goto out;
3230
Willy Tarreaubaaee002006-06-26 02:48:02 +02003231 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3232 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3233 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3234 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003235 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003236 err_code |= ERR_ALERT | ERR_FATAL;
3237 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003238 }
3239 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003240 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003241 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003242
3243 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003244 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003245 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003246 err_code |= ERR_ALERT | ERR_FATAL;
3247 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003248 }
3249
William Lallemanddf1425a2015-04-28 20:17:49 +02003250 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3251 goto out;
3252
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003253 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003254 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3255 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003256 err_code |= ERR_ALERT | ERR_FATAL;
3257 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003258 }
3259
3260 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003261 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003262 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003263
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003264 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003265 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3266 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003267 err_code |= ERR_ALERT | ERR_FATAL;
3268 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003269 }
3270
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003271 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3272 if (node) {
3273 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003274 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3275 file, linenum, proxy_type_str(curproxy), curproxy->id,
3276 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003277 err_code |= ERR_ALERT | ERR_FATAL;
3278 goto out;
3279 }
3280 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003281 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003282 else if (!strcmp(args[0], "description")) {
3283 int i, len=0;
3284 char *d;
3285
Cyril Bonté99ed3272010-01-24 23:29:44 +01003286 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003287 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003288 file, linenum, args[0]);
3289 err_code |= ERR_ALERT | ERR_FATAL;
3290 goto out;
3291 }
3292
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003293 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003294 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3295 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003296 return -1;
3297 }
3298
Willy Tarreau348acfe2014-04-14 15:00:39 +02003299 for (i = 1; *args[i]; i++)
3300 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003301
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003302 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003303 curproxy->desc = d;
3304
Willy Tarreau348acfe2014-04-14 15:00:39 +02003305 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3306 for (i = 2; *args[i]; i++)
3307 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003308
3309 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003310 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003311 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3312 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003313 curproxy->state = PR_STSTOPPED;
3314 }
3315 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003316 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3317 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003318 curproxy->state = PR_STNEW;
3319 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003320 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3321 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003322 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003323
3324 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003325 if (strcmp(args[cur_arg], "all") == 0) {
3326 set = 0;
3327 break;
3328 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003329 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003330 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003331 err_code |= ERR_ALERT | ERR_FATAL;
3332 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003333 }
3334 cur_arg++;
3335 }
3336 curproxy->bind_proc = set;
3337 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003338 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003339 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003340 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003341 err_code |= ERR_ALERT | ERR_FATAL;
3342 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003343 }
3344
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003345 err = invalid_char(args[1]);
3346 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003347 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3348 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003349 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003350 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003351 }
3352
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003353 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003354 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3355 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003356 err_code |= ERR_ALERT | ERR_FATAL;
3357 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003358 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003359 }
3360 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3361
3362 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3363 err_code |= ERR_WARN;
3364
3365 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003366 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3367 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003368 err_code |= ERR_ALERT | ERR_FATAL;
3369 goto out;
3370 }
3371 free(curproxy->dyncookie_key);
3372 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003373 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003374 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3375 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003376
Willy Tarreau977b8e42006-12-29 14:19:17 +01003377 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003378 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003379
Willy Tarreaubaaee002006-06-26 02:48:02 +02003380 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003381 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3382 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003383 err_code |= ERR_ALERT | ERR_FATAL;
3384 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003385 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003386
Willy Tarreau67402132012-05-31 20:40:20 +02003387 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003388 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003389 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003390 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003391 curproxy->cookie_name = strdup(args[1]);
3392 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003393
Willy Tarreaubaaee002006-06-26 02:48:02 +02003394 cur_arg = 2;
3395 while (*(args[cur_arg])) {
3396 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003397 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003398 }
3399 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003400 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003401 }
3402 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003403 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003404 }
3405 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003406 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003407 }
3408 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003409 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003410 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003411 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003412 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003413 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003414 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003415 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003416 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003417 else if (!strcmp(args[cur_arg], "httponly")) {
3418 curproxy->ck_opts |= PR_CK_HTTPONLY;
3419 }
3420 else if (!strcmp(args[cur_arg], "secure")) {
3421 curproxy->ck_opts |= PR_CK_SECURE;
3422 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003423 else if (!strcmp(args[cur_arg], "domain")) {
3424 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003425 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3426 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003427 err_code |= ERR_ALERT | ERR_FATAL;
3428 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003429 }
3430
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003431 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003432 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003433 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3434 " dots nor does not start with a dot."
3435 " RFC forbids it, this configuration may not work properly.\n",
3436 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003437 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003438 }
3439
3440 err = invalid_domainchar(args[cur_arg + 1]);
3441 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003442 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3443 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003444 err_code |= ERR_ALERT | ERR_FATAL;
3445 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003446 }
3447
Willy Tarreau68a897b2009-12-03 23:28:34 +01003448 if (!curproxy->cookie_domain) {
3449 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3450 } else {
3451 /* one domain was already specified, add another one by
3452 * building the string which will be returned along with
3453 * the cookie.
3454 */
3455 char *new_ptr;
3456 int new_len = strlen(curproxy->cookie_domain) +
3457 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3458 new_ptr = malloc(new_len);
3459 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3460 free(curproxy->cookie_domain);
3461 curproxy->cookie_domain = new_ptr;
3462 }
Willy Tarreau31936852010-10-06 16:59:56 +02003463 cur_arg++;
3464 }
3465 else if (!strcmp(args[cur_arg], "maxidle")) {
3466 unsigned int maxidle;
3467 const char *res;
3468
3469 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003470 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3471 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003472 err_code |= ERR_ALERT | ERR_FATAL;
3473 goto out;
3474 }
3475
3476 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3477 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003478 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3479 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003480 err_code |= ERR_ALERT | ERR_FATAL;
3481 goto out;
3482 }
3483 curproxy->cookie_maxidle = maxidle;
3484 cur_arg++;
3485 }
3486 else if (!strcmp(args[cur_arg], "maxlife")) {
3487 unsigned int maxlife;
3488 const char *res;
3489
3490 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003491 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3492 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003493 err_code |= ERR_ALERT | ERR_FATAL;
3494 goto out;
3495 }
3496
3497 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3498 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003499 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3500 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003501 err_code |= ERR_ALERT | ERR_FATAL;
3502 goto out;
3503 }
3504 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003505 cur_arg++;
3506 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003507 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003508
3509 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3510 err_code |= ERR_WARN;
3511 curproxy->ck_opts |= PR_CK_DYNAMIC;
3512 }
3513
Willy Tarreaubaaee002006-06-26 02:48:02 +02003514 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003515 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3516 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003517 err_code |= ERR_ALERT | ERR_FATAL;
3518 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003519 }
3520 cur_arg++;
3521 }
Willy Tarreau67402132012-05-31 20:40:20 +02003522 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003523 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3524 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003525 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003526 }
3527
Willy Tarreau67402132012-05-31 20:40:20 +02003528 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003529 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3530 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003531 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003532 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003533
Willy Tarreau67402132012-05-31 20:40:20 +02003534 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003535 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3536 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003537 err_code |= ERR_ALERT | ERR_FATAL;
3538 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003539 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003540 else if (!strcmp(args[0], "email-alert")) {
3541 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003542 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3543 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003544 err_code |= ERR_ALERT | ERR_FATAL;
3545 goto out;
3546 }
3547
3548 if (!strcmp(args[1], "from")) {
3549 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003550 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3551 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003552 err_code |= ERR_ALERT | ERR_FATAL;
3553 goto out;
3554 }
3555 free(curproxy->email_alert.from);
3556 curproxy->email_alert.from = strdup(args[2]);
3557 }
3558 else if (!strcmp(args[1], "mailers")) {
3559 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003560 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3561 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003562 err_code |= ERR_ALERT | ERR_FATAL;
3563 goto out;
3564 }
3565 free(curproxy->email_alert.mailers.name);
3566 curproxy->email_alert.mailers.name = strdup(args[2]);
3567 }
3568 else if (!strcmp(args[1], "myhostname")) {
3569 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003570 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3571 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003572 err_code |= ERR_ALERT | ERR_FATAL;
3573 goto out;
3574 }
3575 free(curproxy->email_alert.myhostname);
3576 curproxy->email_alert.myhostname = strdup(args[2]);
3577 }
Simon Horman64e34162015-02-06 11:11:57 +09003578 else if (!strcmp(args[1], "level")) {
3579 curproxy->email_alert.level = get_log_level(args[2]);
3580 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003581 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3582 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003583 err_code |= ERR_ALERT | ERR_FATAL;
3584 goto out;
3585 }
3586 }
Simon Horman9dc49962015-01-30 11:22:59 +09003587 else if (!strcmp(args[1], "to")) {
3588 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003589 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3590 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003591 err_code |= ERR_ALERT | ERR_FATAL;
3592 goto out;
3593 }
3594 free(curproxy->email_alert.to);
3595 curproxy->email_alert.to = strdup(args[2]);
3596 }
3597 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003598 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3599 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003600 err_code |= ERR_ALERT | ERR_FATAL;
3601 goto out;
3602 }
Simon Horman64e34162015-02-06 11:11:57 +09003603 /* Indicate that the email_alert is at least partially configured */
3604 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003605 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003606 else if (!strcmp(args[0], "external-check")) {
3607 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003608 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3609 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003610 err_code |= ERR_ALERT | ERR_FATAL;
3611 goto out;
3612 }
3613
3614 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003615 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003616 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003617 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003618 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3619 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003620 err_code |= ERR_ALERT | ERR_FATAL;
3621 goto out;
3622 }
3623 free(curproxy->check_command);
3624 curproxy->check_command = strdup(args[2]);
3625 }
3626 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003627 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003628 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003629 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003630 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3631 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003632 err_code |= ERR_ALERT | ERR_FATAL;
3633 goto out;
3634 }
3635 free(curproxy->check_path);
3636 curproxy->check_path = strdup(args[2]);
3637 }
3638 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003639 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3640 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003641 err_code |= ERR_ALERT | ERR_FATAL;
3642 goto out;
3643 }
3644 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003645 else if (!strcmp(args[0], "persist")) { /* persist */
3646 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003647 ha_alert("parsing [%s:%d] : missing persist method.\n",
3648 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003649 err_code |= ERR_ALERT | ERR_FATAL;
3650 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003651 }
3652
3653 if (!strncmp(args[1], "rdp-cookie", 10)) {
3654 curproxy->options2 |= PR_O2_RDPC_PRST;
3655
Emeric Brunb982a3d2010-01-04 15:45:53 +01003656 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003657 const char *beg, *end;
3658
3659 beg = args[1] + 11;
3660 end = strchr(beg, ')');
3661
William Lallemanddf1425a2015-04-28 20:17:49 +02003662 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3663 goto out;
3664
Emeric Brun647caf12009-06-30 17:57:00 +02003665 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003666 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3667 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003668 err_code |= ERR_ALERT | ERR_FATAL;
3669 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003670 }
3671
3672 free(curproxy->rdp_cookie_name);
3673 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3674 curproxy->rdp_cookie_len = end-beg;
3675 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003676 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003677 free(curproxy->rdp_cookie_name);
3678 curproxy->rdp_cookie_name = strdup("msts");
3679 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3680 }
3681 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003682 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3683 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003684 err_code |= ERR_ALERT | ERR_FATAL;
3685 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003686 }
3687 }
3688 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003689 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3690 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003691 err_code |= ERR_ALERT | ERR_FATAL;
3692 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003693 }
3694 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003695 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003696 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 +02003697 err_code |= ERR_ALERT | ERR_FATAL;
3698 goto out;
3699 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003700 else if (!strcmp(args[0], "load-server-state-from-file")) {
3701 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3702 err_code |= ERR_WARN;
3703 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3704 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3705 }
3706 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3707 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3708 }
3709 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3710 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3711 }
3712 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003713 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3714 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003715 err_code |= ERR_ALERT | ERR_FATAL;
3716 goto out;
3717 }
3718 }
3719 else if (!strcmp(args[0], "server-state-file-name")) {
3720 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3721 err_code |= ERR_WARN;
3722 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003723 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3724 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003725 err_code |= ERR_ALERT | ERR_FATAL;
3726 goto out;
3727 }
3728 else if (!strcmp(args[1], "use-backend-name"))
3729 curproxy->server_state_file_name = strdup(curproxy->id);
3730 else
3731 curproxy->server_state_file_name = strdup(args[1]);
3732 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003733 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003734 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003735 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003736
Willy Tarreaubaaee002006-06-26 02:48:02 +02003737 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003738 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003739 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 +01003740 err_code |= ERR_ALERT | ERR_FATAL;
3741 goto out;
3742 }
3743
William Lallemand1a748ae2015-05-19 16:37:23 +02003744 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3745 goto out;
3746
Willy Tarreaubaaee002006-06-26 02:48:02 +02003747 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003748 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3749 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003750 err_code |= ERR_ALERT | ERR_FATAL;
3751 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003752 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003753 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003754 curproxy->capture_name = strdup(args[2]);
3755 curproxy->capture_namelen = strlen(curproxy->capture_name);
3756 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003757 curproxy->to_log |= LW_COOKIE;
3758 }
3759 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3760 struct cap_hdr *hdr;
3761
3762 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003763 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 +02003764 err_code |= ERR_ALERT | ERR_FATAL;
3765 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003766 }
3767
William Lallemand1a748ae2015-05-19 16:37:23 +02003768 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3769 goto out;
3770
Willy Tarreaubaaee002006-06-26 02:48:02 +02003771 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003772 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3773 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003774 err_code |= ERR_ALERT | ERR_FATAL;
3775 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003776 }
3777
Vincent Bernat02779b62016-04-03 13:48:43 +02003778 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003779 hdr->next = curproxy->req_cap;
3780 hdr->name = strdup(args[3]);
3781 hdr->namelen = strlen(args[3]);
3782 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003783 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003784 hdr->index = curproxy->nb_req_cap++;
3785 curproxy->req_cap = hdr;
3786 curproxy->to_log |= LW_REQHDR;
3787 }
3788 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3789 struct cap_hdr *hdr;
3790
3791 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003792 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 +02003793 err_code |= ERR_ALERT | ERR_FATAL;
3794 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003795 }
3796
William Lallemand1a748ae2015-05-19 16:37:23 +02003797 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3798 goto out;
3799
Willy Tarreaubaaee002006-06-26 02:48:02 +02003800 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003801 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3802 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003803 err_code |= ERR_ALERT | ERR_FATAL;
3804 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003805 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003806 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003807 hdr->next = curproxy->rsp_cap;
3808 hdr->name = strdup(args[3]);
3809 hdr->namelen = strlen(args[3]);
3810 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003811 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003812 hdr->index = curproxy->nb_rsp_cap++;
3813 curproxy->rsp_cap = hdr;
3814 curproxy->to_log |= LW_RSPHDR;
3815 }
3816 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003817 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3818 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003819 err_code |= ERR_ALERT | ERR_FATAL;
3820 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003821 }
3822 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003823 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003824 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003825 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003826
William Lallemanddf1425a2015-04-28 20:17:49 +02003827 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3828 goto out;
3829
Willy Tarreaubaaee002006-06-26 02:48:02 +02003830 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003831 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3832 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003833 err_code |= ERR_ALERT | ERR_FATAL;
3834 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003835 }
3836 curproxy->conn_retries = atol(args[1]);
3837 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003838 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003839 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003840
3841 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003842 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003843 err_code |= ERR_ALERT | ERR_FATAL;
3844 goto out;
3845 }
3846
Willy Tarreau20b0de52012-12-24 15:45:22 +01003847 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003848 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003849 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3850 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3851 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3852 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003853 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3854 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003855 err_code |= ERR_WARN;
3856 }
3857
Willy Tarreauff011f22011-01-06 17:51:27 +01003858 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003859
Willy Tarreauff011f22011-01-06 17:51:27 +01003860 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003861 err_code |= ERR_ALERT | ERR_ABORT;
3862 goto out;
3863 }
3864
Willy Tarreau5002f572014-04-23 01:32:02 +02003865 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003866 err_code |= warnif_cond_conflicts(rule->cond,
3867 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3868 file, linenum);
3869
Willy Tarreauff011f22011-01-06 17:51:27 +01003870 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003871 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003872 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003873 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003874
3875 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003876 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003877 err_code |= ERR_ALERT | ERR_FATAL;
3878 goto out;
3879 }
3880
3881 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003882 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003883 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3884 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003885 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3886 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003887 err_code |= ERR_WARN;
3888 }
3889
3890 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3891
3892 if (!rule) {
3893 err_code |= ERR_ALERT | ERR_ABORT;
3894 goto out;
3895 }
3896
3897 err_code |= warnif_cond_conflicts(rule->cond,
3898 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3899 file, linenum);
3900
3901 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3902 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003903 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3904 /* set the header name and length into the proxy structure */
3905 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3906 err_code |= ERR_WARN;
3907
3908 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003909 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3910 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003911 err_code |= ERR_ALERT | ERR_FATAL;
3912 goto out;
3913 }
3914
3915 /* set the desired header name */
3916 free(curproxy->server_id_hdr_name);
3917 curproxy->server_id_hdr_name = strdup(args[1]);
3918 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3919 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003920 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003921 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003922
Willy Tarreaub099aca2008-10-12 17:26:37 +02003923 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003924 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003925 err_code |= ERR_ALERT | ERR_FATAL;
3926 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003927 }
3928
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003929 /* emulate "block" using "http-request block". Since these rules are supposed to
3930 * be processed before all http-request rules, we put them into their own list
3931 * and will insert them at the end.
3932 */
3933 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3934 if (!rule) {
3935 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003936 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003937 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003938 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3939 err_code |= warnif_cond_conflicts(rule->cond,
3940 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3941 file, linenum);
3942 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003943
3944 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003945 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 +02003946
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003947 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003948 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003949 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003950
Cyril Bonté99ed3272010-01-24 23:29:44 +01003951 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003952 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003953 err_code |= ERR_ALERT | ERR_FATAL;
3954 goto out;
3955 }
3956
Willy Tarreaube4653b2015-05-28 15:26:58 +02003957 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003958 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3959 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003960 err_code |= ERR_ALERT | ERR_FATAL;
3961 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003962 }
3963
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003964 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003965 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003966 err_code |= warnif_cond_conflicts(rule->cond,
3967 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3968 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003969 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003970 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003971 struct switching_rule *rule;
3972
Willy Tarreaub099aca2008-10-12 17:26:37 +02003973 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003974 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003975 err_code |= ERR_ALERT | ERR_FATAL;
3976 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003977 }
3978
Willy Tarreau55ea7572007-06-17 19:56:27 +02003979 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003980 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003981
3982 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003983 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003984 err_code |= ERR_ALERT | ERR_FATAL;
3985 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003986 }
3987
Willy Tarreauf51658d2014-04-23 01:21:56 +02003988 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003989 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003990 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3991 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02003992 err_code |= ERR_ALERT | ERR_FATAL;
3993 goto out;
3994 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003995
Willy Tarreauf51658d2014-04-23 01:21:56 +02003996 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02003997 }
Willy Tarreau4f862642017-02-28 09:34:39 +01003998 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003999 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
4000 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004001 err_code |= ERR_ALERT | ERR_FATAL;
4002 goto out;
4003 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004004
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004005 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004006 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004007 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004008 goto out;
4009 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004010 rule->cond = cond;
4011 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004012 rule->line = linenum;
4013 rule->file = strdup(file);
4014 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004015 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004016 goto out;
4017 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004018 LIST_INIT(&rule->list);
4019 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4020 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004021 else if (strcmp(args[0], "use-server") == 0) {
4022 struct server_rule *rule;
4023
4024 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004025 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004026 err_code |= ERR_ALERT | ERR_FATAL;
4027 goto out;
4028 }
4029
4030 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4031 err_code |= ERR_WARN;
4032
4033 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004034 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004035 err_code |= ERR_ALERT | ERR_FATAL;
4036 goto out;
4037 }
4038
4039 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004040 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4041 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004042 err_code |= ERR_ALERT | ERR_FATAL;
4043 goto out;
4044 }
4045
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004046 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004047 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4048 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004049 err_code |= ERR_ALERT | ERR_FATAL;
4050 goto out;
4051 }
4052
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004053 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004054
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004055 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004056 rule->cond = cond;
4057 rule->srv.name = strdup(args[1]);
4058 LIST_INIT(&rule->list);
4059 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4060 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4061 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004062 else if ((!strcmp(args[0], "force-persist")) ||
4063 (!strcmp(args[0], "ignore-persist"))) {
4064 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004065
4066 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004067 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004068 err_code |= ERR_ALERT | ERR_FATAL;
4069 goto out;
4070 }
4071
4072 if (warnifnotcap(curproxy, PR_CAP_FE|PR_CAP_BE, file, linenum, args[0], NULL))
4073 err_code |= ERR_WARN;
4074
Willy Tarreauef6494c2010-01-28 17:12:36 +01004075 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004076 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4077 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004078 err_code |= ERR_ALERT | ERR_FATAL;
4079 goto out;
4080 }
4081
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004082 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004083 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4084 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004085 err_code |= ERR_ALERT | ERR_FATAL;
4086 goto out;
4087 }
4088
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004089 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4090 * where force-persist is applied.
4091 */
4092 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004093
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004094 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004095 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004096 if (!strcmp(args[0], "force-persist")) {
4097 rule->type = PERSIST_TYPE_FORCE;
4098 } else {
4099 rule->type = PERSIST_TYPE_IGNORE;
4100 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004101 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004102 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004103 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004104 else if (!strcmp(args[0], "stick-table")) {
4105 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004106 struct proxy *other;
4107
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004108 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004109 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004110 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4111 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004112 err_code |= ERR_ALERT | ERR_FATAL;
4113 goto out;
4114 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004115
Emeric Brun32da3c42010-09-23 18:39:19 +02004116 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004117 curproxy->table.type = (unsigned int)-1;
4118 while (*args[myidx]) {
4119 const char *err;
4120
4121 if (strcmp(args[myidx], "size") == 0) {
4122 myidx++;
4123 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004124 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4125 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004126 err_code |= ERR_ALERT | ERR_FATAL;
4127 goto out;
4128 }
4129 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004130 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4131 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004132 err_code |= ERR_ALERT | ERR_FATAL;
4133 goto out;
4134 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004135 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004136 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004137 else if (strcmp(args[myidx], "peers") == 0) {
4138 myidx++;
Godbach50523162013-12-11 19:48:57 +08004139 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004140 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4141 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004142 err_code |= ERR_ALERT | ERR_FATAL;
4143 goto out;
Godbach50523162013-12-11 19:48:57 +08004144 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004145 curproxy->table.peers.name = strdup(args[myidx++]);
4146 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004147 else if (strcmp(args[myidx], "expire") == 0) {
4148 myidx++;
4149 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004150 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4151 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004152 err_code |= ERR_ALERT | ERR_FATAL;
4153 goto out;
4154 }
4155 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4156 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004157 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4158 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004159 err_code |= ERR_ALERT | ERR_FATAL;
4160 goto out;
4161 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004162 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004163 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4164 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004165 err_code |= ERR_ALERT | ERR_FATAL;
4166 goto out;
4167 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004168 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004169 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004170 }
4171 else if (strcmp(args[myidx], "nopurge") == 0) {
4172 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004173 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004174 }
4175 else if (strcmp(args[myidx], "type") == 0) {
4176 myidx++;
4177 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004178 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4179 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004180 err_code |= ERR_ALERT | ERR_FATAL;
4181 goto out;
4182 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004183 /* myidx already points to next arg */
4184 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004185 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004186 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004187 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004188
4189 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004190 nw = args[myidx];
4191 while (*nw) {
4192 /* the "store" keyword supports a comma-separated list */
4193 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004194 sa = NULL; /* store arg */
4195 while (*nw && *nw != ',') {
4196 if (*nw == '(') {
4197 *nw = 0;
4198 sa = ++nw;
4199 while (*nw != ')') {
4200 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004201 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4202 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004203 err_code |= ERR_ALERT | ERR_FATAL;
4204 goto out;
4205 }
4206 nw++;
4207 }
4208 *nw = '\0';
4209 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004210 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004211 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004212 if (*nw)
4213 *nw++ = '\0';
4214 type = stktable_get_data_type(cw);
4215 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004216 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4217 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004218 err_code |= ERR_ALERT | ERR_FATAL;
4219 goto out;
4220 }
Willy Tarreauac782882010-06-20 10:41:54 +02004221
4222 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4223 switch (err) {
4224 case PE_NONE: break;
4225 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004226 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4227 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004228 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004229 break;
4230
4231 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004232 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4233 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004234 err_code |= ERR_ALERT | ERR_FATAL;
4235 goto out;
4236
4237 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004238 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4239 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004240 err_code |= ERR_ALERT | ERR_FATAL;
4241 goto out;
4242
4243 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004244 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4245 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004246 err_code |= ERR_ALERT | ERR_FATAL;
4247 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004248 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004249 }
4250 myidx++;
4251 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004252 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004253 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4254 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004255 err_code |= ERR_ALERT | ERR_FATAL;
4256 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004257 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004258 }
4259
4260 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004261 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4262 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004263 err_code |= ERR_ALERT | ERR_FATAL;
4264 goto out;
4265 }
4266
4267 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004268 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4269 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004270 err_code |= ERR_ALERT | ERR_FATAL;
4271 goto out;
4272 }
4273 }
4274 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004275 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004276 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004277 int myidx = 0;
4278 const char *name = NULL;
4279 int flags;
4280
4281 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004282 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004283 err_code |= ERR_ALERT | ERR_FATAL;
4284 goto out;
4285 }
4286
4287 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4288 err_code |= ERR_WARN;
4289 goto out;
4290 }
4291
4292 myidx++;
4293 if ((strcmp(args[myidx], "store") == 0) ||
4294 (strcmp(args[myidx], "store-request") == 0)) {
4295 myidx++;
4296 flags = STK_IS_STORE;
4297 }
4298 else if (strcmp(args[myidx], "store-response") == 0) {
4299 myidx++;
4300 flags = STK_IS_STORE | STK_ON_RSP;
4301 }
4302 else if (strcmp(args[myidx], "match") == 0) {
4303 myidx++;
4304 flags = STK_IS_MATCH;
4305 }
4306 else if (strcmp(args[myidx], "on") == 0) {
4307 myidx++;
4308 flags = STK_IS_MATCH | STK_IS_STORE;
4309 }
4310 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004311 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004312 err_code |= ERR_ALERT | ERR_FATAL;
4313 goto out;
4314 }
4315
4316 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004317 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004318 err_code |= ERR_ALERT | ERR_FATAL;
4319 goto out;
4320 }
4321
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004322 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004323 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004324 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004325 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004326 err_code |= ERR_ALERT | ERR_FATAL;
4327 goto out;
4328 }
4329
4330 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004331 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004332 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4333 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004334 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004335 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004336 goto out;
4337 }
4338 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004339 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004340 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4341 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004342 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004343 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004344 goto out;
4345 }
4346 }
4347
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004348 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004349 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004350
Emeric Brunb982a3d2010-01-04 15:45:53 +01004351 if (strcmp(args[myidx], "table") == 0) {
4352 myidx++;
4353 name = args[myidx++];
4354 }
4355
Willy Tarreauef6494c2010-01-28 17:12:36 +01004356 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004357 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004358 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4359 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004360 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004361 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004362 goto out;
4363 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004364 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004365 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004366 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4367 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004368 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004369 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004370 goto out;
4371 }
Emeric Brun97679e72010-09-23 17:56:44 +02004372 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004373 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004374 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004375 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004376
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004377 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004378 rule->cond = cond;
4379 rule->expr = expr;
4380 rule->flags = flags;
4381 rule->table.name = name ? strdup(name) : NULL;
4382 LIST_INIT(&rule->list);
4383 if (flags & STK_ON_RSP)
4384 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4385 else
4386 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4387 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004388 else if (!strcmp(args[0], "stats")) {
4389 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4390 curproxy->uri_auth = NULL; /* we must detach from the default config */
4391
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004392 if (!*args[1]) {
4393 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004394 } else if (!strcmp(args[1], "admin")) {
4395 struct stats_admin_rule *rule;
4396
4397 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004398 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 +02004399 err_code |= ERR_ALERT | ERR_FATAL;
4400 goto out;
4401 }
4402
4403 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004404 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004405 err_code |= ERR_ALERT | ERR_ABORT;
4406 goto out;
4407 }
4408
4409 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004410 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4411 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004412 err_code |= ERR_ALERT | ERR_FATAL;
4413 goto out;
4414 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004415 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004416 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4417 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004418 err_code |= ERR_ALERT | ERR_FATAL;
4419 goto out;
4420 }
4421
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004422 err_code |= warnif_cond_conflicts(cond,
4423 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4424 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004425
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004426 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004427 rule->cond = cond;
4428 LIST_INIT(&rule->list);
4429 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004430 } else if (!strcmp(args[1], "uri")) {
4431 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004432 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004433 err_code |= ERR_ALERT | ERR_FATAL;
4434 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004435 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004436 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004437 err_code |= ERR_ALERT | ERR_ABORT;
4438 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004439 }
4440 } else if (!strcmp(args[1], "realm")) {
4441 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004442 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004443 err_code |= ERR_ALERT | ERR_FATAL;
4444 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004445 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004446 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004447 err_code |= ERR_ALERT | ERR_ABORT;
4448 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004449 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004450 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004451 unsigned interval;
4452
4453 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4454 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004455 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4456 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004457 err_code |= ERR_ALERT | ERR_FATAL;
4458 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004459 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004460 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004461 err_code |= ERR_ALERT | ERR_ABORT;
4462 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004463 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004464 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004465 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004466
4467 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004468 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004469 err_code |= ERR_ALERT | ERR_FATAL;
4470 goto out;
4471 }
4472
4473 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004474 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004475 err_code |= ERR_ALERT | ERR_ABORT;
4476 goto out;
4477 }
4478
Willy Tarreauff011f22011-01-06 17:51:27 +01004479 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004480 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004481 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4482 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004483 err_code |= ERR_WARN;
4484 }
4485
Willy Tarreauff011f22011-01-06 17:51:27 +01004486 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004487
Willy Tarreauff011f22011-01-06 17:51:27 +01004488 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004489 err_code |= ERR_ALERT | ERR_ABORT;
4490 goto out;
4491 }
4492
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004493 err_code |= warnif_cond_conflicts(rule->cond,
4494 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4495 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004496 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004497
Willy Tarreaubaaee002006-06-26 02:48:02 +02004498 } else if (!strcmp(args[1], "auth")) {
4499 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004500 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004501 err_code |= ERR_ALERT | ERR_FATAL;
4502 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004503 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004504 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004505 err_code |= ERR_ALERT | ERR_ABORT;
4506 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004507 }
4508 } else if (!strcmp(args[1], "scope")) {
4509 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004510 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004511 err_code |= ERR_ALERT | ERR_FATAL;
4512 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004513 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004514 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004515 err_code |= ERR_ALERT | ERR_ABORT;
4516 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004517 }
4518 } else if (!strcmp(args[1], "enable")) {
4519 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004520 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004521 err_code |= ERR_ALERT | ERR_ABORT;
4522 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004523 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004524 } else if (!strcmp(args[1], "hide-version")) {
4525 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004526 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004527 err_code |= ERR_ALERT | ERR_ABORT;
4528 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004529 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004530 } else if (!strcmp(args[1], "show-legends")) {
4531 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004532 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004533 err_code |= ERR_ALERT | ERR_ABORT;
4534 goto out;
4535 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004536 } else if (!strcmp(args[1], "show-node")) {
4537
4538 if (*args[2]) {
4539 int i;
4540 char c;
4541
4542 for (i=0; args[2][i]; i++) {
4543 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004544 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4545 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004546 break;
4547 }
4548
4549 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004550 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4551 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4552 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004553 err_code |= ERR_ALERT | ERR_FATAL;
4554 goto out;
4555 }
4556 }
4557
4558 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004559 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004560 err_code |= ERR_ALERT | ERR_ABORT;
4561 goto out;
4562 }
4563 } else if (!strcmp(args[1], "show-desc")) {
4564 char *desc = NULL;
4565
4566 if (*args[2]) {
4567 int i, len=0;
4568 char *d;
4569
Willy Tarreau348acfe2014-04-14 15:00:39 +02004570 for (i = 2; *args[i]; i++)
4571 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004572
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004573 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004574
Willy Tarreau348acfe2014-04-14 15:00:39 +02004575 d += snprintf(d, desc + len - d, "%s", args[2]);
4576 for (i = 3; *args[i]; i++)
4577 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004578 }
4579
4580 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004581 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4582 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004583 else {
4584 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4585 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004586 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004587 err_code |= ERR_ALERT | ERR_ABORT;
4588 goto out;
4589 }
4590 free(desc);
4591 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004592 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004593stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004594 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4595 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004596 err_code |= ERR_ALERT | ERR_FATAL;
4597 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004598 }
4599 }
4600 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004601 int optnum;
4602
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004603 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004604 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4605 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004606 err_code |= ERR_ALERT | ERR_FATAL;
4607 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004608 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004609
4610 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4611 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004612 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004613 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4614 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004615 err_code |= ERR_ALERT | ERR_FATAL;
4616 goto out;
4617 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004618 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4619 goto out;
4620
Willy Tarreau93893792009-07-23 13:19:11 +02004621 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4622 err_code |= ERR_WARN;
4623 goto out;
4624 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004625
Willy Tarreau3842f002009-06-14 11:39:52 +02004626 curproxy->no_options &= ~cfg_opts[optnum].val;
4627 curproxy->options &= ~cfg_opts[optnum].val;
4628
4629 switch (kwm) {
4630 case KWM_STD:
4631 curproxy->options |= cfg_opts[optnum].val;
4632 break;
4633 case KWM_NO:
4634 curproxy->no_options |= cfg_opts[optnum].val;
4635 break;
4636 case KWM_DEF: /* already cleared */
4637 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004638 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004639
Willy Tarreau93893792009-07-23 13:19:11 +02004640 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004641 }
4642 }
4643
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004644 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4645 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004646 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004647 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4648 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004649 err_code |= ERR_ALERT | ERR_FATAL;
4650 goto out;
4651 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004652 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4653 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004654 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4655 err_code |= ERR_WARN;
4656 goto out;
4657 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004658
Willy Tarreau3842f002009-06-14 11:39:52 +02004659 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4660 curproxy->options2 &= ~cfg_opts2[optnum].val;
4661
4662 switch (kwm) {
4663 case KWM_STD:
4664 curproxy->options2 |= cfg_opts2[optnum].val;
4665 break;
4666 case KWM_NO:
4667 curproxy->no_options2 |= cfg_opts2[optnum].val;
4668 break;
4669 case KWM_DEF: /* already cleared */
4670 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004671 }
Willy Tarreau93893792009-07-23 13:19:11 +02004672 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004673 }
4674 }
4675
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004676 /* HTTP options override each other. They can be cancelled using
4677 * "no option xxx" which only switches to default mode if the mode
4678 * was this one (useful for cancelling options set in defaults
4679 * sections).
4680 */
4681 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004682 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4683 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004684 if (kwm == KWM_STD) {
4685 curproxy->options &= ~PR_O_HTTP_MODE;
4686 curproxy->options |= PR_O_HTTP_PCL;
4687 goto out;
4688 }
4689 else if (kwm == KWM_NO) {
4690 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4691 curproxy->options &= ~PR_O_HTTP_MODE;
4692 goto out;
4693 }
4694 }
4695 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004696 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4697 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004698 if (kwm == KWM_STD) {
4699 curproxy->options &= ~PR_O_HTTP_MODE;
4700 curproxy->options |= PR_O_HTTP_FCL;
4701 goto out;
4702 }
4703 else if (kwm == KWM_NO) {
4704 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4705 curproxy->options &= ~PR_O_HTTP_MODE;
4706 goto out;
4707 }
4708 }
4709 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004710 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4711 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004712 if (kwm == KWM_STD) {
4713 curproxy->options &= ~PR_O_HTTP_MODE;
4714 curproxy->options |= PR_O_HTTP_SCL;
4715 goto out;
4716 }
4717 else if (kwm == KWM_NO) {
4718 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4719 curproxy->options &= ~PR_O_HTTP_MODE;
4720 goto out;
4721 }
4722 }
4723 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004724 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4725 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004726 if (kwm == KWM_STD) {
4727 curproxy->options &= ~PR_O_HTTP_MODE;
4728 curproxy->options |= PR_O_HTTP_KAL;
4729 goto out;
4730 }
4731 else if (kwm == KWM_NO) {
4732 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4733 curproxy->options &= ~PR_O_HTTP_MODE;
4734 goto out;
4735 }
4736 }
4737 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004738 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4739 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004740 if (kwm == KWM_STD) {
4741 curproxy->options &= ~PR_O_HTTP_MODE;
4742 curproxy->options |= PR_O_HTTP_TUN;
4743 goto out;
4744 }
4745 else if (kwm == KWM_NO) {
4746 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4747 curproxy->options &= ~PR_O_HTTP_MODE;
4748 goto out;
4749 }
4750 }
4751
Joseph Lynch726ab712015-05-11 23:25:34 -07004752 /* Redispatch can take an integer argument that control when the
4753 * resispatch occurs. All values are relative to the retries option.
4754 * This can be cancelled using "no option xxx".
4755 */
4756 if (strcmp(args[1], "redispatch") == 0) {
4757 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4758 err_code |= ERR_WARN;
4759 goto out;
4760 }
4761
4762 curproxy->no_options &= ~PR_O_REDISP;
4763 curproxy->options &= ~PR_O_REDISP;
4764
4765 switch (kwm) {
4766 case KWM_STD:
4767 curproxy->options |= PR_O_REDISP;
4768 curproxy->redispatch_after = -1;
4769 if(*args[2]) {
4770 curproxy->redispatch_after = atol(args[2]);
4771 }
4772 break;
4773 case KWM_NO:
4774 curproxy->no_options |= PR_O_REDISP;
4775 curproxy->redispatch_after = 0;
4776 break;
4777 case KWM_DEF: /* already cleared */
4778 break;
4779 }
4780 goto out;
4781 }
4782
Willy Tarreau3842f002009-06-14 11:39:52 +02004783 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004784 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4785 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004786 err_code |= ERR_ALERT | ERR_FATAL;
4787 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004788 }
4789
Emeric Brun3a058f32009-06-30 18:26:00 +02004790 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004791 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004792 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004793 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004794 if (*(args[2]) != '\0') {
4795 if (!strcmp(args[2], "clf")) {
4796 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004797 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004798 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004799 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004800 err_code |= ERR_ALERT | ERR_FATAL;
4801 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004802 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004803 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4804 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004805 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004806 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4807 char *oldlogformat = "log-format";
4808 char *clflogformat = "";
4809
4810 if (curproxy->conf.logformat_string == default_http_log_format)
4811 oldlogformat = "option httplog";
4812 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4813 oldlogformat = "option tcplog";
4814 else if (curproxy->conf.logformat_string == clf_http_log_format)
4815 oldlogformat = "option httplog clf";
4816 if (logformat == clf_http_log_format)
4817 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004818 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4819 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004820 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004821 if (curproxy->conf.logformat_string != default_http_log_format &&
4822 curproxy->conf.logformat_string != default_tcp_log_format &&
4823 curproxy->conf.logformat_string != clf_http_log_format)
4824 free(curproxy->conf.logformat_string);
4825 curproxy->conf.logformat_string = logformat;
4826
4827 free(curproxy->conf.lfs_file);
4828 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4829 curproxy->conf.lfs_line = curproxy->conf.args.line;
Emeric Brun3a058f32009-06-30 18:26:00 +02004830 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004831 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004832 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4833 char *oldlogformat = "log-format";
4834
4835 if (curproxy->conf.logformat_string == default_http_log_format)
4836 oldlogformat = "option httplog";
4837 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4838 oldlogformat = "option tcplog";
4839 else if (curproxy->conf.logformat_string == clf_http_log_format)
4840 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004841 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4842 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004843 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004844 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004845 if (curproxy->conf.logformat_string != default_http_log_format &&
4846 curproxy->conf.logformat_string != default_tcp_log_format &&
4847 curproxy->conf.logformat_string != clf_http_log_format)
4848 free(curproxy->conf.logformat_string);
4849 curproxy->conf.logformat_string = default_tcp_log_format;
4850
4851 free(curproxy->conf.lfs_file);
4852 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4853 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004854
4855 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4856 goto out;
William Lallemandbddd4fd2012-02-27 11:23:10 +01004857 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004858 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004859 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004860 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004861 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004862
William Lallemanddf1425a2015-04-28 20:17:49 +02004863 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4864 goto out;
4865
Willy Tarreau13943ab2006-12-31 00:24:10 +01004866 if (curproxy->cap & PR_CAP_FE)
4867 curproxy->options |= PR_O_TCP_CLI_KA;
4868 if (curproxy->cap & PR_CAP_BE)
4869 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004870 }
4871 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004872 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004873 err_code |= ERR_WARN;
4874
Willy Tarreaubaaee002006-06-26 02:48:02 +02004875 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004876 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004877 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004878 curproxy->options2 &= ~PR_O2_CHK_ANY;
4879 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004880 if (!*args[2]) { /* no argument */
4881 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4882 curproxy->check_len = strlen(DEF_CHECK_REQ);
4883 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004884 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004885 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004886 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004887 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004888 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004889 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004890 if (*args[4])
4891 reqlen += strlen(args[4]);
4892 else
4893 reqlen += strlen("HTTP/1.0");
4894
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004895 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004896 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004897 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004898 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004899 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4900 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004901 }
4902 else if (!strcmp(args[1], "ssl-hello-chk")) {
4903 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004904 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004905 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004906
Willy Tarreaua534fea2008-08-03 12:19:50 +02004907 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004908 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004909 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004910 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004911
4912 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4913 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004914 }
Willy Tarreau23677902007-05-08 23:50:35 +02004915 else if (!strcmp(args[1], "smtpchk")) {
4916 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004917 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004918 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004919 curproxy->options2 &= ~PR_O2_CHK_ANY;
4920 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004921
4922 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4923 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4924 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4925 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4926 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4927 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004928 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004929 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4930 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4931 } else {
4932 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4933 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4934 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4935 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4936 }
4937 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004938 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4939 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004940 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004941 else if (!strcmp(args[1], "pgsql-check")) {
4942 /* use PostgreSQL request to check servers' health */
4943 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4944 err_code |= ERR_WARN;
4945
4946 free(curproxy->check_req);
4947 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004948 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004949 curproxy->options2 |= PR_O2_PGSQL_CHK;
4950
4951 if (*(args[2])) {
4952 int cur_arg = 2;
4953
4954 while (*(args[cur_arg])) {
4955 if (strcmp(args[cur_arg], "user") == 0) {
4956 char * packet;
4957 uint32_t packet_len;
4958 uint32_t pv;
4959
4960 /* suboption header - needs additional argument for it */
4961 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004962 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4963 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004964 err_code |= ERR_ALERT | ERR_FATAL;
4965 goto out;
4966 }
4967
4968 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4969 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4970 pv = htonl(0x30000); /* protocol version 3.0 */
4971
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004972 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004973
4974 memcpy(packet + 4, &pv, 4);
4975
4976 /* copy "user" */
4977 memcpy(packet + 8, "user", 4);
4978
4979 /* copy username */
4980 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
4981
4982 free(curproxy->check_req);
4983 curproxy->check_req = packet;
4984 curproxy->check_len = packet_len;
4985
4986 packet_len = htonl(packet_len);
4987 memcpy(packet, &packet_len, 4);
4988 cur_arg += 2;
4989 } else {
4990 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004991 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
4992 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004993 err_code |= ERR_ALERT | ERR_FATAL;
4994 goto out;
4995 }
4996 } /* end while loop */
4997 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004998 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4999 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005000 }
5001
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005002 else if (!strcmp(args[1], "redis-check")) {
5003 /* use REDIS PING request to check servers' health */
5004 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5005 err_code |= ERR_WARN;
5006
5007 free(curproxy->check_req);
5008 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005009 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005010 curproxy->options2 |= PR_O2_REDIS_CHK;
5011
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005012 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005013 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5014 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005015
5016 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5017 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005018 }
5019
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005020 else if (!strcmp(args[1], "mysql-check")) {
5021 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005022 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5023 err_code |= ERR_WARN;
5024
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005025 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005026 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005027 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005028 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005029
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005030 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005031 * const char mysql40_client_auth_pkt[] = {
5032 * "\x0e\x00\x00" // packet length
5033 * "\x01" // packet number
5034 * "\x00\x00" // client capabilities
5035 * "\x00\x00\x01" // max packet
5036 * "haproxy\x00" // username (null terminated string)
5037 * "\x00" // filler (always 0x00)
5038 * "\x01\x00\x00" // packet length
5039 * "\x00" // packet number
5040 * "\x01" // COM_QUIT command
5041 * };
5042 */
5043
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005044 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5045 * const char mysql41_client_auth_pkt[] = {
5046 * "\x0e\x00\x00\" // packet length
5047 * "\x01" // packet number
5048 * "\x00\x00\x00\x00" // client capabilities
5049 * "\x00\x00\x00\x01" // max packet
5050 * "\x21" // character set (UTF-8)
5051 * char[23] // All zeroes
5052 * "haproxy\x00" // username (null terminated string)
5053 * "\x00" // filler (always 0x00)
5054 * "\x01\x00\x00" // packet length
5055 * "\x00" // packet number
5056 * "\x01" // COM_QUIT command
5057 * };
5058 */
5059
5060
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005061 if (*(args[2])) {
5062 int cur_arg = 2;
5063
5064 while (*(args[cur_arg])) {
5065 if (strcmp(args[cur_arg], "user") == 0) {
5066 char *mysqluser;
5067 int packetlen, reqlen, userlen;
5068
5069 /* suboption header - needs additional argument for it */
5070 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005071 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5072 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005073 err_code |= ERR_ALERT | ERR_FATAL;
5074 goto out;
5075 }
5076 mysqluser = args[cur_arg + 1];
5077 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005078
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005079 if (*(args[cur_arg+2])) {
5080 if (!strcmp(args[cur_arg+2], "post-41")) {
5081 packetlen = userlen + 7 + 27;
5082 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005083
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005084 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005085 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005086 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005087
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005088 snprintf(curproxy->check_req, 4, "%c%c%c",
5089 ((unsigned char) packetlen & 0xff),
5090 ((unsigned char) (packetlen >> 8) & 0xff),
5091 ((unsigned char) (packetlen >> 16) & 0xff));
5092
5093 curproxy->check_req[3] = 1;
5094 curproxy->check_req[5] = 130;
5095 curproxy->check_req[11] = 1;
5096 curproxy->check_req[12] = 33;
5097 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5098 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5099 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5100 cur_arg += 3;
5101 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005102 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 +02005103 err_code |= ERR_ALERT | ERR_FATAL;
5104 goto out;
5105 }
5106 } else {
5107 packetlen = userlen + 7;
5108 reqlen = packetlen + 9;
5109
5110 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005111 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005112 curproxy->check_len = reqlen;
5113
5114 snprintf(curproxy->check_req, 4, "%c%c%c",
5115 ((unsigned char) packetlen & 0xff),
5116 ((unsigned char) (packetlen >> 8) & 0xff),
5117 ((unsigned char) (packetlen >> 16) & 0xff));
5118
5119 curproxy->check_req[3] = 1;
5120 curproxy->check_req[5] = 128;
5121 curproxy->check_req[8] = 1;
5122 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5123 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5124 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5125 cur_arg += 2;
5126 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005127 } else {
5128 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005129 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5130 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005131 err_code |= ERR_ALERT | ERR_FATAL;
5132 goto out;
5133 }
5134 } /* end while loop */
5135 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005136 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005137 else if (!strcmp(args[1], "ldap-check")) {
5138 /* use LDAP request to check servers' health */
5139 free(curproxy->check_req);
5140 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005141 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005142 curproxy->options2 |= PR_O2_LDAP_CHK;
5143
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005144 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005145 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5146 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005147 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5148 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005149 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005150 else if (!strcmp(args[1], "spop-check")) {
5151 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005152 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5153 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005154 err_code |= ERR_ALERT | ERR_FATAL;
5155 goto out;
5156 }
5157 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005158 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5159 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005160 err_code |= ERR_ALERT | ERR_FATAL;
5161 goto out;
5162 }
5163
5164 /* use SPOE request to check servers' health */
5165 free(curproxy->check_req);
5166 curproxy->check_req = NULL;
5167 curproxy->options2 &= ~PR_O2_CHK_ANY;
5168 curproxy->options2 |= PR_O2_SPOP_CHK;
5169
Christopher Faulet8ef75252017-02-20 22:56:03 +01005170 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005171 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005172 err_code |= ERR_ALERT | ERR_FATAL;
5173 goto out;
5174 }
5175 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5176 goto out;
5177 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005178 else if (!strcmp(args[1], "tcp-check")) {
5179 /* use raw TCPCHK send/expect to check servers' health */
5180 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5181 err_code |= ERR_WARN;
5182
5183 free(curproxy->check_req);
5184 curproxy->check_req = NULL;
5185 curproxy->options2 &= ~PR_O2_CHK_ANY;
5186 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005187 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5188 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005189 }
Simon Horman98637e52014-06-20 12:30:16 +09005190 else if (!strcmp(args[1], "external-check")) {
5191 /* excute an external command to check servers' health */
5192 free(curproxy->check_req);
5193 curproxy->check_req = NULL;
5194 curproxy->options2 &= ~PR_O2_CHK_ANY;
5195 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005196 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5197 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005198 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005199 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005200 int cur_arg;
5201
5202 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5203 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005204 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005205
Willy Tarreau87cf5142011-08-19 22:57:24 +02005206 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005207
5208 free(curproxy->fwdfor_hdr_name);
5209 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5210 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5211
5212 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5213 cur_arg = 2;
5214 while (*(args[cur_arg])) {
5215 if (!strcmp(args[cur_arg], "except")) {
5216 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005217 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005218 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5219 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005220 err_code |= ERR_ALERT | ERR_FATAL;
5221 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005222 }
5223 /* flush useless bits */
5224 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005225 cur_arg += 2;
5226 } else if (!strcmp(args[cur_arg], "header")) {
5227 /* suboption header - needs additional argument for it */
5228 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005229 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> 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;
Ross Westaf72a1d2008-08-03 10:51:45 +02005233 }
5234 free(curproxy->fwdfor_hdr_name);
5235 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5236 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5237 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005238 } else if (!strcmp(args[cur_arg], "if-none")) {
5239 curproxy->options &= ~PR_O_FF_ALWAYS;
5240 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005241 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005242 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005243 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5244 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005245 err_code |= ERR_ALERT | ERR_FATAL;
5246 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005247 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005248 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005249 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005250 else if (!strcmp(args[1], "originalto")) {
5251 int cur_arg;
5252
5253 /* insert x-original-to field, but not for the IP address listed as an except.
5254 * set default options (ie: bitfield, header name, etc)
5255 */
5256
5257 curproxy->options |= PR_O_ORGTO;
5258
5259 free(curproxy->orgto_hdr_name);
5260 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5261 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5262
Willy Tarreau87cf5142011-08-19 22:57:24 +02005263 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005264 cur_arg = 2;
5265 while (*(args[cur_arg])) {
5266 if (!strcmp(args[cur_arg], "except")) {
5267 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005268 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 +01005269 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5270 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005271 err_code |= ERR_ALERT | ERR_FATAL;
5272 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005273 }
5274 /* flush useless bits */
5275 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5276 cur_arg += 2;
5277 } else if (!strcmp(args[cur_arg], "header")) {
5278 /* suboption header - needs additional argument for it */
5279 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005280 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> 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 free(curproxy->orgto_hdr_name);
5286 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5287 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5288 cur_arg += 2;
5289 } else {
5290 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005291 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5292 file, linenum, args[0], args[1]);
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 } /* end while loop */
5297 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005298 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005299 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005300 err_code |= ERR_ALERT | ERR_FATAL;
5301 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005302 }
Willy Tarreau93893792009-07-23 13:19:11 +02005303 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005304 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005305 else if (!strcmp(args[0], "default_backend")) {
5306 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005307 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005308
5309 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005310 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005311 err_code |= ERR_ALERT | ERR_FATAL;
5312 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005313 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005314 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005315 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005316
5317 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5318 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005319 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005320 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005321 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005322 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005323
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005324 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005325 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5326 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005327 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005328 /* enable reconnections to dispatch */
5329 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005330
5331 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5332 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005333 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005334 else if (!strcmp(args[0], "http-reuse")) {
5335 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5336 err_code |= ERR_WARN;
5337
5338 if (strcmp(args[1], "never") == 0) {
5339 /* enable a graceful server shutdown on an HTTP 404 response */
5340 curproxy->options &= ~PR_O_REUSE_MASK;
5341 curproxy->options |= PR_O_REUSE_NEVR;
5342 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5343 goto out;
5344 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005345 else if (strcmp(args[1], "safe") == 0) {
5346 /* enable a graceful server shutdown on an HTTP 404 response */
5347 curproxy->options &= ~PR_O_REUSE_MASK;
5348 curproxy->options |= PR_O_REUSE_SAFE;
5349 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5350 goto out;
5351 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005352 else if (strcmp(args[1], "aggressive") == 0) {
5353 curproxy->options &= ~PR_O_REUSE_MASK;
5354 curproxy->options |= PR_O_REUSE_AGGR;
5355 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5356 goto out;
5357 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005358 else if (strcmp(args[1], "always") == 0) {
5359 /* enable a graceful server shutdown on an HTTP 404 response */
5360 curproxy->options &= ~PR_O_REUSE_MASK;
5361 curproxy->options |= PR_O_REUSE_ALWS;
5362 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5363 goto out;
5364 }
5365 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005366 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005367 err_code |= ERR_ALERT | ERR_FATAL;
5368 goto out;
5369 }
5370 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005371 else if (!strcmp(args[0], "http-check")) {
5372 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005373 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005374
5375 if (strcmp(args[1], "disable-on-404") == 0) {
5376 /* enable a graceful server shutdown on an HTTP 404 response */
5377 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005378 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5379 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005380 }
Willy Tarreauef781042010-01-27 11:53:01 +01005381 else if (strcmp(args[1], "send-state") == 0) {
5382 /* enable emission of the apparent state of a server in HTTP checks */
5383 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005384 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5385 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005386 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005387 else if (strcmp(args[1], "expect") == 0) {
5388 const char *ptr_arg;
5389 int cur_arg;
5390
5391 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005392 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005393 err_code |= ERR_ALERT | ERR_FATAL;
5394 goto out;
5395 }
5396
5397 cur_arg = 2;
5398 /* consider exclamation marks, sole or at the beginning of a word */
5399 while (*(ptr_arg = args[cur_arg])) {
5400 while (*ptr_arg == '!') {
5401 curproxy->options2 ^= PR_O2_EXP_INV;
5402 ptr_arg++;
5403 }
5404 if (*ptr_arg)
5405 break;
5406 cur_arg++;
5407 }
5408 /* now ptr_arg points to the beginning of a word past any possible
5409 * exclamation mark, and cur_arg is the argument which holds this word.
5410 */
5411 if (strcmp(ptr_arg, "status") == 0) {
5412 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005413 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5414 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005415 err_code |= ERR_ALERT | ERR_FATAL;
5416 goto out;
5417 }
5418 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005419 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005420 curproxy->expect_str = strdup(args[cur_arg + 1]);
5421 }
5422 else if (strcmp(ptr_arg, "string") == 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_STR;
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, "rstatus") == 0) {
5434 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005435 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> 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_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005441 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005442 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005443 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005444 free(curproxy->expect_regex);
5445 curproxy->expect_regex = NULL;
5446 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005447 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005448 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5449 error = NULL;
5450 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005451 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5452 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005453 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005454 err_code |= ERR_ALERT | ERR_FATAL;
5455 goto out;
5456 }
5457 }
5458 else if (strcmp(ptr_arg, "rstring") == 0) {
5459 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005460 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5461 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005462 err_code |= ERR_ALERT | ERR_FATAL;
5463 goto out;
5464 }
5465 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005466 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005467 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005468 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005469 free(curproxy->expect_regex);
5470 curproxy->expect_regex = NULL;
5471 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005472 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005473 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5474 error = NULL;
5475 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005476 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5477 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005478 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005479 err_code |= ERR_ALERT | ERR_FATAL;
5480 goto out;
5481 }
5482 }
5483 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005484 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5485 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005486 err_code |= ERR_ALERT | ERR_FATAL;
5487 goto out;
5488 }
5489 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005490 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005491 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 +02005492 err_code |= ERR_ALERT | ERR_FATAL;
5493 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005494 }
5495 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005496 else if (!strcmp(args[0], "tcp-check")) {
5497 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5498 err_code |= ERR_WARN;
5499
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005500 if (strcmp(args[1], "comment") == 0) {
5501 int cur_arg;
5502 struct tcpcheck_rule *tcpcheck;
5503
5504 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005505 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005506 tcpcheck->action = TCPCHK_ACT_COMMENT;
5507
5508 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005509 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5510 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005511 err_code |= ERR_ALERT | ERR_FATAL;
5512 goto out;
5513 }
5514
5515 tcpcheck->comment = strdup(args[cur_arg + 1]);
5516
5517 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005518 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5519 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005520 }
5521 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005522 const char *ptr_arg;
5523 int cur_arg;
5524 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005525
5526 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005527 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5528 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5529 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5530 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5531 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005532
Willy Tarreau5581c272015-05-13 12:24:53 +02005533 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5534 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005535 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5536 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005537 err_code |= ERR_ALERT | ERR_FATAL;
5538 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005539 }
5540
5541 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005542 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005543 tcpcheck->action = TCPCHK_ACT_CONNECT;
5544
5545 /* parsing each parameters to fill up the rule */
5546 while (*(ptr_arg = args[cur_arg])) {
5547 /* tcp port */
5548 if (strcmp(args[cur_arg], "port") == 0) {
5549 if ( (atol(args[cur_arg + 1]) > 65535) ||
5550 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005551 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5552 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005553 err_code |= ERR_ALERT | ERR_FATAL;
5554 goto out;
5555 }
5556 tcpcheck->port = atol(args[cur_arg + 1]);
5557 cur_arg += 2;
5558 }
5559 /* send proxy protocol */
5560 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5561 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5562 cur_arg++;
5563 }
5564#ifdef USE_OPENSSL
5565 else if (strcmp(args[cur_arg], "ssl") == 0) {
5566 curproxy->options |= PR_O_TCPCHK_SSL;
5567 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5568 cur_arg++;
5569 }
5570#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005571 /* comment for this tcpcheck line */
5572 else if (strcmp(args[cur_arg], "comment") == 0) {
5573 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005574 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5575 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005576 err_code |= ERR_ALERT | ERR_FATAL;
5577 goto out;
5578 }
5579 tcpcheck->comment = strdup(args[cur_arg + 1]);
5580 cur_arg += 2;
5581 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005582 else {
5583#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005584 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 +01005585#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005586 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 +01005587#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005588 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005589 err_code |= ERR_ALERT | ERR_FATAL;
5590 goto out;
5591 }
5592
5593 }
5594
5595 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5596 }
5597 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005598 if (! *(args[2]) ) {
5599 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005600 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5601 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005602 err_code |= ERR_ALERT | ERR_FATAL;
5603 goto out;
5604 } else {
5605 struct tcpcheck_rule *tcpcheck;
5606
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005607 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005608
5609 tcpcheck->action = TCPCHK_ACT_SEND;
5610 tcpcheck->string_len = strlen(args[2]);
5611 tcpcheck->string = strdup(args[2]);
5612 tcpcheck->expect_regex = NULL;
5613
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005614 /* comment for this tcpcheck line */
5615 if (strcmp(args[3], "comment") == 0) {
5616 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005617 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5618 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005619 err_code |= ERR_ALERT | ERR_FATAL;
5620 goto out;
5621 }
5622 tcpcheck->comment = strdup(args[4]);
5623 }
5624
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005625 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5626 }
5627 }
5628 else if (strcmp(args[1], "send-binary") == 0) {
5629 if (! *(args[2]) ) {
5630 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005631 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5632 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005633 err_code |= ERR_ALERT | ERR_FATAL;
5634 goto out;
5635 } else {
5636 struct tcpcheck_rule *tcpcheck;
5637 char *err = NULL;
5638
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005639 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005640
5641 tcpcheck->action = TCPCHK_ACT_SEND;
5642 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005643 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5644 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005645 err_code |= ERR_ALERT | ERR_FATAL;
5646 goto out;
5647 }
5648 tcpcheck->expect_regex = NULL;
5649
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005650 /* comment for this tcpcheck line */
5651 if (strcmp(args[3], "comment") == 0) {
5652 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005653 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5654 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005655 err_code |= ERR_ALERT | ERR_FATAL;
5656 goto out;
5657 }
5658 tcpcheck->comment = strdup(args[4]);
5659 }
5660
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005661 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5662 }
5663 }
5664 else if (strcmp(args[1], "expect") == 0) {
5665 const char *ptr_arg;
5666 int cur_arg;
5667 int inverse = 0;
5668
5669 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005670 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005671 err_code |= ERR_ALERT | ERR_FATAL;
5672 goto out;
5673 }
5674
5675 cur_arg = 2;
5676 /* consider exclamation marks, sole or at the beginning of a word */
5677 while (*(ptr_arg = args[cur_arg])) {
5678 while (*ptr_arg == '!') {
5679 inverse = !inverse;
5680 ptr_arg++;
5681 }
5682 if (*ptr_arg)
5683 break;
5684 cur_arg++;
5685 }
5686 /* now ptr_arg points to the beginning of a word past any possible
5687 * exclamation mark, and cur_arg is the argument which holds this word.
5688 */
5689 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005690 struct tcpcheck_rule *tcpcheck;
5691 char *err = NULL;
5692
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005693 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005694 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5695 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005696 err_code |= ERR_ALERT | ERR_FATAL;
5697 goto out;
5698 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005699
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005700 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005701
5702 tcpcheck->action = TCPCHK_ACT_EXPECT;
5703 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005704 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5705 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005706 err_code |= ERR_ALERT | ERR_FATAL;
5707 goto out;
5708 }
5709 tcpcheck->expect_regex = NULL;
5710 tcpcheck->inverse = inverse;
5711
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005712 /* tcpcheck comment */
5713 cur_arg += 2;
5714 if (strcmp(args[cur_arg], "comment") == 0) {
5715 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005716 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5717 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005718 err_code |= ERR_ALERT | ERR_FATAL;
5719 goto out;
5720 }
5721 tcpcheck->comment = strdup(args[cur_arg + 1]);
5722 }
5723
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005724 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5725 }
5726 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005727 struct tcpcheck_rule *tcpcheck;
5728
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005729 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005730 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5731 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005732 err_code |= ERR_ALERT | ERR_FATAL;
5733 goto out;
5734 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005735
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005736 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005737
5738 tcpcheck->action = TCPCHK_ACT_EXPECT;
5739 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5740 tcpcheck->string = strdup(args[cur_arg + 1]);
5741 tcpcheck->expect_regex = NULL;
5742 tcpcheck->inverse = inverse;
5743
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005744 /* tcpcheck comment */
5745 cur_arg += 2;
5746 if (strcmp(args[cur_arg], "comment") == 0) {
5747 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005748 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5749 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005750 err_code |= ERR_ALERT | ERR_FATAL;
5751 goto out;
5752 }
5753 tcpcheck->comment = strdup(args[cur_arg + 1]);
5754 }
5755
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005756 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5757 }
5758 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005759 struct tcpcheck_rule *tcpcheck;
5760
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005761 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005762 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5763 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005764 err_code |= ERR_ALERT | ERR_FATAL;
5765 goto out;
5766 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005767
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005768 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005769
5770 tcpcheck->action = TCPCHK_ACT_EXPECT;
5771 tcpcheck->string_len = 0;
5772 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005773 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5774 error = NULL;
5775 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005776 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5777 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005778 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005779 err_code |= ERR_ALERT | ERR_FATAL;
5780 goto out;
5781 }
5782 tcpcheck->inverse = inverse;
5783
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005784 /* tcpcheck comment */
5785 cur_arg += 2;
5786 if (strcmp(args[cur_arg], "comment") == 0) {
5787 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005788 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5789 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005790 err_code |= ERR_ALERT | ERR_FATAL;
5791 goto out;
5792 }
5793 tcpcheck->comment = strdup(args[cur_arg + 1]);
5794 }
5795
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005796 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5797 }
5798 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005799 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5800 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005801 err_code |= ERR_ALERT | ERR_FATAL;
5802 goto out;
5803 }
5804 }
5805 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005806 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 +02005807 err_code |= ERR_ALERT | ERR_FATAL;
5808 goto out;
5809 }
5810 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005811 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005812 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005813 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005814 err_code |= ERR_ALERT | ERR_FATAL;
5815 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005816 }
5817
Willy Tarreaub80c2302007-11-30 20:51:32 +01005818 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005819 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005820
5821 if (strcmp(args[1], "fail") == 0) {
5822 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005823 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005824 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5825 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005826 err_code |= ERR_ALERT | ERR_FATAL;
5827 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005828 }
5829
Willy Tarreau721d8e02017-12-01 18:25:08 +01005830 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005831 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005832 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5833 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005834 err_code |= ERR_ALERT | ERR_FATAL;
5835 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005836 }
5837 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5838 }
5839 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005840 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005841 err_code |= ERR_ALERT | ERR_FATAL;
5842 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005843 }
5844 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005845#ifdef TPROXY
5846 else if (!strcmp(args[0], "transparent")) {
5847 /* enable transparent proxy connections */
5848 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005849 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5850 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005851 }
5852#endif
5853 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005854 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005855 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005856
Willy Tarreaubaaee002006-06-26 02:48:02 +02005857 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005858 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005859 err_code |= ERR_ALERT | ERR_FATAL;
5860 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005861 }
5862 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005863 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5864 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005865 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005866 else if (!strcmp(args[0], "backlog")) { /* backlog */
5867 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005868 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005869
5870 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005871 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005872 err_code |= ERR_ALERT | ERR_FATAL;
5873 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005874 }
5875 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005876 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5877 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005878 }
Willy Tarreau86034312006-12-29 00:10:33 +01005879 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005880 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005881 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005882
Willy Tarreau86034312006-12-29 00:10:33 +01005883 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005884 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005885 err_code |= ERR_ALERT | ERR_FATAL;
5886 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005887 }
5888 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005889 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5890 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005891 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005892 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5893 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005894 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005895 err_code |= ERR_ALERT | ERR_FATAL;
5896 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005897 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005898 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5899 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005900 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5901 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005902 err_code |= ERR_ALERT | ERR_FATAL;
5903 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005904 }
5905 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005906 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5907 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005908 }
5909 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005910 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005911 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005912 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005913
Willy Tarreaubaaee002006-06-26 02:48:02 +02005914 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005915 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005916 err_code |= ERR_ALERT | ERR_FATAL;
5917 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005918 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005919 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005920 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005921
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005922 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005923 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005924 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005925 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005926 goto out;
5927 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005928
5929 proto = protocol_by_family(sk->ss_family);
5930 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005931 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5932 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005933 err_code |= ERR_ALERT | ERR_FATAL;
5934 goto out;
5935 }
5936
5937 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005938 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5939 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005940 err_code |= ERR_ALERT | ERR_FATAL;
5941 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005942 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005943
5944 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005945 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5946 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005947 err_code |= ERR_ALERT | ERR_FATAL;
5948 goto out;
5949 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005950
William Lallemanddf1425a2015-04-28 20:17:49 +02005951 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5952 goto out;
5953
Willy Tarreaud5191e72010-02-09 20:50:45 +01005954 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005955 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005956 }
5957 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005958 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005959 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005960
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005961 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005962 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005963 err_code |= ERR_ALERT | ERR_FATAL;
5964 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005965 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005966 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005967 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005968 /**
5969 * The syntax for hash-type config element is
5970 * hash-type {map-based|consistent} [[<algo>] avalanche]
5971 *
5972 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5973 */
5974 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005975
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005976 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5977 err_code |= ERR_WARN;
5978
5979 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005980 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
5981 }
5982 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005983 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
5984 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005985 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005986 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 -05005987 err_code |= ERR_ALERT | ERR_FATAL;
5988 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01005989 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005990 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005991 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005992 err_code |= ERR_ALERT | ERR_FATAL;
5993 goto out;
5994 }
Bhaskar98634f02013-10-29 23:30:51 -04005995
5996 /* set the hash function to use */
5997 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005998 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04005999 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006000
6001 /* if consistent with no argument, then avalanche modifier is also applied */
6002 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6003 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006004 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006005 /* set the hash function */
6006 if (!strcmp(args[2], "sdbm")) {
6007 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6008 }
6009 else if (!strcmp(args[2], "djb2")) {
6010 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006011 }
6012 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006013 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006014 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006015 else if (!strcmp(args[2], "crc32")) {
6016 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6017 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006018 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006019 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 -05006020 err_code |= ERR_ALERT | ERR_FATAL;
6021 goto out;
6022 }
6023
6024 /* set the hash modifier */
6025 if (!strcmp(args[3], "avalanche")) {
6026 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6027 }
6028 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006029 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 -05006030 err_code |= ERR_ALERT | ERR_FATAL;
6031 goto out;
6032 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006033 }
William Lallemanda73203e2012-03-12 12:48:57 +01006034 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006035 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6036 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006037 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006038 err_code |= ERR_ALERT | ERR_FATAL;
6039 goto out;
6040 }
6041 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6042 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006043 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 -04006044 err_code |= ERR_ALERT | ERR_FATAL;
6045 goto out;
6046 }
6047 }
William Lallemanda73203e2012-03-12 12:48:57 +01006048 else if (strcmp(args[0], "unique-id-format") == 0) {
6049 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006050 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006051 err_code |= ERR_ALERT | ERR_FATAL;
6052 goto out;
6053 }
William Lallemand3203ff42012-11-11 17:30:56 +01006054 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006055 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 +01006056 err_code |= ERR_ALERT | ERR_FATAL;
6057 goto out;
6058 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006059 free(curproxy->conf.uniqueid_format_string);
6060 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006061
Willy Tarreau62a61232013-04-12 18:13:46 +02006062 free(curproxy->conf.uif_file);
6063 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6064 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006065 }
William Lallemanda73203e2012-03-12 12:48:57 +01006066
6067 else if (strcmp(args[0], "unique-id-header") == 0) {
6068 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006069 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006070 err_code |= ERR_ALERT | ERR_FATAL;
6071 goto out;
6072 }
6073 free(curproxy->header_unique_id);
6074 curproxy->header_unique_id = strdup(args[1]);
6075 }
6076
William Lallemand723b73a2012-02-08 16:37:49 +01006077 else if (strcmp(args[0], "log-format") == 0) {
6078 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006079 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006080 err_code |= ERR_ALERT | ERR_FATAL;
6081 goto out;
6082 }
William Lallemand3203ff42012-11-11 17:30:56 +01006083 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006084 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 +01006085 err_code |= ERR_ALERT | ERR_FATAL;
6086 goto out;
6087 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006088 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6089 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006090
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006091 if (curproxy->conf.logformat_string == default_http_log_format)
6092 oldlogformat = "option httplog";
6093 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6094 oldlogformat = "option tcplog";
6095 else if (curproxy->conf.logformat_string == clf_http_log_format)
6096 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006097 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6098 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006099 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006100 if (curproxy->conf.logformat_string != default_http_log_format &&
6101 curproxy->conf.logformat_string != default_tcp_log_format &&
6102 curproxy->conf.logformat_string != clf_http_log_format)
6103 free(curproxy->conf.logformat_string);
6104 curproxy->conf.logformat_string = strdup(args[1]);
6105
6106 free(curproxy->conf.lfs_file);
6107 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6108 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006109
6110 /* get a chance to improve log-format error reporting by
6111 * reporting the correct line-number when possible.
6112 */
6113 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006114 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6115 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006116 err_code |= ERR_WARN;
6117 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006118 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006119 else if (!strcmp(args[0], "log-format-sd")) {
6120 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006121 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006122 err_code |= ERR_ALERT | ERR_FATAL;
6123 goto out;
6124 }
6125 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006126 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 +02006127 err_code |= ERR_ALERT | ERR_FATAL;
6128 goto out;
6129 }
6130
6131 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6132 free(curproxy->conf.logformat_sd_string);
6133 curproxy->conf.logformat_sd_string = strdup(args[1]);
6134
6135 free(curproxy->conf.lfsd_file);
6136 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6137 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6138
6139 /* get a chance to improve log-format-sd error reporting by
6140 * reporting the correct line-number when possible.
6141 */
6142 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006143 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6144 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006145 err_code |= ERR_WARN;
6146 }
6147 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006148 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6149 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006150 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 +01006151 err_code |= ERR_ALERT | ERR_FATAL;
6152 goto out;
6153 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006154 chunk_destroy(&curproxy->log_tag);
6155 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006156 }
William Lallemand0f99e342011-10-12 17:50:54 +02006157 else if (!strcmp(args[0], "log") && kwm == KWM_NO) {
6158 /* delete previous herited or defined syslog servers */
6159 struct logsrv *back;
6160
6161 if (*(args[1]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006162 ha_alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
William Lallemand0f99e342011-10-12 17:50:54 +02006163 err_code |= ERR_ALERT | ERR_FATAL;
6164 goto out;
6165 }
6166
William Lallemand723b73a2012-02-08 16:37:49 +01006167 list_for_each_entry_safe(tmplogsrv, back, &curproxy->logsrvs, list) {
6168 LIST_DEL(&tmplogsrv->list);
6169 free(tmplogsrv);
William Lallemand0f99e342011-10-12 17:50:54 +02006170 }
6171 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006172 else if (!strcmp(args[0], "log")) { /* syslog server address */
William Lallemand0f99e342011-10-12 17:50:54 +02006173 struct logsrv *logsrv;
6174
Willy Tarreaubaaee002006-06-26 02:48:02 +02006175 if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
William Lallemand0f99e342011-10-12 17:50:54 +02006176 /* copy global.logrsvs linked list to the end of curproxy->logsrvs */
William Lallemand723b73a2012-02-08 16:37:49 +01006177 list_for_each_entry(tmplogsrv, &global.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02006178 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01006179 memcpy(node, tmplogsrv, sizeof(struct logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02006180 LIST_INIT(&node->list);
6181 LIST_ADDQ(&curproxy->logsrvs, &node->list);
6182 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006183 }
6184 else if (*(args[1]) && *(args[2])) {
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006185 struct sockaddr_storage *sk;
6186 int port1, port2;
Willy Tarreau18324f52014-06-27 18:10:07 +02006187 int arg = 0;
6188 int len = 0;
William Lallemand0f99e342011-10-12 17:50:54 +02006189
Vincent Bernat02779b62016-04-03 13:48:43 +02006190 logsrv = calloc(1, sizeof(*logsrv));
Willy Tarreaubaaee002006-06-26 02:48:02 +02006191
Willy Tarreau18324f52014-06-27 18:10:07 +02006192 /* just after the address, a length may be specified */
6193 if (strcmp(args[arg+2], "len") == 0) {
6194 len = atoi(args[arg+3]);
6195 if (len < 80 || len > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006196 ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
6197 file, linenum, args[arg+3]);
Willy Tarreau18324f52014-06-27 18:10:07 +02006198 err_code |= ERR_ALERT | ERR_FATAL;
6199 goto out;
6200 }
6201 logsrv->maxlen = len;
6202
6203 /* skip these two args */
6204 arg += 2;
6205 }
6206 else
6207 logsrv->maxlen = MAX_SYSLOG_LEN;
6208
Christopher Faulet084aa962017-08-29 16:54:41 +02006209 if (logsrv->maxlen > global.max_syslog_len)
Willy Tarreau18324f52014-06-27 18:10:07 +02006210 global.max_syslog_len = logsrv->maxlen;
Willy Tarreau18324f52014-06-27 18:10:07 +02006211
Dragan Dosen1322d092015-09-22 16:05:32 +02006212 /* after the length, a format may be specified */
6213 if (strcmp(args[arg+2], "format") == 0) {
6214 logsrv->format = get_log_format(args[arg+3]);
6215 if (logsrv->format < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006216 ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
Dragan Dosen1322d092015-09-22 16:05:32 +02006217 err_code |= ERR_ALERT | ERR_FATAL;
6218 goto out;
6219 }
6220
6221 /* skip these two args */
6222 arg += 2;
6223 }
6224
William Lallemanddf1425a2015-04-28 20:17:49 +02006225 if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code))
6226 goto out;
6227
Willy Tarreau18324f52014-06-27 18:10:07 +02006228 logsrv->facility = get_log_facility(args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02006229 if (logsrv->facility < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006230 ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02006231 err_code |= ERR_ALERT | ERR_FATAL;
6232 goto out;
6233
Willy Tarreaubaaee002006-06-26 02:48:02 +02006234 }
6235
William Lallemand0f99e342011-10-12 17:50:54 +02006236 logsrv->level = 7; /* max syslog level = debug */
Willy Tarreau18324f52014-06-27 18:10:07 +02006237 if (*(args[arg+3])) {
6238 logsrv->level = get_log_level(args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02006239 if (logsrv->level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006240 ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02006241 err_code |= ERR_ALERT | ERR_FATAL;
6242 goto out;
6243
Willy Tarreaubaaee002006-06-26 02:48:02 +02006244 }
6245 }
6246
William Lallemand0f99e342011-10-12 17:50:54 +02006247 logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
Willy Tarreau18324f52014-06-27 18:10:07 +02006248 if (*(args[arg+4])) {
6249 logsrv->minlvl = get_log_level(args[arg+4]);
Willy Tarreauf7f057b2013-01-24 00:31:24 +01006250 if (logsrv->minlvl < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006251 ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
William Lallemand0f99e342011-10-12 17:50:54 +02006252 err_code |= ERR_ALERT | ERR_FATAL;
6253 goto out;
6254
Willy Tarreauf7edefa2009-05-10 17:20:05 +02006255 }
6256 }
6257
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006258 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006259 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006260 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006261 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006262 goto out;
6263 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006264
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006265 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006266
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006267 if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006268 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006269 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6270 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006271 err_code |= ERR_ALERT | ERR_FATAL;
6272 goto out;
6273 }
6274
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006275 if (!port1)
William Lallemand0f99e342011-10-12 17:50:54 +02006276 set_host_port(&logsrv->addr, SYSLOG_PORT);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006277 }
William Lallemand0f99e342011-10-12 17:50:54 +02006278
6279 LIST_ADDQ(&curproxy->logsrvs, &logsrv->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006280 }
6281 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006282 ha_alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
6283 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02006284 err_code |= ERR_ALERT | ERR_FATAL;
6285 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006286 }
6287 }
6288 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006289 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006290 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006291 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006292 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006293
Willy Tarreau977b8e42006-12-29 14:19:17 +01006294 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006295 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006296
Willy Tarreaubaaee002006-06-26 02:48:02 +02006297 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006298 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6299 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006300 err_code |= ERR_ALERT | ERR_FATAL;
6301 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006302 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006303
6304 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006305 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6306 free(curproxy->conn_src.iface_name);
6307 curproxy->conn_src.iface_name = NULL;
6308 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006309
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006310 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006311 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006312 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6313 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006314 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006315 goto out;
6316 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006317
6318 proto = protocol_by_family(sk->ss_family);
6319 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006320 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6321 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006322 err_code |= ERR_ALERT | ERR_FATAL;
6323 goto out;
6324 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006325
6326 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006327 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6328 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006329 err_code |= ERR_ALERT | ERR_FATAL;
6330 goto out;
6331 }
6332
Willy Tarreauef9a3602012-12-08 22:29:20 +01006333 curproxy->conn_src.source_addr = *sk;
6334 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006335
6336 cur_arg = 2;
6337 while (*(args[cur_arg])) {
6338 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006339#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006340 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006341 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6342 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006343 err_code |= ERR_ALERT | ERR_FATAL;
6344 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006345 }
6346
6347 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006348 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6349 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006350 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006351 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6352 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006353 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6354 char *name, *end;
6355
6356 name = args[cur_arg+1] + 7;
6357 while (isspace(*name))
6358 name++;
6359
6360 end = name;
6361 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6362 end++;
6363
Willy Tarreauef9a3602012-12-08 22:29:20 +01006364 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6365 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6366 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6367 curproxy->conn_src.bind_hdr_len = end - name;
6368 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6369 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6370 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006371
6372 /* now look for an occurrence number */
6373 while (isspace(*end))
6374 end++;
6375 if (*end == ',') {
6376 end++;
6377 name = end;
6378 if (*end == '-')
6379 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006380 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006381 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006382 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006383 }
6384
Willy Tarreauef9a3602012-12-08 22:29:20 +01006385 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006386 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6387 " occurrences values smaller than %d.\n",
6388 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006389 err_code |= ERR_ALERT | ERR_FATAL;
6390 goto out;
6391 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006392 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006393 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006394
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006395 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006396 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006397 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6398 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006399 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006400 goto out;
6401 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006402
6403 proto = protocol_by_family(sk->ss_family);
6404 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006405 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6406 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006407 err_code |= ERR_ALERT | ERR_FATAL;
6408 goto out;
6409 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006410
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006411 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006412 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6413 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006414 err_code |= ERR_ALERT | ERR_FATAL;
6415 goto out;
6416 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006417 curproxy->conn_src.tproxy_addr = *sk;
6418 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006419 }
6420 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006421#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006422 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6423 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006424 err_code |= ERR_ALERT | ERR_FATAL;
6425 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006426#endif
6427 cur_arg += 2;
6428 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006429 }
6430
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006431 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6432#ifdef SO_BINDTODEVICE
6433 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006434 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6435 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006436 err_code |= ERR_ALERT | ERR_FATAL;
6437 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006438 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006439 free(curproxy->conn_src.iface_name);
6440 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6441 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006442 global.last_checks |= LSTCHK_NETADM;
6443#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006444 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6445 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006446 err_code |= ERR_ALERT | ERR_FATAL;
6447 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006448#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006449 cur_arg += 2;
6450 continue;
6451 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006452 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6453 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006454 err_code |= ERR_ALERT | ERR_FATAL;
6455 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006456 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006457 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006458 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006459 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6460 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006461 err_code |= ERR_ALERT | ERR_FATAL;
6462 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006463 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006464 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006465 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006466 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6467 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006468 err_code |= ERR_ALERT | ERR_FATAL;
6469 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006470 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006471
6472 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006473 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006474 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006475 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006476 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006477 }
6478 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006479 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006480 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006481 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006482 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006483 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006484 }
6485 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006486 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006487 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006488 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006489 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006490 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006491 }
6492 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006493 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006494 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006495 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006496 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006497 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006498 }
6499 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006500 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006501 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006502 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006503 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006504 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006505 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006506 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006507 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006508 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006509 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006510 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006511 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006512 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006513 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006514 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006515 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6516 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006517 err_code |= ERR_ALERT | ERR_FATAL;
6518 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006519 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006520
6521 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006522 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006523 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006524 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006525 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006526 }
6527 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006528 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006529 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006530 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006531 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006532 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006533 }
6534 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006535 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006536 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006537 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006538 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006539 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006540 }
6541 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006542 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006543 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006544 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006545 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006546 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006547 }
6548 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006549 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006550 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006551 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006552 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006553 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006554 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006555 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006556 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006557 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006558 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006559 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006560 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006561 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006562 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006563 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006564
Willy Tarreaubaaee002006-06-26 02:48:02 +02006565 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006566 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006567 err_code |= ERR_ALERT | ERR_FATAL;
6568 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006569 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006570 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006571 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006572
Willy Tarreaubaaee002006-06-26 02:48:02 +02006573 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006574 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006575 err_code |= ERR_ALERT | ERR_FATAL;
6576 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006577 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006578
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006579 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006580 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006581 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6582 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006583 err_code |= ERR_ALERT | ERR_FATAL;
6584 goto out;
6585 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006586 err_code |= warnif_cond_conflicts(cond,
6587 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6588 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006589 }
6590 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006591 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6592 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006593 err_code |= ERR_ALERT | ERR_FATAL;
6594 goto out;
6595 }
6596
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006597 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006598 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006599 wl->s = strdup(args[1]);
6600 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006601 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006602 }
6603 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006604 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006605 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6606 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006607 err_code |= ERR_ALERT | ERR_FATAL;
6608 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006609 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006610
Willy Tarreauade5ec42010-01-28 19:33:49 +01006611 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006612 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006613 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006614 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006615 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006616 }
6617 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006618 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006619 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006620 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006621 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006622 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006623 }
6624 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006625 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006626 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006627 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006628 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006629 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006630 }
6631 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006632 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006633 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6634 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006635 err_code |= ERR_ALERT | ERR_FATAL;
6636 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006637 }
6638
Willy Tarreauade5ec42010-01-28 19:33:49 +01006639 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006640 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006641 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006642 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006643 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006644 }
6645 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006646 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006647 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006648 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006649 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006650 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006651 }
6652 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006653 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006654 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006655 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006656 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006657 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006658 }
6659 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006660 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006661
Willy Tarreaubaaee002006-06-26 02:48:02 +02006662 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006663 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006664 err_code |= ERR_ALERT | ERR_FATAL;
6665 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006666 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006667 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006668 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006669
Willy Tarreaubaaee002006-06-26 02:48:02 +02006670 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006671 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006672 err_code |= ERR_ALERT | ERR_FATAL;
6673 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006674 }
6675
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006676 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006677 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006678 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6679 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006680 err_code |= ERR_ALERT | ERR_FATAL;
6681 goto out;
6682 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006683 err_code |= warnif_cond_conflicts(cond,
6684 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6685 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006686 }
6687 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006688 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6689 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006690 err_code |= ERR_ALERT | ERR_FATAL;
6691 goto out;
6692 }
6693
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006694 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006695 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006696 wl->s = strdup(args[1]);
6697 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006698 }
6699 else if (!strcmp(args[0], "errorloc") ||
6700 !strcmp(args[0], "errorloc302") ||
6701 !strcmp(args[0], "errorloc303")) { /* error location */
6702 int errnum, errlen;
6703 char *err;
6704
Willy Tarreau977b8e42006-12-29 14:19:17 +01006705 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006706 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006707
Willy Tarreaubaaee002006-06-26 02:48:02 +02006708 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006709 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 +02006710 err_code |= ERR_ALERT | ERR_FATAL;
6711 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006712 }
6713
6714 errnum = atol(args[1]);
6715 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006716 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6717 err = malloc(errlen);
6718 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006719 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006720 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6721 err = malloc(errlen);
6722 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006723 }
6724
Willy Tarreau0f772532006-12-23 20:51:41 +01006725 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6726 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006727 chunk_destroy(&curproxy->errmsg[rc]);
6728 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006729 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006730 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006731 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006732
6733 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006734 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6735 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006736 free(err);
6737 }
6738 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006739 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6740 int errnum, errlen, fd;
6741 char *err;
6742 struct stat stat;
6743
6744 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006745 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006746
6747 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006748 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 +02006749 err_code |= ERR_ALERT | ERR_FATAL;
6750 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006751 }
6752
6753 fd = open(args[2], O_RDONLY);
6754 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006755 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6756 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006757 if (fd >= 0)
6758 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006759 err_code |= ERR_ALERT | ERR_FATAL;
6760 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006761 }
6762
Willy Tarreau27a674e2009-08-17 07:23:33 +02006763 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006764 errlen = stat.st_size;
6765 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006766 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6767 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006768 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006769 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006770 }
6771
6772 err = malloc(errlen); /* malloc() must succeed during parsing */
6773 errnum = read(fd, err, errlen);
6774 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006775 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6776 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006777 close(fd);
6778 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006779 err_code |= ERR_ALERT | ERR_FATAL;
6780 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006781 }
6782 close(fd);
6783
6784 errnum = atol(args[1]);
6785 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6786 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006787 chunk_destroy(&curproxy->errmsg[rc]);
6788 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006789 break;
6790 }
6791 }
6792
6793 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006794 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6795 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006796 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006797 free(err);
6798 }
6799 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006800 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006801 struct cfg_kw_list *kwl;
6802 int index;
6803
6804 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6805 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6806 if (kwl->kw[index].section != CFG_LISTEN)
6807 continue;
6808 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6809 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006810 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006811 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006812 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006813 err_code |= ERR_ALERT | ERR_FATAL;
6814 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006815 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006816 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006817 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006818 err_code |= ERR_WARN;
6819 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006820 }
Willy Tarreau93893792009-07-23 13:19:11 +02006821 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006822 }
6823 }
6824 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006825
Christopher Faulet767a84b2017-11-24 16:50:31 +01006826 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006827 err_code |= ERR_ALERT | ERR_FATAL;
6828 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006829 }
Willy Tarreau93893792009-07-23 13:19:11 +02006830 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006831 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006832 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006833}
6834
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006835int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006836cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6837{
6838#ifdef CONFIG_HAP_NS
6839 const char *err;
6840 const char *item = args[0];
6841
6842 if (!strcmp(item, "namespace_list")) {
6843 return 0;
6844 }
6845 else if (!strcmp(item, "namespace")) {
6846 size_t idx = 1;
6847 const char *current;
6848 while (*(current = args[idx++])) {
6849 err = invalid_char(current);
6850 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006851 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6852 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006853 return ERR_ALERT | ERR_FATAL;
6854 }
6855
6856 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006857 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6858 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006859 return ERR_ALERT | ERR_FATAL;
6860 }
6861 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006862 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6863 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006864 return ERR_ALERT | ERR_FATAL;
6865 }
6866 }
6867 }
6868
6869 return 0;
6870#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006871 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6872 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006873 return ERR_ALERT | ERR_FATAL;
6874#endif
6875}
6876
6877int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006878cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6879{
6880
6881 int err_code = 0;
6882 const char *err;
6883
6884 if (!strcmp(args[0], "userlist")) { /* new userlist */
6885 struct userlist *newul;
6886
6887 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006888 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6889 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006890 err_code |= ERR_ALERT | ERR_FATAL;
6891 goto out;
6892 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006893 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6894 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006895
6896 err = invalid_char(args[1]);
6897 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006898 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6899 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006900 err_code |= ERR_ALERT | ERR_FATAL;
6901 goto out;
6902 }
6903
6904 for (newul = userlist; newul; newul = newul->next)
6905 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006906 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6907 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006908 err_code |= ERR_WARN;
6909 goto out;
6910 }
6911
Vincent Bernat02779b62016-04-03 13:48:43 +02006912 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006913 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006914 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006915 err_code |= ERR_ALERT | ERR_ABORT;
6916 goto out;
6917 }
6918
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006919 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006920 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006921 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006922 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006923 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006924 goto out;
6925 }
6926
6927 newul->next = userlist;
6928 userlist = newul;
6929
6930 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006931 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006932 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006933 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006934
6935 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006936 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6937 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006938 err_code |= ERR_ALERT | ERR_FATAL;
6939 goto out;
6940 }
6941
6942 err = invalid_char(args[1]);
6943 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006944 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6945 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006946 err_code |= ERR_ALERT | ERR_FATAL;
6947 goto out;
6948 }
6949
William Lallemand4ac9f542015-05-28 18:03:51 +02006950 if (!userlist)
6951 goto out;
6952
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006953 for (ag = userlist->groups; ag; ag = ag->next)
6954 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006955 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6956 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006957 err_code |= ERR_ALERT;
6958 goto out;
6959 }
6960
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006961 ag = calloc(1, sizeof(*ag));
6962 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006963 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006964 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006965 goto out;
6966 }
6967
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006968 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006969 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006970 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006971 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006972 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006973 goto out;
6974 }
6975
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006976 cur_arg = 2;
6977
6978 while (*args[cur_arg]) {
6979 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006980 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006981 cur_arg += 2;
6982 continue;
6983 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006984 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6985 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006986 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006987 free(ag->groupusers);
6988 free(ag->name);
6989 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006990 goto out;
6991 }
6992 }
6993
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006994 ag->next = userlist->groups;
6995 userlist->groups = ag;
6996
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006997 } else if (!strcmp(args[0], "user")) { /* new user */
6998 struct auth_users *newuser;
6999 int cur_arg;
7000
7001 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007002 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
7003 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007004 err_code |= ERR_ALERT | ERR_FATAL;
7005 goto out;
7006 }
William Lallemand4ac9f542015-05-28 18:03:51 +02007007 if (!userlist)
7008 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007009
7010 for (newuser = userlist->users; newuser; newuser = newuser->next)
7011 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007012 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
7013 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007014 err_code |= ERR_ALERT;
7015 goto out;
7016 }
7017
Vincent Bernat02779b62016-04-03 13:48:43 +02007018 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007019 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007020 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007021 err_code |= ERR_ALERT | ERR_ABORT;
7022 goto out;
7023 }
7024
7025 newuser->user = strdup(args[1]);
7026
7027 newuser->next = userlist->users;
7028 userlist->users = newuser;
7029
7030 cur_arg = 2;
7031
7032 while (*args[cur_arg]) {
7033 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02007034#ifdef CONFIG_HAP_CRYPT
7035 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007036 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
7037 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02007038 err_code |= ERR_ALERT | ERR_FATAL;
7039 goto out;
7040 }
7041#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01007042 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
7043 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007044 err_code |= ERR_ALERT;
7045#endif
7046 newuser->pass = strdup(args[cur_arg + 1]);
7047 cur_arg += 2;
7048 continue;
7049 } else if (!strcmp(args[cur_arg], "insecure-password")) {
7050 newuser->pass = strdup(args[cur_arg + 1]);
7051 newuser->flags |= AU_O_INSECURE;
7052 cur_arg += 2;
7053 continue;
7054 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007055 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007056 cur_arg += 2;
7057 continue;
7058 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007059 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
7060 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007061 err_code |= ERR_ALERT | ERR_FATAL;
7062 goto out;
7063 }
7064 }
7065 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007066 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 +01007067 err_code |= ERR_ALERT | ERR_FATAL;
7068 }
7069
7070out:
7071 return err_code;
7072}
Willy Tarreaubaaee002006-06-26 02:48:02 +02007073
Christopher Faulet79bdef32016-11-04 22:36:15 +01007074int
7075cfg_parse_scope(const char *file, int linenum, char *line)
7076{
7077 char *beg, *end, *scope = NULL;
7078 int err_code = 0;
7079 const char *err;
7080
7081 beg = line + 1;
7082 end = strchr(beg, ']');
7083
7084 /* Detect end of scope declaration */
7085 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007086 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
7087 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007088 err_code |= ERR_ALERT | ERR_FATAL;
7089 goto out;
7090 }
7091
7092 /* Get scope name and check its validity */
7093 scope = my_strndup(beg, end-beg);
7094 err = invalid_char(scope);
7095 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007096 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
7097 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007098 err_code |= ERR_ALERT | ERR_ABORT;
7099 goto out;
7100 }
7101
7102 /* Be sure to have a scope declaration alone on its line */
7103 line = end+1;
7104 while (isspace((unsigned char)*line))
7105 line++;
7106 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007107 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7108 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007109 err_code |= ERR_ALERT | ERR_ABORT;
7110 goto out;
7111 }
7112
7113 /* We have a valid scope declaration, save it */
7114 free(cfg_scope);
7115 cfg_scope = scope;
7116 scope = NULL;
7117
7118 out:
7119 free(scope);
7120 return err_code;
7121}
7122
Willy Tarreaubaaee002006-06-26 02:48:02 +02007123/*
7124 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007125 * Returns the error code, 0 if OK, or any combination of :
7126 * - ERR_ABORT: must abort ASAP
7127 * - ERR_FATAL: we can continue parsing but not start the service
7128 * - ERR_WARN: a warning has been emitted
7129 * - ERR_ALERT: an alert has been emitted
7130 * Only the two first ones can stop processing, the two others are just
7131 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007132 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007133int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007134{
William Lallemand64e84512015-05-12 14:25:37 +02007135 char *thisline;
7136 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007137 FILE *f;
7138 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007139 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007140 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007141 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007142 int readbytes = 0;
7143
7144 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007145 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007146 return -1;
7147 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007148
David Carlier97880bb2016-04-08 10:35:26 +01007149 if ((f=fopen(file,"r")) == NULL) {
7150 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007151 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007152 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007153
William Lallemandb2f07452015-05-12 14:27:13 +02007154next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007155 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007156 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007157 char *end;
7158 char *args[MAX_LINE_ARGS + 1];
7159 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007160 int dquote = 0; /* double quote */
7161 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007162
Willy Tarreaubaaee002006-06-26 02:48:02 +02007163 linenum++;
7164
7165 end = line + strlen(line);
7166
William Lallemand64e84512015-05-12 14:25:37 +02007167 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007168 /* Check if we reached the limit and the last char is not \n.
7169 * Watch out for the last line without the terminating '\n'!
7170 */
William Lallemand64e84512015-05-12 14:25:37 +02007171 char *newline;
7172 int newlinesize = linesize * 2;
7173
7174 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7175 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007176 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7177 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007178 err_code |= ERR_ALERT | ERR_FATAL;
7179 continue;
7180 }
7181
7182 readbytes = linesize - 1;
7183 linesize = newlinesize;
7184 thisline = newline;
7185 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007186 }
7187
William Lallemand64e84512015-05-12 14:25:37 +02007188 readbytes = 0;
7189
Willy Tarreaubaaee002006-06-26 02:48:02 +02007190 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007191 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007192 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007193
Christopher Faulet79bdef32016-11-04 22:36:15 +01007194
7195 if (*line == '[') {/* This is the begining if a scope */
7196 err_code |= cfg_parse_scope(file, linenum, line);
7197 goto next_line;
7198 }
7199
Willy Tarreaubaaee002006-06-26 02:48:02 +02007200 arg = 0;
7201 args[arg] = line;
7202
7203 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007204 if (*line == '"' && !squote) { /* double quote outside single quotes */
7205 if (dquote)
7206 dquote = 0;
7207 else
7208 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007209 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007210 end--;
7211 }
7212 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7213 if (squote)
7214 squote = 0;
7215 else
7216 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007217 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007218 end--;
7219 }
7220 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007221 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7222 * C equivalent value. Other combinations left unchanged (eg: \1).
7223 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007224 int skip = 0;
7225 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7226 *line = line[1];
7227 skip = 1;
7228 }
7229 else if (line[1] == 'r') {
7230 *line = '\r';
7231 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007232 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007233 else if (line[1] == 'n') {
7234 *line = '\n';
7235 skip = 1;
7236 }
7237 else if (line[1] == 't') {
7238 *line = '\t';
7239 skip = 1;
7240 }
7241 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007242 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007243 unsigned char hex1, hex2;
7244 hex1 = toupper(line[2]) - '0';
7245 hex2 = toupper(line[3]) - '0';
7246 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7247 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7248 *line = (hex1<<4) + hex2;
7249 skip = 3;
7250 }
7251 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007252 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007253 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007254 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007255 } else if (line[1] == '"') {
7256 *line = '"';
7257 skip = 1;
7258 } else if (line[1] == '\'') {
7259 *line = '\'';
7260 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007261 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7262 *line = '$';
7263 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007264 }
7265 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007266 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007267 end -= skip;
7268 }
7269 line++;
7270 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007271 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007272 /* end of string, end of loop */
7273 *line = 0;
7274 break;
7275 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007276 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007277 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007278 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007279 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007280 line++;
7281 args[++arg] = line;
7282 }
William Lallemandb2f07452015-05-12 14:27:13 +02007283 else if (dquote && *line == '$') {
7284 /* environment variables are evaluated inside double quotes */
7285 char *var_beg;
7286 char *var_end;
7287 char save_char;
7288 char *value;
7289 int val_len;
7290 int newlinesize;
7291 int braces = 0;
7292
7293 var_beg = line + 1;
7294 var_end = var_beg;
7295
7296 if (*var_beg == '{') {
7297 var_beg++;
7298 var_end++;
7299 braces = 1;
7300 }
7301
7302 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007303 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 +02007304 err_code |= ERR_ALERT | ERR_FATAL;
7305 goto next_line; /* skip current line */
7306 }
7307
7308 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7309 var_end++;
7310
7311 save_char = *var_end;
7312 *var_end = '\0';
7313 value = getenv(var_beg);
7314 *var_end = save_char;
7315 val_len = value ? strlen(value) : 0;
7316
7317 if (braces) {
7318 if (*var_end == '}') {
7319 var_end++;
7320 braces = 0;
7321 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007322 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007323 err_code |= ERR_ALERT | ERR_FATAL;
7324 goto next_line; /* skip current line */
7325 }
7326 }
7327
7328 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7329
7330 /* if not enough space in thisline */
7331 if (newlinesize > linesize) {
7332 char *newline;
7333
7334 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7335 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007336 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007337 err_code |= ERR_ALERT | ERR_FATAL;
7338 goto next_line; /* slip current line */
7339 }
7340 /* recompute pointers if realloc returns a new pointer */
7341 if (newline != thisline) {
7342 int i;
7343 int diff;
7344
7345 for (i = 0; i <= arg; i++) {
7346 diff = args[i] - thisline;
7347 args[i] = newline + diff;
7348 }
7349
7350 diff = var_end - thisline;
7351 var_end = newline + diff;
7352 diff = end - thisline;
7353 end = newline + diff;
7354 diff = line - thisline;
7355 line = newline + diff;
7356 thisline = newline;
7357 }
7358 linesize = newlinesize;
7359 }
7360
7361 /* insert value inside the line */
7362 memmove(line + val_len, var_end, end - var_end + 1);
7363 memcpy(line, value, val_len);
7364 end += val_len - (var_end - line);
7365 line += val_len;
7366 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007367 else {
7368 line++;
7369 }
7370 }
William Lallemandb2f07452015-05-12 14:27:13 +02007371
William Lallemandf9873ba2015-05-05 17:37:14 +02007372 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007373 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007374 err_code |= ERR_ALERT | ERR_FATAL;
7375 }
7376
7377 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007378 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007379 err_code |= ERR_ALERT | ERR_FATAL;
7380 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007381
7382 /* empty line */
7383 if (!**args)
7384 continue;
7385
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007386 if (*line) {
7387 /* we had to stop due to too many args.
7388 * Let's terminate the string, print the offending part then cut the
7389 * last arg.
7390 */
7391 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7392 line++;
7393 *line = '\0';
7394
Christopher Faulet767a84b2017-11-24 16:50:31 +01007395 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7396 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007397 err_code |= ERR_ALERT | ERR_FATAL;
7398 args[arg] = line;
7399 }
7400
Willy Tarreau540abe42007-05-02 20:50:16 +02007401 /* zero out remaining args and ensure that at least one entry
7402 * is zeroed out.
7403 */
7404 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007405 args[arg] = line;
7406 }
7407
Willy Tarreau3842f002009-06-14 11:39:52 +02007408 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007409 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007410 char *tmp;
7411
Willy Tarreau3842f002009-06-14 11:39:52 +02007412 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007413 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007414 for (arg=0; *args[arg+1]; arg++)
7415 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007416 *tmp = '\0'; // fix the next arg to \0
7417 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007418 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007419 else if (!strcmp(args[0], "default")) {
7420 kwm = KWM_DEF;
7421 for (arg=0; *args[arg+1]; arg++)
7422 args[arg] = args[arg+1]; // shift args after inversion
7423 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007424
William Lallemand0f99e342011-10-12 17:50:54 +02007425 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7426 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007427 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007428 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007429 }
7430
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007431 /* detect section start */
7432 list_for_each_entry(ics, &sections, list) {
7433 if (strcmp(args[0], ics->section_name) == 0) {
7434 cursection = ics->section_name;
7435 cs = ics;
7436 break;
7437 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007438 }
7439
William Lallemandd2ff56d2017-10-16 11:06:50 +02007440 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007441 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007442 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007443 } else {
7444 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007445
William Lallemandd2ff56d2017-10-16 11:06:50 +02007446 if (pcs != cs && pcs && pcs->post_section_parser) {
7447 err_code |= pcs->post_section_parser();
7448 if (err_code & ERR_ABORT)
7449 goto err;
7450 }
7451
7452 err_code |= cs->section_parser(file, linenum, args, kwm);
7453 if (err_code & ERR_ABORT)
7454 goto err;
7455 }
7456 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007457 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007458
7459 if (pcs == cs && pcs && pcs->post_section_parser)
7460 err_code |= pcs->post_section_parser();
7461
7462err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007463 free(cfg_scope);
7464 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007465 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007466 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007467 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007468 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007469}
7470
Willy Tarreau64ab6072014-09-16 12:17:36 +02007471/* This function propagates processes from frontend <from> to backend <to> so
7472 * that it is always guaranteed that a backend pointed to by a frontend is
7473 * bound to all of its processes. After that, if the target is a "listen"
7474 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007475 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007476 * checked first to ensure that <to> is already bound to all processes of
7477 * <from>, there is no risk of looping and we ensure to follow the shortest
7478 * path to the destination.
7479 *
7480 * It is possible to set <to> to NULL for the first call so that the function
7481 * takes care of visiting the initial frontend in <from>.
7482 *
7483 * It is important to note that the function relies on the fact that all names
7484 * have already been resolved.
7485 */
7486void propagate_processes(struct proxy *from, struct proxy *to)
7487{
7488 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007489
7490 if (to) {
7491 /* check whether we need to go down */
7492 if (from->bind_proc &&
7493 (from->bind_proc & to->bind_proc) == from->bind_proc)
7494 return;
7495
7496 if (!from->bind_proc && !to->bind_proc)
7497 return;
7498
7499 to->bind_proc = from->bind_proc ?
7500 (to->bind_proc | from->bind_proc) : 0;
7501
7502 /* now propagate down */
7503 from = to;
7504 }
7505
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007506 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007507 return;
7508
Willy Tarreauf6b70012014-12-18 14:00:43 +01007509 if (from->state == PR_STSTOPPED)
7510 return;
7511
Willy Tarreau64ab6072014-09-16 12:17:36 +02007512 /* default_backend */
7513 if (from->defbe.be)
7514 propagate_processes(from, from->defbe.be);
7515
7516 /* use_backend */
7517 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007518 if (rule->dynamic)
7519 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007520 to = rule->be.backend;
7521 propagate_processes(from, to);
7522 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007523}
7524
Willy Tarreaubb925012009-07-23 13:36:36 +02007525/*
7526 * Returns the error code, 0 if OK, or any combination of :
7527 * - ERR_ABORT: must abort ASAP
7528 * - ERR_FATAL: we can continue parsing but not start the service
7529 * - ERR_WARN: a warning has been emitted
7530 * - ERR_ALERT: an alert has been emitted
7531 * Only the two first ones can stop processing, the two others are just
7532 * indicators.
7533 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007534int check_config_validity()
7535{
7536 int cfgerr = 0;
7537 struct proxy *curproxy = NULL;
7538 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007539 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007540 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007541 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007542 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007543 struct cfg_postparser *postparser;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007544
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007545 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007546 /*
7547 * Now, check for the integrity of all that we have collected.
7548 */
7549
7550 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007551 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007552
Willy Tarreau193b8c62012-11-22 00:17:38 +01007553 if (!global.tune.max_http_hdr)
7554 global.tune.max_http_hdr = MAX_HTTP_HDR;
7555
7556 if (!global.tune.cookie_len)
7557 global.tune.cookie_len = CAPTURE_LEN;
7558
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007559 if (!global.tune.requri_len)
7560 global.tune.requri_len = REQURI_LEN;
7561
Willy Tarreaubafbe012017-11-24 17:34:44 +01007562 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007563
Willy Tarreaubafbe012017-11-24 17:34:44 +01007564 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007565
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007566 /* Post initialisation of the users and groups lists. */
7567 err_code = userlist_postinit();
7568 if (err_code != ERR_NONE)
7569 goto out;
7570
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007571 /* first, we will invert the proxy list order */
7572 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007573 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007574 struct proxy *next;
7575
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007576 next = proxies_list->next;
7577 proxies_list->next = curproxy;
7578 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007579 if (!next)
7580 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007581 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007582 }
7583
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007584 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007585 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007586 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007587 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007588 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007589 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007590 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007591 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007592
Willy Tarreau050536d2012-10-04 08:47:34 +02007593 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007594 /* proxy ID not set, use automatic numbering with first
7595 * spare entry starting with next_pxid.
7596 */
7597 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7598 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7599 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007600 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007601 next_pxid++;
7602
Willy Tarreau55ea7572007-06-17 19:56:27 +02007603
Willy Tarreaubaaee002006-06-26 02:48:02 +02007604 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007605 /* ensure we don't keep listeners uselessly bound */
7606 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007607 free((void *)curproxy->table.peers.name);
7608 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007609 continue;
7610 }
7611
Willy Tarreau102df612014-05-07 23:56:38 +02007612 /* Check multi-process mode compatibility for the current proxy */
7613
7614 if (curproxy->bind_proc) {
7615 /* an explicit bind-process was specified, let's check how many
7616 * processes remain.
7617 */
David Carliere6c39412015-07-02 07:00:17 +00007618 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007619
7620 curproxy->bind_proc &= nbits(global.nbproc);
7621 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007622 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 +02007623 curproxy->bind_proc = 1;
7624 }
7625 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007626 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 +02007627 curproxy->bind_proc = 0;
7628 }
7629 }
7630
Willy Tarreau3d209582014-05-09 17:06:11 +02007631 /* check and reduce the bind-proc of each listener */
7632 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7633 unsigned long mask;
7634
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007635 /* HTTP frontends with "h2" as ALPN/NPN will work in
7636 * HTTP/2 and absolutely require buffers 16kB or larger.
7637 */
7638#ifdef USE_OPENSSL
7639 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7640#ifdef OPENSSL_NPN_NEGOTIATED
7641 /* check NPN */
7642 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007643 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",
7644 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007645 cfgerr++;
7646 }
7647#endif
7648#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7649 /* check ALPN */
7650 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007651 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",
7652 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007653 cfgerr++;
7654 }
7655#endif
7656 } /* HTTP && bufsize < 16384 */
7657#endif
7658
Willy Tarreau3d209582014-05-09 17:06:11 +02007659 if (!bind_conf->bind_proc)
7660 continue;
7661
7662 mask = nbits(global.nbproc);
7663 if (curproxy->bind_proc)
7664 mask &= curproxy->bind_proc;
7665 /* mask cannot be null here thanks to the previous checks */
7666
David Carliere6c39412015-07-02 07:00:17 +00007667 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007668 bind_conf->bind_proc &= mask;
7669
7670 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007671 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",
7672 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007673 bind_conf->bind_proc = mask & ~(mask - 1);
7674 }
7675 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007676 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",
7677 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007678 bind_conf->bind_proc = 0;
7679 }
7680 }
7681
Willy Tarreauff01a212009-03-15 13:46:16 +01007682 switch (curproxy->mode) {
7683 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007684 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007685 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007686 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7687 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007688 cfgerr++;
7689 }
7690
7691 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007692 ha_warning("config : servers will be ignored for %s '%s'.\n",
7693 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007694 break;
7695
7696 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007697 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007698 break;
7699
7700 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007701 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007702 break;
7703 }
7704
Willy Tarreauf3934b82015-08-11 11:36:45 +02007705 if ((curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007706 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7707 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007708 err_code |= ERR_WARN;
7709 }
7710
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007711 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007712 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007713 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007714 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7715 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007716 cfgerr++;
7717 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007718#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007719 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007720 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7721 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007722 cfgerr++;
7723 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007724#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007725 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007726 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7727 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007728 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007729 }
7730 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007731 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007732 /* If no LB algo is set in a backend, and we're not in
7733 * transparent mode, dispatch mode nor proxy mode, we
7734 * want to use balance roundrobin by default.
7735 */
7736 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7737 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007738 }
7739 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007740
Willy Tarreau1620ec32011-08-06 17:05:02 +02007741 if (curproxy->options & PR_O_DISPATCH)
7742 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7743 else if (curproxy->options & PR_O_HTTP_PROXY)
7744 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7745 else if (curproxy->options & PR_O_TRANSP)
7746 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007747
Willy Tarreau1620ec32011-08-06 17:05:02 +02007748 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7749 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007750 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7751 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007752 err_code |= ERR_WARN;
7753 curproxy->options &= ~PR_O_DISABLE404;
7754 }
7755 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007756 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7757 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007758 err_code |= ERR_WARN;
7759 curproxy->options &= ~PR_O2_CHK_SNDST;
7760 }
Willy Tarreauef781042010-01-27 11:53:01 +01007761 }
7762
Simon Horman98637e52014-06-20 12:30:16 +09007763 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7764 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007765 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7766 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007767 cfgerr++;
7768 }
7769 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007770 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7771 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007772 cfgerr++;
7773 }
7774 }
7775
Simon Horman64e34162015-02-06 11:11:57 +09007776 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007777 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007778 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7779 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7780 "'email-alert myhostname', or 'email-alert to' "
7781 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7782 "to be present).\n",
7783 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007784 err_code |= ERR_WARN;
7785 free_email_alert(curproxy);
7786 }
7787 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007788 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007789 }
7790
Simon Horman98637e52014-06-20 12:30:16 +09007791 if (curproxy->check_command) {
7792 int clear = 0;
7793 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007794 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7795 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007796 err_code |= ERR_WARN;
7797 clear = 1;
7798 }
7799 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007800 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7801 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007802 cfgerr++;
7803 }
7804 if (clear) {
7805 free(curproxy->check_command);
7806 curproxy->check_command = NULL;
7807 }
7808 }
7809
7810 if (curproxy->check_path) {
7811 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007812 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7813 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007814 err_code |= ERR_WARN;
7815 free(curproxy->check_path);
7816 curproxy->check_path = NULL;
7817 }
7818 }
7819
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007820 /* if a default backend was specified, let's find it */
7821 if (curproxy->defbe.name) {
7822 struct proxy *target;
7823
Willy Tarreauafb39922015-05-26 12:04:09 +02007824 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007825 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007826 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7827 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007828 cfgerr++;
7829 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007830 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7831 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007832 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007833 } else if (target->mode != curproxy->mode &&
7834 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7835
Christopher Faulet767a84b2017-11-24 16:50:31 +01007836 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7837 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7838 curproxy->conf.file, curproxy->conf.line,
7839 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7840 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007841 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007842 } else {
7843 free(curproxy->defbe.name);
7844 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007845 /* Update tot_fe_maxconn for a further fullconn's computation */
7846 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007847 /* Emit a warning if this proxy also has some servers */
7848 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007849 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7850 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007851 err_code |= ERR_WARN;
7852 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007853 }
7854 }
7855
Emeric Brun3f783572017-01-12 11:21:28 +01007856 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7857 /* Case of listen without default backend
7858 * The curproxy will be its own default backend
7859 * so we update tot_fe_maxconn for a further
7860 * fullconn's computation */
7861 curproxy->tot_fe_maxconn += curproxy->maxconn;
7862 }
7863
Willy Tarreau55ea7572007-06-17 19:56:27 +02007864 /* find the target proxy for 'use_backend' rules */
7865 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007866 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007867 struct logformat_node *node;
7868 char *pxname;
7869
7870 /* Try to parse the string as a log format expression. If the result
7871 * of the parsing is only one entry containing a simple string, then
7872 * it's a standard string corresponding to a static rule, thus the
7873 * parsing is cancelled and be.name is restored to be resolved.
7874 */
7875 pxname = rule->be.name;
7876 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007877 curproxy->conf.args.ctx = ARGC_UBK;
7878 curproxy->conf.args.file = rule->file;
7879 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007880 err = NULL;
7881 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007882 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7883 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007884 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007885 cfgerr++;
7886 continue;
7887 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007888 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7889
7890 if (!LIST_ISEMPTY(&rule->be.expr)) {
7891 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7892 rule->dynamic = 1;
7893 free(pxname);
7894 continue;
7895 }
7896 /* simple string: free the expression and fall back to static rule */
7897 free(node->arg);
7898 free(node);
7899 }
7900
7901 rule->dynamic = 0;
7902 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007903
Willy Tarreauafb39922015-05-26 12:04:09 +02007904 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007905 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007906 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7907 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007908 cfgerr++;
7909 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007910 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7911 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007912 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007913 } else if (target->mode != curproxy->mode &&
7914 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7915
Christopher Faulet767a84b2017-11-24 16:50:31 +01007916 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7917 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7918 curproxy->conf.file, curproxy->conf.line,
7919 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7920 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007921 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007922 } else {
7923 free((void *)rule->be.name);
7924 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007925 /* For each target of switching rules, we update
7926 * their tot_fe_maxconn, except if a previous rule point
7927 * on the same backend or on the default backend */
7928 if (rule->be.backend != curproxy->defbe.be) {
7929 struct switching_rule *swrule;
7930
7931 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7932 if (rule == swrule) {
7933 target->tot_fe_maxconn += curproxy->maxconn;
7934 break;
7935 }
7936 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7937 /* there is multiple ref of this backend */
7938 break;
7939 }
7940 }
7941 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007942 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007943 }
7944
Willy Tarreau64ab6072014-09-16 12:17:36 +02007945 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007946 list_for_each_entry(srule, &curproxy->server_rules, list) {
7947 struct server *target = findserver(curproxy, srule->srv.name);
7948
7949 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007950 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7951 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007952 cfgerr++;
7953 continue;
7954 }
7955 free((void *)srule->srv.name);
7956 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007957 }
7958
Emeric Brunb982a3d2010-01-04 15:45:53 +01007959 /* find the target table for 'stick' rules */
7960 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7961 struct proxy *target;
7962
Emeric Brun1d33b292010-01-04 15:47:17 +01007963 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7964 if (mrule->flags & STK_IS_STORE)
7965 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7966
Emeric Brunb982a3d2010-01-04 15:45:53 +01007967 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007968 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007969 else
7970 target = curproxy;
7971
7972 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007973 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7974 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007975 cfgerr++;
7976 }
7977 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007978 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7979 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007980 cfgerr++;
7981 }
Willy Tarreau12785782012-04-27 21:37:17 +02007982 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007983 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7984 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007985 cfgerr++;
7986 }
7987 else {
7988 free((void *)mrule->table.name);
7989 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007990 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007991 }
7992 }
7993
7994 /* find the target table for 'store response' rules */
7995 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7996 struct proxy *target;
7997
Emeric Brun1d33b292010-01-04 15:47:17 +01007998 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7999
Emeric Brunb982a3d2010-01-04 15:45:53 +01008000 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008001 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008002 else
8003 target = curproxy;
8004
8005 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008006 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
8007 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008008 cfgerr++;
8009 }
8010 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008011 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
8012 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008013 cfgerr++;
8014 }
Willy Tarreau12785782012-04-27 21:37:17 +02008015 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008016 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
8017 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008018 cfgerr++;
8019 }
8020 else {
8021 free((void *)mrule->table.name);
8022 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02008023 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008024 }
8025 }
8026
Christopher Faulete4e830d2017-09-18 14:51:41 +02008027 /* check validity for 'tcp-request' layer 4 rules */
8028 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
8029 err = NULL;
8030 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008031 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008032 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01008033 cfgerr++;
8034 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02008035 }
8036
Christopher Faulete4e830d2017-09-18 14:51:41 +02008037 /* check validity for 'tcp-request' layer 5 rules */
8038 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
8039 err = NULL;
8040 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008041 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008042 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008043 cfgerr++;
8044 }
8045 }
8046
Christopher Faulete4e830d2017-09-18 14:51:41 +02008047 /* check validity for 'tcp-request' layer 6 rules */
8048 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8049 err = NULL;
8050 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008051 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008052 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008053 cfgerr++;
8054 }
8055 }
8056
Christopher Faulete4e830d2017-09-18 14:51:41 +02008057 /* check validity for 'http-request' layer 7 rules */
8058 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
8059 err = NULL;
8060 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008061 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008062 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008063 cfgerr++;
8064 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008065 }
8066
Christopher Faulete4e830d2017-09-18 14:51:41 +02008067 /* check validity for 'http-response' layer 7 rules */
8068 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
8069 err = NULL;
8070 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008071 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008072 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02008073 cfgerr++;
8074 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008075 }
8076
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008077 /* move any "block" rules at the beginning of the http-request rules */
8078 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8079 /* insert block_rules into http_req_rules at the beginning */
8080 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8081 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8082 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8083 curproxy->http_req_rules.n = curproxy->block_rules.n;
8084 LIST_INIT(&curproxy->block_rules);
8085 }
8086
Emeric Brun32da3c42010-09-23 18:39:19 +02008087 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008088 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008089
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008090 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008091 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8092 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008093 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008094 break;
8095 }
8096 }
8097
8098 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008099 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8100 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008101 free((void *)curproxy->table.peers.name);
8102 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008103 cfgerr++;
8104 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008105 else if (curpeers->state == PR_STSTOPPED) {
8106 /* silently disable this peers section */
8107 curproxy->table.peers.p = NULL;
8108 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008109 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008110 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8111 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008112 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008113 cfgerr++;
8114 }
8115 }
8116
Simon Horman9dc49962015-01-30 11:22:59 +09008117
8118 if (curproxy->email_alert.mailers.name) {
8119 struct mailers *curmailers = mailers;
8120
8121 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008122 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008123 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008124 }
Simon Horman9dc49962015-01-30 11:22:59 +09008125 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008126 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8127 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008128 free_email_alert(curproxy);
8129 cfgerr++;
8130 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008131 else {
8132 err = NULL;
8133 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008134 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008135 free(err);
8136 cfgerr++;
8137 }
8138 }
Simon Horman9dc49962015-01-30 11:22:59 +09008139 }
8140
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008141 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008142 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008143 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008144 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8145 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008146 cfgerr++;
8147 goto out_uri_auth_compat;
8148 }
8149
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008150 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008151 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008152 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008153 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008154
Willy Tarreau95fa4692010-02-01 13:05:50 +01008155 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8156 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008157
8158 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008159 uri_auth_compat_req[i++] = "realm";
8160 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8161 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008162
Willy Tarreau95fa4692010-02-01 13:05:50 +01008163 uri_auth_compat_req[i++] = "unless";
8164 uri_auth_compat_req[i++] = "{";
8165 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8166 uri_auth_compat_req[i++] = "}";
8167 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008168
Willy Tarreauff011f22011-01-06 17:51:27 +01008169 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8170 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008171 cfgerr++;
8172 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008173 }
8174
Willy Tarreauff011f22011-01-06 17:51:27 +01008175 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008176
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008177 if (curproxy->uri_auth->auth_realm) {
8178 free(curproxy->uri_auth->auth_realm);
8179 curproxy->uri_auth->auth_realm = NULL;
8180 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008181
8182 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008183 }
8184out_uri_auth_compat:
8185
Dragan Dosen43885c72015-10-01 13:18:13 +02008186 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008187 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008188 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8189 if (!curproxy->conf.logformat_sd_string) {
8190 /* set the default logformat_sd_string */
8191 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8192 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008193 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008194 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008195 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008196
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008197 /* compile the log format */
8198 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008199 if (curproxy->conf.logformat_string != default_http_log_format &&
8200 curproxy->conf.logformat_string != default_tcp_log_format &&
8201 curproxy->conf.logformat_string != clf_http_log_format)
8202 free(curproxy->conf.logformat_string);
8203 curproxy->conf.logformat_string = NULL;
8204 free(curproxy->conf.lfs_file);
8205 curproxy->conf.lfs_file = NULL;
8206 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008207
8208 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8209 free(curproxy->conf.logformat_sd_string);
8210 curproxy->conf.logformat_sd_string = NULL;
8211 free(curproxy->conf.lfsd_file);
8212 curproxy->conf.lfsd_file = NULL;
8213 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008214 }
8215
Willy Tarreau62a61232013-04-12 18:13:46 +02008216 if (curproxy->conf.logformat_string) {
8217 curproxy->conf.args.ctx = ARGC_LOG;
8218 curproxy->conf.args.file = curproxy->conf.lfs_file;
8219 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008220 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008221 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008222 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008223 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8224 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008225 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008226 cfgerr++;
8227 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008228 curproxy->conf.args.file = NULL;
8229 curproxy->conf.args.line = 0;
8230 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008231
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008232 if (curproxy->conf.logformat_sd_string) {
8233 curproxy->conf.args.ctx = ARGC_LOGSD;
8234 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8235 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008236 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008237 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 +01008238 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008239 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8240 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008241 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008242 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008243 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008244 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8245 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008246 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008247 cfgerr++;
8248 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008249 curproxy->conf.args.file = NULL;
8250 curproxy->conf.args.line = 0;
8251 }
8252
Willy Tarreau62a61232013-04-12 18:13:46 +02008253 if (curproxy->conf.uniqueid_format_string) {
8254 curproxy->conf.args.ctx = ARGC_UIF;
8255 curproxy->conf.args.file = curproxy->conf.uif_file;
8256 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008257 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008258 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 +01008259 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008260 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8261 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008262 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008263 cfgerr++;
8264 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008265 curproxy->conf.args.file = NULL;
8266 curproxy->conf.args.line = 0;
8267 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008268
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008269 /* only now we can check if some args remain unresolved.
8270 * This must be done after the users and groups resolution.
8271 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008272 cfgerr += smp_resolve_args(curproxy);
8273 if (!cfgerr)
8274 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008275
Willy Tarreau2738a142006-07-08 17:28:09 +02008276 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008277 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008278 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008279 (!curproxy->timeout.connect ||
8280 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008281 ha_warning("config : missing timeouts for %s '%s'.\n"
8282 " | While not properly invalid, you will certainly encounter various problems\n"
8283 " | with such a configuration. To fix this, please ensure that all following\n"
8284 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8285 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008286 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008287 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008288
Willy Tarreau1fa31262007-12-03 00:36:16 +01008289 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8290 * We must still support older configurations, so let's find out whether those
8291 * parameters have been set or must be copied from contimeouts.
8292 */
8293 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008294 if (!curproxy->timeout.tarpit ||
8295 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008296 /* tarpit timeout not set. We search in the following order:
8297 * default.tarpit, curr.connect, default.connect.
8298 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008299 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008300 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008301 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008302 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008303 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008304 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008305 }
8306 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008307 (!curproxy->timeout.queue ||
8308 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008309 /* queue timeout not set. We search in the following order:
8310 * default.queue, curr.connect, default.connect.
8311 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008312 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008313 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008314 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008315 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008316 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008317 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008318 }
8319 }
8320
Willy Tarreau1620ec32011-08-06 17:05:02 +02008321 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008322 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008323 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008324 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008325 }
8326
Willy Tarreau215663d2014-06-13 18:30:23 +02008327 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8328 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008329 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8330 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008331 err_code |= ERR_WARN;
8332 }
8333
Willy Tarreau193b8c62012-11-22 00:17:38 +01008334 /* ensure that cookie capture length is not too large */
8335 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008336 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8337 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008338 err_code |= ERR_WARN;
8339 curproxy->capture_len = global.tune.cookie_len - 1;
8340 }
8341
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008342 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008343 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008344 curproxy->req_cap_pool = create_pool("ptrcap",
8345 curproxy->nb_req_cap * sizeof(char *),
8346 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008347 }
8348
8349 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008350 curproxy->rsp_cap_pool = create_pool("ptrcap",
8351 curproxy->nb_rsp_cap * sizeof(char *),
8352 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008353 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008354
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008355 switch (curproxy->load_server_state_from_file) {
8356 case PR_SRV_STATE_FILE_UNSPEC:
8357 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8358 break;
8359 case PR_SRV_STATE_FILE_GLOBAL:
8360 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008361 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",
8362 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008363 err_code |= ERR_WARN;
8364 }
8365 break;
8366 }
8367
Willy Tarreaubaaee002006-06-26 02:48:02 +02008368 /* first, we will invert the servers list order */
8369 newsrv = NULL;
8370 while (curproxy->srv) {
8371 struct server *next;
8372
8373 next = curproxy->srv->next;
8374 curproxy->srv->next = newsrv;
8375 newsrv = curproxy->srv;
8376 if (!next)
8377 break;
8378 curproxy->srv = next;
8379 }
8380
Willy Tarreau17edc812014-01-03 12:14:34 +01008381 /* Check that no server name conflicts. This causes trouble in the stats.
8382 * We only emit a warning for the first conflict affecting each server,
8383 * in order to avoid combinatory explosion if all servers have the same
8384 * name. We do that only for servers which do not have an explicit ID,
8385 * because these IDs were made also for distinguishing them and we don't
8386 * want to annoy people who correctly manage them.
8387 */
8388 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8389 struct server *other_srv;
8390
8391 if (newsrv->puid)
8392 continue;
8393
8394 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8395 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008396 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",
8397 newsrv->conf.file, newsrv->conf.line,
8398 proxy_type_str(curproxy), curproxy->id,
8399 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008400 break;
8401 }
8402 }
8403 }
8404
Willy Tarreaudd701652010-05-25 23:03:02 +02008405 /* assign automatic UIDs to servers which don't have one yet */
8406 next_id = 1;
8407 newsrv = curproxy->srv;
8408 while (newsrv != NULL) {
8409 if (!newsrv->puid) {
8410 /* server ID not set, use automatic numbering with first
8411 * spare entry starting with next_svid.
8412 */
8413 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8414 newsrv->conf.id.key = newsrv->puid = next_id;
8415 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8416 }
8417 next_id++;
8418 newsrv = newsrv->next;
8419 }
8420
Willy Tarreau20697042007-11-15 23:26:18 +01008421 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008422 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008423
Willy Tarreau62c3be22012-01-20 13:12:32 +01008424 /*
8425 * If this server supports a maxconn parameter, it needs a dedicated
8426 * tasks to fill the emptied slots when a connection leaves.
8427 * Also, resolve deferred tracking dependency if needed.
8428 */
8429 newsrv = curproxy->srv;
8430 while (newsrv != NULL) {
8431 if (newsrv->minconn > newsrv->maxconn) {
8432 /* Only 'minconn' was specified, or it was higher than or equal
8433 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8434 * this will avoid further useless expensive computations.
8435 */
8436 newsrv->maxconn = newsrv->minconn;
8437 } else if (newsrv->maxconn && !newsrv->minconn) {
8438 /* minconn was not specified, so we set it to maxconn */
8439 newsrv->minconn = newsrv->maxconn;
8440 }
8441
Willy Tarreau17d45382016-12-22 21:16:08 +01008442 /* this will also properly set the transport layer for prod and checks */
8443 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8444 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8445 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8446 }
Emeric Brun94324a42012-10-11 14:00:19 +02008447
Willy Tarreau2f075e92013-12-03 11:11:34 +01008448 /* set the check type on the server */
8449 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8450
Willy Tarreau62c3be22012-01-20 13:12:32 +01008451 if (newsrv->trackit) {
8452 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008453 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008454 char *pname, *sname;
8455
8456 pname = newsrv->trackit;
8457 sname = strrchr(pname, '/');
8458
8459 if (sname)
8460 *sname++ = '\0';
8461 else {
8462 sname = pname;
8463 pname = NULL;
8464 }
8465
8466 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008467 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008468 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008469 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8470 proxy_type_str(curproxy), curproxy->id,
8471 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008472 cfgerr++;
8473 goto next_srv;
8474 }
8475 } else
8476 px = curproxy;
8477
8478 srv = findserver(px, sname);
8479 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008480 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8481 proxy_type_str(curproxy), curproxy->id,
8482 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008483 cfgerr++;
8484 goto next_srv;
8485 }
8486
Willy Tarreau32091232014-05-16 13:52:00 +02008487 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8488 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8489 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008490 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8491 "tracking as it does not have any check nor agent enabled.\n",
8492 proxy_type_str(curproxy), curproxy->id,
8493 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008494 cfgerr++;
8495 goto next_srv;
8496 }
8497
8498 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8499
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008500 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008501 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8502 "belongs to a tracking chain looping back to %s/%s.\n",
8503 proxy_type_str(curproxy), curproxy->id,
8504 newsrv->id, px->id, srv->id, px->id,
8505 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008506 cfgerr++;
8507 goto next_srv;
8508 }
8509
8510 if (curproxy != px &&
8511 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008512 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8513 "tracking: disable-on-404 option inconsistency.\n",
8514 proxy_type_str(curproxy), curproxy->id,
8515 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008516 cfgerr++;
8517 goto next_srv;
8518 }
8519
Willy Tarreau62c3be22012-01-20 13:12:32 +01008520 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008521 newsrv->tracknext = srv->trackers;
8522 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008523
8524 free(newsrv->trackit);
8525 newsrv->trackit = NULL;
8526 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008527
Willy Tarreau62c3be22012-01-20 13:12:32 +01008528 next_srv:
8529 newsrv = newsrv->next;
8530 }
8531
Olivier Houchard4e694042017-03-14 20:01:29 +01008532 /*
8533 * Try to generate dynamic cookies for servers now.
8534 * It couldn't be done earlier, since at the time we parsed
8535 * the server line, we may not have known yet that we
8536 * should use dynamic cookies, or the secret key may not
8537 * have been provided yet.
8538 */
8539 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8540 newsrv = curproxy->srv;
8541 while (newsrv != NULL) {
8542 srv_set_dyncookie(newsrv);
8543 newsrv = newsrv->next;
8544 }
8545
8546 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008547 /* We have to initialize the server lookup mechanism depending
8548 * on what LB algorithm was choosen.
8549 */
8550
8551 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8552 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8553 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008554 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8555 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8556 init_server_map(curproxy);
8557 } else {
8558 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8559 fwrr_init_server_groups(curproxy);
8560 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008561 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008562
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008563 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008564 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8565 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8566 fwlc_init_server_tree(curproxy);
8567 } else {
8568 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8569 fas_init_server_tree(curproxy);
8570 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008571 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008572
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008573 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008574 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8575 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8576 chash_init_server_tree(curproxy);
8577 } else {
8578 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8579 init_server_map(curproxy);
8580 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008581 break;
8582 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008583 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008584
8585 if (curproxy->options & PR_O_LOGASAP)
8586 curproxy->to_log &= ~LW_BYTES;
8587
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008588 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008589 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8590 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008591 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8592 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008593 err_code |= ERR_WARN;
8594 }
8595
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008596 if (curproxy->mode != PR_MODE_HTTP) {
8597 int optnum;
8598
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008599 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008600 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8601 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008602 err_code |= ERR_WARN;
8603 curproxy->uri_auth = NULL;
8604 }
8605
Willy Tarreaude7dc882017-03-10 11:49:21 +01008606 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008607 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8608 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008609 err_code |= ERR_WARN;
8610 }
8611
8612 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008613 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8614 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008615 err_code |= ERR_WARN;
8616 }
8617
8618 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008619 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8620 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008621 err_code |= ERR_WARN;
8622 }
8623
8624 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008625 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8626 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008627 err_code |= ERR_WARN;
8628 }
8629
8630 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008631 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8632 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008633 err_code |= ERR_WARN;
8634 }
8635
Willy Tarreau87cf5142011-08-19 22:57:24 +02008636 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008637 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8638 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008639 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008640 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008641 }
8642
8643 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008644 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8645 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008646 err_code |= ERR_WARN;
8647 curproxy->options &= ~PR_O_ORGTO;
8648 }
8649
8650 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8651 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8652 (curproxy->cap & cfg_opts[optnum].cap) &&
8653 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008654 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8655 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008656 err_code |= ERR_WARN;
8657 curproxy->options &= ~cfg_opts[optnum].val;
8658 }
8659 }
8660
8661 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8662 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8663 (curproxy->cap & cfg_opts2[optnum].cap) &&
8664 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008665 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8666 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008667 err_code |= ERR_WARN;
8668 curproxy->options2 &= ~cfg_opts2[optnum].val;
8669 }
8670 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008671
Willy Tarreau29fbe512015-08-20 19:35:14 +02008672#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008673 if (curproxy->conn_src.bind_hdr_occ) {
8674 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008675 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8676 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008677 err_code |= ERR_WARN;
8678 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008679#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008680 }
8681
Willy Tarreaubaaee002006-06-26 02:48:02 +02008682 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008683 * ensure that we're not cross-dressing a TCP server into HTTP.
8684 */
8685 newsrv = curproxy->srv;
8686 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008687 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008688 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8689 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008690 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008691 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008692
Willy Tarreau0cec3312011-10-31 13:49:26 +01008693 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008694 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8695 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008696 err_code |= ERR_WARN;
8697 }
8698
Willy Tarreauc93cd162014-05-13 15:54:22 +02008699 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008700 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8701 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008702 err_code |= ERR_WARN;
8703 }
8704
Willy Tarreau29fbe512015-08-20 19:35:14 +02008705#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008706 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8707 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008708 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8709 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008710 err_code |= ERR_WARN;
8711 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008712#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008713
8714 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8715 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8716 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8717 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8718 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008719 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",
8720 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008721 err_code |= ERR_WARN;
8722 }
8723
8724
8725 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008726 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",
8727 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008728 err_code |= ERR_WARN;
8729 }
8730 }
8731
Willy Tarreau21d2af32008-02-14 20:25:24 +01008732 newsrv = newsrv->next;
8733 }
8734
Willy Tarreaue42bd962014-09-16 16:21:19 +02008735 /* check if we have a frontend with "tcp-request content" looking at L7
8736 * with no inspect-delay
8737 */
8738 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008739 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8740 if (arule->action == ACT_TCP_CAPTURE &&
8741 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008742 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008743 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8744 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008745 break;
8746 }
8747
Christopher Faulete4e830d2017-09-18 14:51:41 +02008748 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008749 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8750 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8751 " This means that these rules will randomly find their contents. This can be fixed by"
8752 " setting the tcp-request inspect-delay.\n",
8753 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008754 err_code |= ERR_WARN;
8755 }
8756 }
8757
Christopher Fauletd7c91962015-04-30 11:48:27 +02008758 /* Check filter configuration, if any */
8759 cfgerr += flt_check(curproxy);
8760
Willy Tarreauc1a21672009-08-16 22:37:44 +02008761 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008762 if (!curproxy->accept)
8763 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008764
Willy Tarreauc1a21672009-08-16 22:37:44 +02008765 if (curproxy->tcp_req.inspect_delay ||
8766 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008767 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008768
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008769 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008770 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008771 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008772 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008773
8774 /* both TCP and HTTP must check switching rules */
8775 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008776
8777 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008778 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008779 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8780 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 +01008781 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008782 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8783 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008784 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008785 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008786 }
8787
8788 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008789 if (curproxy->tcp_req.inspect_delay ||
8790 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8791 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8792
Emeric Brun97679e72010-09-23 17:56:44 +02008793 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8794 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8795
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008796 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008797 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008798 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008799 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008800
8801 /* If the backend does requires RDP cookie persistence, we have to
8802 * enable the corresponding analyser.
8803 */
8804 if (curproxy->options2 & PR_O2_RDPC_PRST)
8805 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008806
8807 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008808 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008809 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8810 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 +01008811 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008812 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8813 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008814 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008815 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008816 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008817 }
8818
8819 /***********************************************************/
8820 /* At this point, target names have already been resolved. */
8821 /***********************************************************/
8822
8823 /* Check multi-process mode compatibility */
8824
8825 if (global.nbproc > 1 && global.stats_fe) {
8826 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8827 unsigned long mask;
8828
8829 mask = nbits(global.nbproc);
8830 if (global.stats_fe->bind_proc)
8831 mask &= global.stats_fe->bind_proc;
8832
8833 if (bind_conf->bind_proc)
8834 mask &= bind_conf->bind_proc;
8835
8836 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008837 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008838 break;
8839 }
8840 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008841 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 +02008842 }
8843 }
8844
8845 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008846 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008847 if (curproxy->bind_proc)
8848 continue;
8849
8850 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8851 unsigned long mask;
8852
Willy Tarreaue428b082015-05-04 21:57:58 +02008853 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008854 curproxy->bind_proc |= mask;
8855 }
8856
8857 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008858 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008859 }
8860
8861 if (global.stats_fe) {
8862 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8863 unsigned long mask;
8864
Cyril Bonté06181952016-02-24 00:14:54 +01008865 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008866 global.stats_fe->bind_proc |= mask;
8867 }
8868 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008869 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008870 }
8871
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008872 /* propagate bindings from frontends to backends. Don't do it if there
8873 * are any fatal errors as we must not call it with unresolved proxies.
8874 */
8875 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008876 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008877 if (curproxy->cap & PR_CAP_FE)
8878 propagate_processes(curproxy, NULL);
8879 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008880 }
8881
8882 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008883 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008884 if (curproxy->bind_proc)
8885 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008886 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008887 }
8888
8889 /*******************************************************/
8890 /* At this step, all proxies have a non-null bind_proc */
8891 /*******************************************************/
8892
8893 /* perform the final checks before creating tasks */
8894
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008895 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008896 struct listener *listener;
8897 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008898
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008899 /* Configure SSL for each bind line.
8900 * Note: if configuration fails at some point, the ->ctx member
8901 * remains NULL so that listeners can later detach.
8902 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008903 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008904 if (bind_conf->xprt->prepare_bind_conf &&
8905 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008906 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008907 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008908
Willy Tarreaue6b98942007-10-29 01:09:36 +01008909 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008910 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008911 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008912 int nbproc;
8913
8914 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008915 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008916 nbits(global.nbproc));
8917
8918 if (!nbproc) /* no intersection between listener and frontend */
8919 nbproc = 1;
8920
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008921 if (!listener->luid) {
8922 /* listener ID not set, use automatic numbering with first
8923 * spare entry starting with next_luid.
8924 */
8925 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8926 listener->conf.id.key = listener->luid = next_id;
8927 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008928 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008929 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008930
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008931 /* enable separate counters */
8932 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008933 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008934 if (!listener->name)
8935 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008936 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008937
Willy Tarreaue6b98942007-10-29 01:09:36 +01008938 if (curproxy->options & PR_O_TCP_NOLING)
8939 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008940 if (!listener->maxconn)
8941 listener->maxconn = curproxy->maxconn;
8942 if (!listener->backlog)
8943 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008944 if (!listener->maxaccept)
8945 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8946
8947 /* we want to have an optimal behaviour on single process mode to
8948 * maximize the work at once, but in multi-process we want to keep
8949 * some fairness between processes, so we target half of the max
8950 * number of events to be balanced over all the processes the proxy
8951 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8952 * used to disable the limit.
8953 */
8954 if (listener->maxaccept > 0) {
8955 if (nbproc > 1)
8956 listener->maxaccept = (listener->maxaccept + 1) / 2;
8957 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8958 }
8959
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008960 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008961 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008962 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008963
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008964 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008965 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008966
Willy Tarreau620408f2016-10-21 16:37:51 +02008967 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8968 listener->options |= LI_O_TCP_L5_RULES;
8969
Willy Tarreaude3041d2010-05-31 10:56:17 +02008970 if (curproxy->mon_mask.s_addr)
8971 listener->options |= LI_O_CHK_MONNET;
8972
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008973 /* smart accept mode is automatic in HTTP mode */
8974 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008975 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008976 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8977 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008978 }
8979
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008980 /* Release unused SSL configs */
8981 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008982 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8983 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008984 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008985
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008986 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008987 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008988 int count, maxproc = 0;
8989
8990 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008991 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008992 if (count > maxproc)
8993 maxproc = count;
8994 }
8995 /* backends have 0, frontends have 1 or more */
8996 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008997 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8998 " limited to process assigned to the current request.\n",
8999 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02009000
Willy Tarreau102df612014-05-07 23:56:38 +02009001 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009002 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
9003 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009004 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009005 }
Willy Tarreau102df612014-05-07 23:56:38 +02009006 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009007 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
9008 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01009009 }
9010 }
Willy Tarreau918ff602011-07-25 16:33:49 +02009011
9012 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02009013 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02009014 if (curproxy->task) {
9015 curproxy->task->context = curproxy;
9016 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02009017 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009018 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
9019 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02009020 cfgerr++;
9021 }
Willy Tarreaub369a042014-09-16 13:21:03 +02009022 }
9023
Willy Tarreaufbb78422011-06-05 15:38:35 +02009024 /* automatically compute fullconn if not set. We must not do it in the
9025 * loop above because cross-references are not yet fully resolved.
9026 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009027 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009028 /* If <fullconn> is not set, let's set it to 10% of the sum of
9029 * the possible incoming frontend's maxconns.
9030 */
9031 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009032 /* we have the sum of the maxconns in <total>. We only
9033 * keep 10% of that sum to set the default fullconn, with
9034 * a hard minimum of 1 (to avoid a divide by zero).
9035 */
Emeric Brun3f783572017-01-12 11:21:28 +01009036 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02009037 if (!curproxy->fullconn)
9038 curproxy->fullconn = 1;
9039 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01009040 }
9041
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009042 /*
9043 * Recount currently required checks.
9044 */
9045
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009046 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009047 int optnum;
9048
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009049 for (optnum = 0; cfg_opts[optnum].name; optnum++)
9050 if (curproxy->options & cfg_opts[optnum].val)
9051 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009052
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009053 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
9054 if (curproxy->options2 & cfg_opts2[optnum].val)
9055 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009056 }
9057
Willy Tarreau0fca4832015-05-01 19:12:05 +02009058 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009059 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02009060 if (curproxy->table.peers.p)
9061 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
9062
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009063 if (cfg_peers) {
9064 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02009065 struct peer *p, *pb;
9066
Willy Tarreau1e273012015-05-01 19:15:17 +02009067 /* Remove all peers sections which don't have a valid listener,
9068 * which are not used by any table, or which are bound to more
9069 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009070 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009071 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009072 while (*last) {
9073 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009074
9075 if (curpeers->state == PR_STSTOPPED) {
9076 /* the "disabled" keyword was present */
9077 if (curpeers->peers_fe)
9078 stop_proxy(curpeers->peers_fe);
9079 curpeers->peers_fe = NULL;
9080 }
9081 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009082 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9083 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009084 }
David Carliere6c39412015-07-02 07:00:17 +00009085 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009086 /* either it's totally stopped or too much used */
9087 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009088 ha_alert("Peers section '%s': peers referenced by sections "
9089 "running in different processes (%d different ones). "
9090 "Check global.nbproc and all tables' bind-process "
9091 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009092 cfgerr++;
9093 }
9094 stop_proxy(curpeers->peers_fe);
9095 curpeers->peers_fe = NULL;
9096 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009097 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009098 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009099 last = &curpeers->next;
9100 continue;
9101 }
9102
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009103 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009104 p = curpeers->remote;
9105 while (p) {
9106 pb = p->next;
9107 free(p->id);
9108 free(p);
9109 p = pb;
9110 }
9111
9112 /* Destroy and unlink this curpeers section.
9113 * Note: curpeers is backed up into *last.
9114 */
9115 free(curpeers->id);
9116 curpeers = curpeers->next;
9117 free(*last);
9118 *last = curpeers;
9119 }
9120 }
9121
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009122 /* initialize stick-tables on backend capable proxies. This must not
9123 * be done earlier because the data size may be discovered while parsing
9124 * other proxies.
9125 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009126 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009127 if (curproxy->state == PR_STSTOPPED)
9128 continue;
9129
9130 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009131 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009132 cfgerr++;
9133 }
9134 }
9135
Simon Horman0d16a402015-01-30 11:22:58 +09009136 if (mailers) {
9137 struct mailers *curmailers = mailers, **last;
9138 struct mailer *m, *mb;
9139
9140 /* Remove all mailers sections which don't have a valid listener.
9141 * This can happen when a mailers section is never referenced.
9142 */
9143 last = &mailers;
9144 while (*last) {
9145 curmailers = *last;
9146 if (curmailers->users) {
9147 last = &curmailers->next;
9148 continue;
9149 }
9150
Christopher Faulet767a84b2017-11-24 16:50:31 +01009151 ha_warning("Removing incomplete section 'mailers %s'.\n",
9152 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009153
9154 m = curmailers->mailer_list;
9155 while (m) {
9156 mb = m->next;
9157 free(m->id);
9158 free(m);
9159 m = mb;
9160 }
9161
9162 /* Destroy and unlink this curmailers section.
9163 * Note: curmailers is backed up into *last.
9164 */
9165 free(curmailers->id);
9166 curmailers = curmailers->next;
9167 free(*last);
9168 *last = curmailers;
9169 }
9170 }
9171
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009172 /* Update server_state_file_name to backend name if backend is supposed to use
9173 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009174 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009175 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9176 curproxy->server_state_file_name == NULL)
9177 curproxy->server_state_file_name = strdup(curproxy->id);
9178 }
9179
Willy Tarreaubafbe012017-11-24 17:34:44 +01009180 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009181 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009182 MEM_F_SHARED);
9183
William Lallemand48b4bb42017-10-23 14:36:34 +02009184 list_for_each_entry(postparser, &postparsers, list) {
9185 if (postparser->func)
9186 cfgerr += postparser->func();
9187 }
9188
Willy Tarreaubb925012009-07-23 13:36:36 +02009189 if (cfgerr > 0)
9190 err_code |= ERR_ALERT | ERR_FATAL;
9191 out:
9192 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009193}
9194
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009195/*
9196 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9197 * parsing sessions.
9198 */
9199void cfg_register_keywords(struct cfg_kw_list *kwl)
9200{
9201 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9202}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009203
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009204/*
9205 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9206 */
9207void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9208{
9209 LIST_DEL(&kwl->list);
9210 LIST_INIT(&kwl->list);
9211}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009212
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009213/* this function register new section in the haproxy configuration file.
9214 * <section_name> is the name of this new section and <section_parser>
9215 * is the called parser. If two section declaration have the same name,
9216 * only the first declared is used.
9217 */
9218int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009219 int (*section_parser)(const char *, int, char **, int),
9220 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009221{
9222 struct cfg_section *cs;
9223
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009224 list_for_each_entry(cs, &sections, list) {
9225 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009226 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009227 return 0;
9228 }
9229 }
9230
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009231 cs = calloc(1, sizeof(*cs));
9232 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009233 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009234 return 0;
9235 }
9236
9237 cs->section_name = section_name;
9238 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009239 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009240
9241 LIST_ADDQ(&sections, &cs->list);
9242
9243 return 1;
9244}
9245
William Lallemand48b4bb42017-10-23 14:36:34 +02009246/* this function register a new function which will be called once the haproxy
9247 * configuration file has been parsed. It's useful to check dependencies
9248 * between sections or to resolve items once everything is parsed.
9249 */
9250int cfg_register_postparser(char *name, int (*func)())
9251{
9252 struct cfg_postparser *cp;
9253
9254 cp = calloc(1, sizeof(*cp));
9255 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009256 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009257 return 0;
9258 }
9259 cp->name = name;
9260 cp->func = func;
9261
9262 LIST_ADDQ(&postparsers, &cp->list);
9263
9264 return 1;
9265}
9266
Willy Tarreaubaaee002006-06-26 02:48:02 +02009267/*
David Carlier845efb52015-09-25 11:49:18 +01009268 * free all config section entries
9269 */
9270void cfg_unregister_sections(void)
9271{
9272 struct cfg_section *cs, *ics;
9273
9274 list_for_each_entry_safe(cs, ics, &sections, list) {
9275 LIST_DEL(&cs->list);
9276 free(cs);
9277 }
9278}
9279
Christopher Faulet7110b402016-10-26 11:09:44 +02009280void cfg_backup_sections(struct list *backup_sections)
9281{
9282 struct cfg_section *cs, *ics;
9283
9284 list_for_each_entry_safe(cs, ics, &sections, list) {
9285 LIST_DEL(&cs->list);
9286 LIST_ADDQ(backup_sections, &cs->list);
9287 }
9288}
9289
9290void cfg_restore_sections(struct list *backup_sections)
9291{
9292 struct cfg_section *cs, *ics;
9293
9294 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9295 LIST_DEL(&cs->list);
9296 LIST_ADDQ(&sections, &cs->list);
9297 }
9298}
9299
Willy Tarreau659fbf02016-05-26 17:55:28 +02009300__attribute__((constructor))
9301static void cfgparse_init(void)
9302{
9303 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009304 cfg_register_section("listen", cfg_parse_listen, NULL);
9305 cfg_register_section("frontend", cfg_parse_listen, NULL);
9306 cfg_register_section("backend", cfg_parse_listen, NULL);
9307 cfg_register_section("defaults", cfg_parse_listen, NULL);
9308 cfg_register_section("global", cfg_parse_global, NULL);
9309 cfg_register_section("userlist", cfg_parse_users, NULL);
9310 cfg_register_section("peers", cfg_parse_peers, NULL);
9311 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9312 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9313 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009314}
9315
David Carlier845efb52015-09-25 11:49:18 +01009316/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009317 * Local variables:
9318 * c-indent-level: 8
9319 * c-basic-offset: 8
9320 * End:
9321 */