blob: 37bbf45313299ed44f4a53747458040f02b348d1 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Configuration parser
3 *
Willy Tarreauff011f22011-01-06 17:51:27 +01004 * Copyright 2000-2011 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Cyril Bonté1a0191d2014-08-29 20:20:02 +020013#ifdef CONFIG_HAP_CRYPT
14/* This is to have crypt() defined on Linux */
15#define _GNU_SOURCE
16
17#ifdef NEED_CRYPT_H
18/* some platforms such as Solaris need this */
19#include <crypt.h>
20#endif
21#endif /* CONFIG_HAP_CRYPT */
22
Willy Tarreaubaaee002006-06-26 02:48:02 +020023#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <netdb.h>
27#include <ctype.h>
Willy Tarreau95c20ac2007-03-25 15:39:23 +020028#include <pwd.h>
29#include <grp.h>
Willy Tarreau0b4ed902007-03-26 00:18:40 +020030#include <errno.h>
Willy Tarreau3f49b302007-06-11 00:29:26 +020031#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <unistd.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035
Willy Tarreau2dd0d472006-06-29 17:53:05 +020036#include <common/cfgparse.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020037#include <common/chunk.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020038#include <common/config.h>
Willy Tarreau058e9072009-07-20 09:30:05 +020039#include <common/errors.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020040#include <common/memory.h>
41#include <common/standard.h>
42#include <common/time.h>
43#include <common/uri_auth.h>
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +010044#include <common/namespace.h>
Emeric Brunc60def82017-09-27 14:59:38 +020045#include <common/hathreads.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020046
47#include <types/capture.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020048#include <types/compression.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020049#include <types/filters.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020050#include <types/global.h>
Willy Tarreau3fdb3662012-11-12 00:42:33 +010051#include <types/obj_type.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020052#include <types/peers.h>
Simon Horman0d16a402015-01-30 11:22:58 +090053#include <types/mailers.h>
Baptiste Assmann325137d2015-04-13 23:40:55 +020054#include <types/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010055#include <types/stats.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020056
Willy Tarreaueb0c6142007-05-07 00:53:22 +020057#include <proto/acl.h>
Christopher Faulet4fce0d82017-09-18 11:57:31 +020058#include <proto/action.h>
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +010059#include <proto/auth.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020060#include <proto/backend.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020061#include <proto/channel.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020062#include <proto/checks.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020063#include <proto/compression.h>
Baptiste Assmann201c07f2017-05-22 15:17:15 +020064#include <proto/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010065#include <proto/stats.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020066#include <proto/filters.h>
Willy Tarreaueb472682010-05-28 18:46:57 +020067#include <proto/frontend.h>
Willy Tarreau34eb6712011-10-24 18:15:04 +020068#include <proto/hdr_idx.h>
Willy Tarreau6b2e11b2009-10-01 07:52:15 +020069#include <proto/lb_chash.h>
Willy Tarreauf09c6602012-02-13 17:12:08 +010070#include <proto/lb_fas.h>
Willy Tarreauf89c1872009-10-01 11:19:37 +020071#include <proto/lb_fwlc.h>
72#include <proto/lb_fwrr.h>
73#include <proto/lb_map.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020074#include <proto/listener.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020075#include <proto/log.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020076#include <proto/protocol.h>
Willy Tarreaue6b98942007-10-29 01:09:36 +010077#include <proto/proto_http.h>
Willy Tarreau2b5652f2006-12-31 17:46:05 +010078#include <proto/proxy.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020079#include <proto/peers.h>
Willy Tarreaucd3b0942012-04-27 21:52:18 +020080#include <proto/sample.h>
Willy Tarreau9903f0e2015-04-04 18:50:31 +020081#include <proto/session.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020082#include <proto/server.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020083#include <proto/stream.h>
Emeric Brunb982a3d2010-01-04 15:45:53 +010084#include <proto/stick_table.h>
Willy Tarreau39713102016-11-25 15:49:32 +010085#include <proto/task.h>
86#include <proto/tcp_rules.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020087
88
Willy Tarreauf3c69202006-07-09 16:42:34 +020089/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
90 * ssl-hello-chk option to ensure that the remote server speaks SSL.
91 *
92 * Check RFC 2246 (TLSv1.0) sections A.3 and A.4 for details.
93 */
94const char sslv3_client_hello_pkt[] = {
95 "\x16" /* ContentType : 0x16 = Hanshake */
96 "\x03\x00" /* ProtocolVersion : 0x0300 = SSLv3 */
97 "\x00\x79" /* ContentLength : 0x79 bytes after this one */
98 "\x01" /* HanshakeType : 0x01 = CLIENT HELLO */
99 "\x00\x00\x75" /* HandshakeLength : 0x75 bytes after this one */
100 "\x03\x00" /* Hello Version : 0x0300 = v3 */
101 "\x00\x00\x00\x00" /* Unix GMT Time (s) : filled with <now> (@0x0B) */
102 "HAPROXYSSLCHK\nHAPROXYSSLCHK\n" /* Random : must be exactly 28 bytes */
103 "\x00" /* Session ID length : empty (no session ID) */
104 "\x00\x4E" /* Cipher Suite Length : 78 bytes after this one */
105 "\x00\x01" "\x00\x02" "\x00\x03" "\x00\x04" /* 39 most common ciphers : */
106 "\x00\x05" "\x00\x06" "\x00\x07" "\x00\x08" /* 0x01...0x1B, 0x2F...0x3A */
107 "\x00\x09" "\x00\x0A" "\x00\x0B" "\x00\x0C" /* This covers RSA/DH, */
108 "\x00\x0D" "\x00\x0E" "\x00\x0F" "\x00\x10" /* various bit lengths, */
109 "\x00\x11" "\x00\x12" "\x00\x13" "\x00\x14" /* SHA1/MD5, DES/3DES/AES... */
110 "\x00\x15" "\x00\x16" "\x00\x17" "\x00\x18"
111 "\x00\x19" "\x00\x1A" "\x00\x1B" "\x00\x2F"
112 "\x00\x30" "\x00\x31" "\x00\x32" "\x00\x33"
113 "\x00\x34" "\x00\x35" "\x00\x36" "\x00\x37"
114 "\x00\x38" "\x00\x39" "\x00\x3A"
115 "\x01" /* Compression Length : 0x01 = 1 byte for types */
116 "\x00" /* Compression Type : 0x00 = NULL compression */
117};
118
Willy Tarreau3842f002009-06-14 11:39:52 +0200119/* various keyword modifiers */
120enum kw_mod {
121 KWM_STD = 0, /* normal */
122 KWM_NO, /* "no" prefixed before the keyword */
123 KWM_DEF, /* "default" prefixed before the keyword */
124};
125
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100126/* permit to store configuration section */
127struct cfg_section {
128 struct list list;
129 char *section_name;
130 int (*section_parser)(const char *, int, char **, int);
William Lallemandd2ff56d2017-10-16 11:06:50 +0200131 int (*post_section_parser)();
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100132};
133
134/* Used to chain configuration sections definitions. This list
135 * stores struct cfg_section
136 */
137struct list sections = LIST_HEAD_INIT(sections);
138
William Lallemand48b4bb42017-10-23 14:36:34 +0200139/* store post configuration parsing */
140
141struct cfg_postparser {
142 struct list list;
143 char *name;
144 int (*func)();
145};
146
147struct list postparsers = LIST_HEAD_INIT(postparsers);
148
Willy Tarreau13943ab2006-12-31 00:24:10 +0100149/* some of the most common options which are also the easiest to handle */
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100150struct cfg_opt {
Willy Tarreau13943ab2006-12-31 00:24:10 +0100151 const char *name;
152 unsigned int val;
153 unsigned int cap;
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100154 unsigned int checks;
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100155 unsigned int mode;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100156};
157
158/* proxy->options */
159static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100160{
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100161 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
162 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
163 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
164 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
165 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
166 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100167 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau9fbe18e2015-05-01 22:42:08 +0200168 { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau0f228a02015-05-01 15:37:53 +0200169 { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreau9420b122013-12-15 18:58:25 +0100170 { "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100171 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
172 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
173 { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100174 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100175#ifdef TPROXY
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100176 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100177#else
178 { "transparent", 0, 0, 0, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100179#endif
180
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100181 { NULL, 0, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100182};
183
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100184/* proxy->options2 */
185static const struct cfg_opt cfg_opts2[] =
186{
187#ifdef CONFIG_HAP_LINUX_SPLICE
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100188 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
189 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
190 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100191#else
192 { "splice-request", 0, 0, 0, 0 },
193 { "splice-response", 0, 0, 0, 0 },
194 { "splice-auto", 0, 0, 0, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100195#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100196 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
197 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
198 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
199 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
200 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0, 0 },
201 { "socket-stats", PR_O2_SOCKSTAT, PR_CAP_FE, 0, 0 },
202 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0, 0 },
203 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0, 0 },
204 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Jamie Gloudon801a0a32012-08-25 00:18:33 -0400205 { "independent-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100206 { "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreaue52564c2010-04-27 22:19:14 +0200207 { "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau96e31212011-05-30 18:10:30 +0200208 { "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100209 { NULL, 0, 0, 0 }
210};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200211
Willy Tarreau6daf3432008-01-22 16:44:08 +0100212static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200213static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
214int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100215int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100216char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200217
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200218/* List head of all known configuration keywords */
219static struct cfg_kw_list cfg_keywords = {
220 .list = LIST_HEAD_INIT(cfg_keywords.list)
221};
222
Willy Tarreaubaaee002006-06-26 02:48:02 +0200223/*
224 * converts <str> to a list of listeners which are dynamically allocated.
225 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
226 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
227 * - <port> is a numerical port from 1 to 65535 ;
228 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
229 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200230 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
231 * not NULL, it must be a valid pointer to either NULL or a freeable area that
232 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200233 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200234int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200235{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100236 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200237 int port, end;
238
239 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200240
Willy Tarreaubaaee002006-06-26 02:48:02 +0200241 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100242 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200243 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100244 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200245
246 str = next;
247 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100248 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200249 *next++ = 0;
250 }
251
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100252 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200253 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200254 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100255 if (!ss2)
256 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200257
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100258 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100259 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200260 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100261 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200262 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200263
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100264 if (!port || !end) {
265 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
266 goto fail;
267 }
268
Emeric Bruned760922010-10-22 17:59:25 +0200269 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200270 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200271 goto fail;
272 }
273
274 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200275 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200276 goto fail;
277 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200278 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100279 else if (ss2->ss_family == AF_UNSPEC) {
280 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100281 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100282
283 /* We want to attach to an already bound fd whose number
284 * is in the addr part of ss2 when cast to sockaddr_in.
285 * Note that by definition there is a single listener.
286 * We still have to determine the address family to
287 * register the correct protocol.
288 */
289 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
290 addr_len = sizeof(*ss2);
291 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
292 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
293 goto fail;
294 }
295
296 port = end = get_host_port(ss2);
297 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200298
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100299 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100300 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200301 memprintf(err, "%s for address '%s'.\n", *err, str);
302 goto fail;
303 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200304 } /* end while(next) */
305 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200306 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200307 fail:
308 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200309 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200310}
311
William Lallemand6e62fb62015-04-28 16:55:23 +0200312/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100313 * Report an error in <msg> when there are too many arguments. This version is
314 * intended to be used by keyword parsers so that the message will be included
315 * into the general error message. The index is the current keyword in args.
316 * Return 0 if the number of argument is correct, otherwise build a message and
317 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
318 * message may also be null, it will simply not be produced (useful to check only).
319 * <msg> and <err_code> are only affected on error.
320 */
321int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
322{
323 int i;
324
325 if (!*args[index + maxarg + 1])
326 return 0;
327
328 if (msg) {
329 *msg = NULL;
330 memprintf(msg, "%s", args[0]);
331 for (i = 1; i <= index; i++)
332 memprintf(msg, "%s %s", *msg, args[i]);
333
334 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
335 }
336 if (err_code)
337 *err_code |= ERR_ALERT | ERR_FATAL;
338
339 return 1;
340}
341
342/*
343 * same as too_many_args_idx with a 0 index
344 */
345int too_many_args(int maxarg, char **args, char **msg, int *err_code)
346{
347 return too_many_args_idx(maxarg, 0, args, msg, err_code);
348}
349
350/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200351 * Report a fatal Alert when there is too much arguments
352 * The index is the current keyword in args
353 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
354 * Fill err_code with an ERR_ALERT and an ERR_FATAL
355 */
356int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
357{
358 char *kw = NULL;
359 int i;
360
361 if (!*args[index + maxarg + 1])
362 return 0;
363
364 memprintf(&kw, "%s", args[0]);
365 for (i = 1; i <= index; i++) {
366 memprintf(&kw, "%s %s", kw, args[i]);
367 }
368
Christopher Faulet767a84b2017-11-24 16:50:31 +0100369 ha_alert("parsing [%s:%d] : '%s' cannot handle unexpected argument '%s'.\n", file, linenum, kw, args[index + maxarg + 1]);
William Lallemand6e62fb62015-04-28 16:55:23 +0200370 free(kw);
371 *err_code |= ERR_ALERT | ERR_FATAL;
372 return 1;
373}
374
375/*
376 * same as alertif_too_many_args_idx with a 0 index
377 */
378int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
379{
380 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
381}
382
Willy Tarreau620408f2016-10-21 16:37:51 +0200383/* Report a warning if a rule is placed after a 'tcp-request session' rule.
384 * Return 1 if the warning has been emitted, otherwise 0.
385 */
386int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
387{
388 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100389 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
390 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200391 return 1;
392 }
393 return 0;
394}
395
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200396/* Report a warning if a rule is placed after a 'tcp-request content' rule.
397 * Return 1 if the warning has been emitted, otherwise 0.
398 */
399int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
400{
401 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100402 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
403 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200404 return 1;
405 }
406 return 0;
407}
408
Willy Tarreau721d8e02017-12-01 18:25:08 +0100409/* Report a warning if a rule is placed after a 'monitor fail' rule.
410 * Return 1 if the warning has been emitted, otherwise 0.
411 */
412int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
413{
414 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
415 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
416 file, line, arg);
417 return 1;
418 }
419 return 0;
420}
421
Willy Tarreau61d18892009-03-31 10:49:21 +0200422/* Report a warning if a rule is placed after a 'block' rule.
423 * Return 1 if the warning has been emitted, otherwise 0.
424 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100425int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200426{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200427 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100428 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
429 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200430 return 1;
431 }
432 return 0;
433}
434
Willy Tarreau5002f572014-04-23 01:32:02 +0200435/* Report a warning if a rule is placed after an 'http_request' rule.
436 * Return 1 if the warning has been emitted, otherwise 0.
437 */
438int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
439{
440 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100441 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
442 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200443 return 1;
444 }
445 return 0;
446}
447
Willy Tarreau61d18892009-03-31 10:49:21 +0200448/* Report a warning if a rule is placed after a reqrewrite rule.
449 * Return 1 if the warning has been emitted, otherwise 0.
450 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100451int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200452{
453 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100454 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
455 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200456 return 1;
457 }
458 return 0;
459}
460
461/* Report a warning if a rule is placed after a reqadd rule.
462 * Return 1 if the warning has been emitted, otherwise 0.
463 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100464int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200465{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100466 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100467 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
468 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200469 return 1;
470 }
471 return 0;
472}
473
474/* Report a warning if a rule is placed after a redirect rule.
475 * Return 1 if the warning has been emitted, otherwise 0.
476 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100477int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200478{
479 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100480 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
481 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200482 return 1;
483 }
484 return 0;
485}
486
487/* Report a warning if a rule is placed after a 'use_backend' rule.
488 * Return 1 if the warning has been emitted, otherwise 0.
489 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100490int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200491{
492 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100493 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
494 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200495 return 1;
496 }
497 return 0;
498}
499
Willy Tarreauee445d92014-04-23 01:39:04 +0200500/* Report a warning if a rule is placed after a 'use-server' rule.
501 * Return 1 if the warning has been emitted, otherwise 0.
502 */
503int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
504{
505 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100506 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
507 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200508 return 1;
509 }
510 return 0;
511}
512
Willy Tarreaud39ad442016-11-25 15:16:12 +0100513/* report a warning if a redirect rule is dangerously placed */
514int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200515{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100516 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200517 warnif_rule_after_use_server(proxy, file, line, arg);
518}
519
Willy Tarreaud39ad442016-11-25 15:16:12 +0100520/* report a warning if a reqadd rule is dangerously placed */
521int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200522{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100523 return warnif_rule_after_redirect(proxy, file, line, arg) ||
524 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200525}
526
Willy Tarreaud39ad442016-11-25 15:16:12 +0100527/* report a warning if a reqxxx rule is dangerously placed */
528int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200529{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100530 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
531 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200532}
533
534/* report a warning if an http-request rule is dangerously placed */
535int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
536{
Willy Tarreau61d18892009-03-31 10:49:21 +0200537 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100538 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200539}
540
Willy Tarreaud39ad442016-11-25 15:16:12 +0100541/* report a warning if a block rule is dangerously placed */
542int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200543{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100544 return warnif_rule_after_http_req(proxy, file, line, arg) ||
545 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200546}
547
Willy Tarreau721d8e02017-12-01 18:25:08 +0100548/* report a warning if a block rule is dangerously placed */
549int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200550{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100551 return warnif_rule_after_block(proxy, file, line, arg) ||
552 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200553}
554
Willy Tarreau721d8e02017-12-01 18:25:08 +0100555/* report a warning if a "tcp request content" rule is dangerously placed */
556int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
557{
558 return warnif_rule_after_monitor(proxy, file, line, arg) ||
559 warnif_misplaced_monitor(proxy, file, line, arg);
560}
561
Willy Tarreaud39ad442016-11-25 15:16:12 +0100562/* report a warning if a "tcp request session" rule is dangerously placed */
563int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200564{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100565 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
566 warnif_misplaced_tcp_cont(proxy, file, line, arg);
567}
568
569/* report a warning if a "tcp request connection" rule is dangerously placed */
570int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
571{
572 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
573 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200574}
575
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100576/* Report it if a request ACL condition uses some keywords that are incompatible
577 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
578 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
579 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100580 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100581static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100582{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100583 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200584 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100585
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100586 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100587 return 0;
588
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100589 acl = acl_cond_conflicts(cond, where);
590 if (acl) {
591 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100592 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
593 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100594 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100595 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
596 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100597 return ERR_WARN;
598 }
599 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100600 return 0;
601
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100602 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100603 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
604 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100605 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100606 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
607 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100608 return ERR_WARN;
609}
610
Christopher Faulet62519022017-10-16 15:49:32 +0200611/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100612 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100613 * two such numbers delimited by a dash ('-'). On success, it returns
614 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200615 *
616 * Note: this function can also be used to parse a thread number or a set of
617 * threads.
618 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100619int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200620{
Christopher Faulet26028f62017-11-22 15:01:51 +0100621 if (autoinc) {
622 *autoinc = 0;
623 if (strncmp(arg, "auto:", 5) == 0) {
624 arg += 5;
625 *autoinc = 1;
626 }
627 }
628
Christopher Faulet62519022017-10-16 15:49:32 +0200629 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100630 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200631 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100632 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200633 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100634 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200635 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100636 char *dash;
637 unsigned int low, high;
638
Christopher Faulet5ab51772017-11-22 11:21:58 +0100639 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100640 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100641 return -1;
642 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100643
644 low = high = str2uic(arg);
645 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100646 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
647
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100648 if (high < low) {
649 unsigned int swap = low;
650 low = high;
651 high = swap;
652 }
653
Christopher Faulet5ab51772017-11-22 11:21:58 +0100654 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100655 memprintf(err, "'%s' is not a valid number/range."
656 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100657 arg, LONGBITS);
658 return 1;
659 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100660
661 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100662 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200663 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100664
Christopher Faulet5ab51772017-11-22 11:21:58 +0100665 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200666}
667
David Carlier7e351ee2017-12-01 09:14:02 +0000668#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200669/* Parse cpu sets. Each CPU set is either a unique number between 0 and
670 * <LONGBITS> or a range with two such numbers delimited by a dash
671 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
672 * returns 0. otherwise it returns 1 with an error message in <err>.
673 */
674static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
675{
676 int cur_arg = 0;
677
678 *cpu_set = 0;
679 while (*args[cur_arg]) {
680 char *dash;
681 unsigned int low, high;
682
683 if (!isdigit((int)*args[cur_arg])) {
684 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
685 return -1;
686 }
687
688 low = high = str2uic(args[cur_arg]);
689 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100690 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200691
692 if (high < low) {
693 unsigned int swap = low;
694 low = high;
695 high = swap;
696 }
697
698 if (high >= LONGBITS) {
699 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
700 return 1;
701 }
702
703 while (low <= high)
704 *cpu_set |= 1UL << low++;
705
706 cur_arg++;
707 }
708 return 0;
709}
David Carlier7e351ee2017-12-01 09:14:02 +0000710#endif
711
Willy Tarreaubaaee002006-06-26 02:48:02 +0200712/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200713 * parse a line in a <global> section. Returns the error code, 0 if OK, or
714 * any combination of :
715 * - ERR_ABORT: must abort ASAP
716 * - ERR_FATAL: we can continue parsing but not start the service
717 * - ERR_WARN: a warning has been emitted
718 * - ERR_ALERT: an alert has been emitted
719 * Only the two first ones can stop processing, the two others are just
720 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200721 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200722int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200723{
Willy Tarreau058e9072009-07-20 09:30:05 +0200724 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200725 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200726
727 if (!strcmp(args[0], "global")) { /* new section */
728 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200729 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200730 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200731 }
732 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200733 if (alertif_too_many_args(0, file, linenum, args, &err_code))
734 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200735 global.mode |= MODE_DAEMON;
736 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200737 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200738 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200739 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200740 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100741 if (!strcmp(args[1], "no-exit-on-failure")) {
742 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200743 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100744 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
William Lallemand69f9b3b2017-06-01 17:38:54 +0200745 err_code |= ERR_ALERT | ERR_FATAL;
746 goto out;
747 }
748 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200749 global.mode |= MODE_MWORKER;
750 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200751 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200752 if (alertif_too_many_args(0, file, linenum, args, &err_code))
753 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200754 global.mode |= MODE_DEBUG;
755 }
756 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200757 if (alertif_too_many_args(0, file, linenum, args, &err_code))
758 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100759 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200760 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200761 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200762 if (alertif_too_many_args(0, file, linenum, args, &err_code))
763 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100764 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200765 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200766 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200767 if (alertif_too_many_args(0, file, linenum, args, &err_code))
768 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100769 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200770 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100771 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200772 if (alertif_too_many_args(0, file, linenum, args, &err_code))
773 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100774 global.tune.options &= ~GTUNE_USE_SPLICE;
775 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200776 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200777 if (alertif_too_many_args(0, file, linenum, args, &err_code))
778 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200779 global.tune.options &= ~GTUNE_USE_GAI;
780 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000781 else if (!strcmp(args[0], "noreuseport")) {
782 if (alertif_too_many_args(0, file, linenum, args, &err_code))
783 goto out;
784 global.tune.options &= ~GTUNE_USE_REUSEPORT;
785 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200786 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200787 if (alertif_too_many_args(0, file, linenum, args, &err_code))
788 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200789 global.mode |= MODE_QUIET;
790 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200791 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200792 if (alertif_too_many_args(1, file, linenum, args, &err_code))
793 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200794 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100795 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200796 err_code |= ERR_ALERT;
797 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200798 }
799 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100800 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200801 err_code |= ERR_ALERT | ERR_FATAL;
802 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200803 }
804 global.tune.maxpollevents = atol(args[1]);
805 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100806 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200807 if (alertif_too_many_args(1, file, linenum, args, &err_code))
808 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100809 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100810 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200811 err_code |= ERR_ALERT;
812 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100813 }
814 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100815 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200816 err_code |= ERR_ALERT | ERR_FATAL;
817 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100818 }
819 global.tune.maxaccept = atol(args[1]);
820 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200821 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200822 if (alertif_too_many_args(1, file, linenum, args, &err_code))
823 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200824 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100825 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200826 err_code |= ERR_ALERT | ERR_FATAL;
827 goto out;
828 }
829 global.tune.chksize = atol(args[1]);
830 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100831 else if (!strcmp(args[0], "tune.recv_enough")) {
832 if (alertif_too_many_args(1, file, linenum, args, &err_code))
833 goto out;
834 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100835 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100836 err_code |= ERR_ALERT | ERR_FATAL;
837 goto out;
838 }
839 global.tune.recv_enough = atol(args[1]);
840 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100841 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200842 if (alertif_too_many_args(1, file, linenum, args, &err_code))
843 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100844 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100845 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100846 err_code |= ERR_ALERT | ERR_FATAL;
847 goto out;
848 }
849 global.tune.buf_limit = atol(args[1]);
850 if (global.tune.buf_limit) {
851 if (global.tune.buf_limit < 3)
852 global.tune.buf_limit = 3;
853 if (global.tune.buf_limit <= global.tune.reserved_bufs)
854 global.tune.buf_limit = global.tune.reserved_bufs + 1;
855 }
856 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100857 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200858 if (alertif_too_many_args(1, file, linenum, args, &err_code))
859 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100860 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100861 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100862 err_code |= ERR_ALERT | ERR_FATAL;
863 goto out;
864 }
865 global.tune.reserved_bufs = atol(args[1]);
866 if (global.tune.reserved_bufs < 2)
867 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100868 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
869 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100870 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200871 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200872 if (alertif_too_many_args(1, file, linenum, args, &err_code))
873 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200874 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100875 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200876 err_code |= ERR_ALERT | ERR_FATAL;
877 goto out;
878 }
879 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200880 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100881 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200882 err_code |= ERR_ALERT | ERR_FATAL;
883 goto out;
884 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200885 }
886 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200887 if (alertif_too_many_args(1, file, linenum, args, &err_code))
888 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200889 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100890 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200891 err_code |= ERR_ALERT | ERR_FATAL;
892 goto out;
893 }
894 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200895 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100896 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200897 err_code |= ERR_ALERT | ERR_FATAL;
898 goto out;
899 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200900 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100901 else if (!strcmp(args[0], "tune.idletimer")) {
902 unsigned int idle;
903 const char *res;
904
William Lallemand1a748ae2015-05-19 16:37:23 +0200905 if (alertif_too_many_args(1, file, linenum, args, &err_code))
906 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100907 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100908 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100909 err_code |= ERR_ALERT | ERR_FATAL;
910 goto out;
911 }
912
913 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
914 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100915 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100916 file, linenum, *res, args[0]);
917 err_code |= ERR_ALERT | ERR_FATAL;
918 goto out;
919 }
920
921 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100922 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100923 err_code |= ERR_ALERT | ERR_FATAL;
924 goto out;
925 }
926 global.tune.idle_timer = idle;
927 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100928 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200929 if (alertif_too_many_args(1, file, linenum, args, &err_code))
930 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100931 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100932 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100933 err_code |= ERR_ALERT;
934 goto out;
935 }
936 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100937 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100938 err_code |= ERR_ALERT | ERR_FATAL;
939 goto out;
940 }
941 global.tune.client_rcvbuf = atol(args[1]);
942 }
943 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200944 if (alertif_too_many_args(1, file, linenum, args, &err_code))
945 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100946 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100947 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100948 err_code |= ERR_ALERT;
949 goto out;
950 }
951 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100952 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100953 err_code |= ERR_ALERT | ERR_FATAL;
954 goto out;
955 }
956 global.tune.server_rcvbuf = atol(args[1]);
957 }
958 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200959 if (alertif_too_many_args(1, file, linenum, args, &err_code))
960 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100961 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100962 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100963 err_code |= ERR_ALERT;
964 goto out;
965 }
966 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100967 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100968 err_code |= ERR_ALERT | ERR_FATAL;
969 goto out;
970 }
971 global.tune.client_sndbuf = atol(args[1]);
972 }
973 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200974 if (alertif_too_many_args(1, file, linenum, args, &err_code))
975 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100976 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100977 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100978 err_code |= ERR_ALERT;
979 goto out;
980 }
981 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100982 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100983 err_code |= ERR_ALERT | ERR_FATAL;
984 goto out;
985 }
986 global.tune.server_sndbuf = atol(args[1]);
987 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200988 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200989 if (alertif_too_many_args(1, file, linenum, args, &err_code))
990 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200991 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100992 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200993 err_code |= ERR_ALERT | ERR_FATAL;
994 goto out;
995 }
996 global.tune.pipesize = atol(args[1]);
997 }
Willy Tarreau193b8c62012-11-22 00:17:38 +0100998 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200999 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1000 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001001 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001002 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001003 err_code |= ERR_ALERT | ERR_FATAL;
1004 goto out;
1005 }
1006 global.tune.cookie_len = atol(args[1]) + 1;
1007 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001008 else if (!strcmp(args[0], "tune.http.logurilen")) {
1009 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1010 goto out;
1011 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001012 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001013 err_code |= ERR_ALERT | ERR_FATAL;
1014 goto out;
1015 }
1016 global.tune.requri_len = atol(args[1]) + 1;
1017 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001018 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001019 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1020 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001021 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001022 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001023 err_code |= ERR_ALERT | ERR_FATAL;
1024 goto out;
1025 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001026 global.tune.max_http_hdr = atoi(args[1]);
1027 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001028 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1029 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001030 err_code |= ERR_ALERT | ERR_FATAL;
1031 goto out;
1032 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001033 }
William Lallemandf3747832012-11-09 12:33:10 +01001034 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001035 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1036 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001037 if (*args[1]) {
1038 global.tune.comp_maxlevel = atoi(args[1]);
1039 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001040 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1041 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001042 err_code |= ERR_ALERT | ERR_FATAL;
1043 goto out;
1044 }
1045 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001046 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1047 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001048 err_code |= ERR_ALERT | ERR_FATAL;
1049 goto out;
1050 }
1051 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001052 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1053 if (*args[1]) {
1054 global.tune.pattern_cache = atoi(args[1]);
1055 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001056 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1057 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001058 err_code |= ERR_ALERT | ERR_FATAL;
1059 goto out;
1060 }
1061 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001062 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1063 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001064 err_code |= ERR_ALERT | ERR_FATAL;
1065 goto out;
1066 }
1067 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001068 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001069 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1070 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001071 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001072 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001073 err_code |= ERR_ALERT;
1074 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001075 }
1076 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001077 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001078 err_code |= ERR_ALERT | ERR_FATAL;
1079 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001080 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001081 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001082 ha_warning("parsing [%s:%d] : uid: string '%s' is not a number.\n | You might want to use the 'user' parameter to use a system user name.\n", file, linenum, args[1]);
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001083 err_code |= ERR_WARN;
1084 goto out;
1085 }
1086
Willy Tarreaubaaee002006-06-26 02:48:02 +02001087 }
1088 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001089 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1090 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001091 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001092 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001093 err_code |= ERR_ALERT;
1094 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001095 }
1096 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001097 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001098 err_code |= ERR_ALERT | ERR_FATAL;
1099 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001100 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001101 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001102 ha_warning("parsing [%s:%d] : gid: string '%s' is not a number.\n | You might want to use the 'group' parameter to use a system group name.\n", file, linenum, args[1]);
Baptiste Assmann776e5182016-03-11 17:21:15 +01001103 err_code |= ERR_WARN;
1104 goto out;
1105 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001106 }
Simon Horman98637e52014-06-20 12:30:16 +09001107 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001108 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1109 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001110 global.external_check = 1;
1111 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001112 /* user/group name handling */
1113 else if (!strcmp(args[0], "user")) {
1114 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001115 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1116 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001117 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001118 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001119 err_code |= ERR_ALERT;
1120 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001121 }
1122 errno = 0;
1123 ha_user = getpwnam(args[1]);
1124 if (ha_user != NULL) {
1125 global.uid = (int)ha_user->pw_uid;
1126 }
1127 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001128 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001129 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001130 }
1131 }
1132 else if (!strcmp(args[0], "group")) {
1133 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001134 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1135 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001136 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001137 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001138 err_code |= ERR_ALERT;
1139 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001140 }
1141 errno = 0;
1142 ha_group = getgrnam(args[1]);
1143 if (ha_group != NULL) {
1144 global.gid = (int)ha_group->gr_gid;
1145 }
1146 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001147 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001148 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001149 }
1150 }
1151 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001152 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001153 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1154 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001155 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001156 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001157 err_code |= ERR_ALERT | ERR_FATAL;
1158 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001159 }
1160 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001161 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001162 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1163 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001164 err_code |= ERR_ALERT | ERR_FATAL;
1165 goto out;
1166 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001167 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001168 else if (!strcmp(args[0], "nbthread")) {
1169 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1170 goto out;
1171 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001172 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001173 err_code |= ERR_ALERT | ERR_FATAL;
1174 goto out;
1175 }
1176 global.nbthread = atol(args[1]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001177#ifndef USE_THREAD
1178 if (global.nbthread > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 ha_alert("HAProxy is not compiled with threads support, please check build options for USE_THREAD.\n");
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001180 global.nbthread = 1;
1181 err_code |= ERR_ALERT | ERR_FATAL;
1182 goto out;
1183 }
1184#endif
Willy Tarreau421f02e2018-01-20 18:19:22 +01001185 if (global.nbthread < 1 || global.nbthread > MAX_THREADS) {
1186 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1187 file, linenum, args[0], MAX_THREADS, global.nbthread);
1188 err_code |= ERR_ALERT | ERR_FATAL;
1189 goto out;
1190 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001191 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001192 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001193 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1194 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001195 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001196 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001197 err_code |= ERR_ALERT;
1198 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001199 }
1200 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001201 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001202 err_code |= ERR_ALERT | ERR_FATAL;
1203 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001204 }
1205 global.maxconn = atol(args[1]);
1206#ifdef SYSTEM_MAXCONN
1207 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001208 ha_alert("parsing [%s:%d] : maxconn value %d too high for this system.\nLimiting to %d. Please use '-n' to force the value.\n", file, linenum, global.maxconn, DEFAULT_MAXCONN);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001209 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001210 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001211 }
1212#endif /* SYSTEM_MAXCONN */
1213 }
Emeric Brun850efd52014-01-29 12:24:34 +01001214 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001215 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1216 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001217 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001218 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001219 err_code |= ERR_ALERT | ERR_FATAL;
1220 goto out;
1221 }
1222 if (strcmp(args[1],"none") == 0)
1223 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1224 else if (strcmp(args[1],"required") == 0)
1225 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1226 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001227 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001228 err_code |= ERR_ALERT | ERR_FATAL;
1229 goto out;
1230 }
1231 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001232 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001233 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1234 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001235 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001236 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001237 err_code |= ERR_ALERT;
1238 goto out;
1239 }
1240 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001241 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001242 err_code |= ERR_ALERT | ERR_FATAL;
1243 goto out;
1244 }
1245 global.cps_lim = atol(args[1]);
1246 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001247 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001248 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1249 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001250 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001251 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001252 err_code |= ERR_ALERT;
1253 goto out;
1254 }
1255 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001256 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001257 err_code |= ERR_ALERT | ERR_FATAL;
1258 goto out;
1259 }
1260 global.sps_lim = atol(args[1]);
1261 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001262 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001263 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1264 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001265 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001266 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001267 err_code |= ERR_ALERT;
1268 goto out;
1269 }
1270 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001271 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001272 err_code |= ERR_ALERT | ERR_FATAL;
1273 goto out;
1274 }
1275 global.ssl_lim = atol(args[1]);
1276 }
William Lallemandd85f9172012-11-09 17:05:39 +01001277 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001278 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1279 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001280 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001281 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
William Lallemandd85f9172012-11-09 17:05:39 +01001282 err_code |= ERR_ALERT | ERR_FATAL;
1283 goto out;
1284 }
1285 global.comp_rate_lim = atoi(args[1]) * 1024;
1286 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001287 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001288 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1289 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001290 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001291 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001292 err_code |= ERR_ALERT;
1293 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001294 }
1295 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001296 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001297 err_code |= ERR_ALERT | ERR_FATAL;
1298 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001299 }
1300 global.maxpipes = atol(args[1]);
1301 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001302 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001303 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1304 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001305 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001306 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001307 err_code |= ERR_ALERT | ERR_FATAL;
1308 goto out;
1309 }
William Lallemande3a7d992012-11-20 11:25:20 +01001310 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001311 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001312 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001313 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1314 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001315 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001316 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
William Lallemand072a2bf2012-11-20 17:01:01 +01001317 err_code |= ERR_ALERT | ERR_FATAL;
1318 goto out;
1319 }
1320 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001321 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001322 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
William Lallemand072a2bf2012-11-20 17:01:01 +01001323 err_code |= ERR_ALERT | ERR_FATAL;
1324 goto out;
1325 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001326 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001327
Willy Tarreaubaaee002006-06-26 02:48:02 +02001328 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001329 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1330 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001331 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001332 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001333 err_code |= ERR_ALERT;
1334 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001335 }
1336 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001337 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001338 err_code |= ERR_ALERT | ERR_FATAL;
1339 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001340 }
1341 global.rlimit_nofile = atol(args[1]);
1342 }
1343 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001344 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1345 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001346 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001347 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001348 err_code |= ERR_ALERT;
1349 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001350 }
1351 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001352 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001353 err_code |= ERR_ALERT | ERR_FATAL;
1354 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001355 }
1356 global.chroot = strdup(args[1]);
1357 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001358 else if (!strcmp(args[0], "description")) {
1359 int i, len=0;
1360 char *d;
1361
1362 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001363 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1364 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001365 err_code |= ERR_ALERT | ERR_FATAL;
1366 goto out;
1367 }
1368
Willy Tarreau348acfe2014-04-14 15:00:39 +02001369 for (i = 1; *args[i]; i++)
1370 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001371
1372 if (global.desc)
1373 free(global.desc);
1374
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001375 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001376
Willy Tarreau348acfe2014-04-14 15:00:39 +02001377 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1378 for (i = 2; *args[i]; i++)
1379 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001380 }
1381 else if (!strcmp(args[0], "node")) {
1382 int i;
1383 char c;
1384
William Lallemand1a748ae2015-05-19 16:37:23 +02001385 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1386 goto out;
1387
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001388 for (i=0; args[1][i]; i++) {
1389 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001390 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1391 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001392 break;
1393 }
1394
1395 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001396 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1397 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1398 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001399 err_code |= ERR_ALERT | ERR_FATAL;
1400 goto out;
1401 }
1402
1403 if (global.node)
1404 free(global.node);
1405
1406 global.node = strdup(args[1]);
1407 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001408 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001409 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1410 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001411 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001412 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001413 err_code |= ERR_ALERT;
1414 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001415 }
1416 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001417 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001418 err_code |= ERR_ALERT | ERR_FATAL;
1419 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001420 }
1421 global.pidfile = strdup(args[1]);
1422 }
Emeric Bruned760922010-10-22 17:59:25 +02001423 else if (!strcmp(args[0], "unix-bind")) {
1424 int cur_arg = 1;
1425 while (*(args[cur_arg])) {
1426 if (!strcmp(args[cur_arg], "prefix")) {
1427 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001428 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001429 err_code |= ERR_ALERT;
1430 cur_arg += 2;
1431 continue;
1432 }
1433
1434 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001435 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001436 err_code |= ERR_ALERT | ERR_FATAL;
1437 goto out;
1438 }
1439 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1440 cur_arg += 2;
1441 continue;
1442 }
1443
1444 if (!strcmp(args[cur_arg], "mode")) {
1445
1446 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1447 cur_arg += 2;
1448 continue;
1449 }
1450
1451 if (!strcmp(args[cur_arg], "uid")) {
1452
1453 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1454 cur_arg += 2;
1455 continue;
1456 }
1457
1458 if (!strcmp(args[cur_arg], "gid")) {
1459
1460 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1461 cur_arg += 2;
1462 continue;
1463 }
1464
1465 if (!strcmp(args[cur_arg], "user")) {
1466 struct passwd *user;
1467
1468 user = getpwnam(args[cur_arg + 1]);
1469 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001470 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1471 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001472 err_code |= ERR_ALERT | ERR_FATAL;
1473 goto out;
1474 }
1475
1476 global.unix_bind.ux.uid = user->pw_uid;
1477 cur_arg += 2;
1478 continue;
1479 }
1480
1481 if (!strcmp(args[cur_arg], "group")) {
1482 struct group *group;
1483
1484 group = getgrnam(args[cur_arg + 1]);
1485 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001486 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1487 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001488 err_code |= ERR_ALERT | ERR_FATAL;
1489 goto out;
1490 }
1491
1492 global.unix_bind.ux.gid = group->gr_gid;
1493 cur_arg += 2;
1494 continue;
1495 }
1496
Christopher Faulet767a84b2017-11-24 16:50:31 +01001497 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1498 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001499 err_code |= ERR_ALERT | ERR_FATAL;
1500 goto out;
1501 }
1502 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001503 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1504 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1505 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001506 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001507 goto out;
1508 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001509 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001510 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1511 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001512
1513 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001514 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001515 err_code |= ERR_ALERT;
1516 goto out;
1517 }
1518
1519 if (*(args[1]))
1520 name = args[1];
1521 else
1522 name = hostname;
1523
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001524 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001525 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001526 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001527 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1528 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001529 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001530 err_code |= ERR_ALERT;
1531 goto out;
1532 }
1533
1534 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001535 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001536 err_code |= ERR_FATAL;
1537 goto out;
1538 }
1539
1540 global.server_state_base = strdup(args[1]);
1541 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001542 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1543 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001544 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001545 err_code |= ERR_ALERT;
1546 goto out;
1547 }
1548
1549 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001550 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001551 err_code |= ERR_FATAL;
1552 goto out;
1553 }
1554
1555 global.server_state_file = strdup(args[1]);
1556 }
Kevinm48936af2010-12-22 16:08:21 +00001557 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001558 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1559 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001560 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001561 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001562 err_code |= ERR_ALERT | ERR_FATAL;
1563 goto out;
1564 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001565 chunk_destroy(&global.log_tag);
1566 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001567 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001568 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001569 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1570 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001571 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001572 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001573 err_code |= ERR_ALERT;
1574 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001575 }
1576 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001577 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001578 err_code |= ERR_ALERT | ERR_FATAL;
1579 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001580 }
1581 global.spread_checks = atol(args[1]);
1582 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001583 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 +02001584 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001585 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001586 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001587 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1588 const char *err;
1589 unsigned int val;
1590
William Lallemand1a748ae2015-05-19 16:37:23 +02001591 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1592 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001593 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001594 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001595 err_code |= ERR_ALERT | ERR_FATAL;
1596 goto out;
1597 }
1598
1599 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1600 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001601 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 +02001602 err_code |= ERR_ALERT | ERR_FATAL;
1603 }
1604 global.max_spread_checks = val;
1605 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001606 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001607 err_code |= ERR_ALERT | ERR_FATAL;
1608 }
1609 }
Christopher Faulet62519022017-10-16 15:49:32 +02001610 else if (strcmp(args[0], "cpu-map") == 0) {
1611 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001612#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001613 char *slash;
1614 unsigned long proc = 0, thread = 0, cpus;
1615 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001616
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001617 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001618 ha_alert("parsing [%s:%d] : %s expects a process number "
1619 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1620 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1621 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001622 err_code |= ERR_ALERT | ERR_FATAL;
1623 goto out;
1624 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001625
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001626 if ((slash = strchr(args[1], '/')) != NULL)
1627 *slash = 0;
1628
Christopher Faulet26028f62017-11-22 15:01:51 +01001629 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001630 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001631 err_code |= ERR_ALERT | ERR_FATAL;
1632 goto out;
1633 }
1634
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001635 if (slash) {
1636 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001637 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001638 err_code |= ERR_ALERT | ERR_FATAL;
1639 goto out;
1640 }
1641 *slash = '/';
1642
1643 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001644 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1645 "a process range _AND_ a thread range\n",
1646 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001647 err_code |= ERR_ALERT | ERR_FATAL;
1648 goto out;
1649 }
1650 }
1651
Christopher Faulet62519022017-10-16 15:49:32 +02001652 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001653 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001654 err_code |= ERR_ALERT | ERR_FATAL;
1655 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001656 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001657
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001658 if (autoinc &&
1659 my_popcountl(proc) != my_popcountl(cpus) &&
1660 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001661 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1662 "must have the same size to be automatically bound\n",
1663 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001664 err_code |= ERR_ALERT | ERR_FATAL;
1665 goto out;
1666 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001667
Christopher Faulet26028f62017-11-22 15:01:51 +01001668 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001669 /* No mapping for this process */
1670 if (!(proc & (1UL << i)))
1671 continue;
1672
1673 /* Mapping at the process level */
1674 if (!thread) {
1675 if (!autoinc)
1676 global.cpu_map.proc[i] = cpus;
1677 else {
1678 n += my_ffsl(cpus >> n);
1679 global.cpu_map.proc[i] = (1UL << (n-1));
1680 }
1681 continue;
1682 }
1683
1684 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001685 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001686 /* Np mapping for this thread */
1687 if (!(thread & (1UL << j)))
1688 continue;
1689
1690 if (!autoinc)
1691 global.cpu_map.thread[i][j] = cpus;
1692 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001693 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001694 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001695 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001696 }
1697 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001698#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001699 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1700 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001701 err_code |= ERR_ALERT | ERR_FATAL;
1702 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001703#endif /* ! USE_CPU_AFFINITY */
1704 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001705 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1706 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1707 goto out;
1708
1709 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001710 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001711 err_code |= ERR_ALERT | ERR_FATAL;
1712 goto out;
1713 }
1714
1715 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1716 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001717 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 +01001718 err_code |= ERR_ALERT | ERR_FATAL;
1719 goto out;
1720 }
1721 }
1722 else if (!strcmp(args[0], "unsetenv")) {
1723 int arg;
1724
1725 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001726 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001727 err_code |= ERR_ALERT | ERR_FATAL;
1728 goto out;
1729 }
1730
1731 for (arg = 1; *args[arg]; arg++) {
1732 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001733 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 +01001734 err_code |= ERR_ALERT | ERR_FATAL;
1735 goto out;
1736 }
1737 }
1738 }
1739 else if (!strcmp(args[0], "resetenv")) {
1740 extern char **environ;
1741 char **env = environ;
1742
1743 /* args contain variable names to keep, one per argument */
1744 while (*env) {
1745 int arg;
1746
1747 /* look for current variable in among all those we want to keep */
1748 for (arg = 1; *args[arg]; arg++) {
1749 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1750 (*env)[strlen(args[arg])] == '=')
1751 break;
1752 }
1753
1754 /* delete this variable */
1755 if (!*args[arg]) {
1756 char *delim = strchr(*env, '=');
1757
1758 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001759 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 +01001760 err_code |= ERR_ALERT | ERR_FATAL;
1761 goto out;
1762 }
1763
1764 memcpy(trash.str, *env, delim - *env);
1765 trash.str[delim - *env] = 0;
1766
1767 if (unsetenv(trash.str) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001768 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 +01001769 err_code |= ERR_ALERT | ERR_FATAL;
1770 goto out;
1771 }
1772 }
1773 else
1774 env++;
1775 }
1776 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001777 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001778 struct cfg_kw_list *kwl;
1779 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001780 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001781
1782 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1783 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1784 if (kwl->kw[index].section != CFG_GLOBAL)
1785 continue;
1786 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001787 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001788 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001789 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001790 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001791 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001792 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001793 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001794 err_code |= ERR_WARN;
1795 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001796 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001797 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001798 }
1799 }
1800 }
1801
Christopher Faulet767a84b2017-11-24 16:50:31 +01001802 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001803 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001804 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001805
Willy Tarreau058e9072009-07-20 09:30:05 +02001806 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001807 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001808 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001809}
1810
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001811void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001812{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001813 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001814 defproxy.mode = PR_MODE_TCP;
1815 defproxy.state = PR_STNEW;
1816 defproxy.maxconn = cfg_maxpconn;
1817 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001818 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001819 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001820
Simon Horman66183002013-02-23 10:16:43 +09001821 defproxy.defsrv.check.inter = DEF_CHKINTR;
1822 defproxy.defsrv.check.fastinter = 0;
1823 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001824 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1825 defproxy.defsrv.agent.fastinter = 0;
1826 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001827 defproxy.defsrv.check.rise = DEF_RISETIME;
1828 defproxy.defsrv.check.fall = DEF_FALLTIME;
1829 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1830 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001831 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001832 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001833 defproxy.defsrv.maxqueue = 0;
1834 defproxy.defsrv.minconn = 0;
1835 defproxy.defsrv.maxconn = 0;
1836 defproxy.defsrv.slowstart = 0;
1837 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1838 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1839 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001840
1841 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001842 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001843}
1844
Willy Tarreauade5ec42010-01-28 19:33:49 +01001845
Willy Tarreau63af98d2014-05-18 08:11:41 +02001846/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1847 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1848 * ERR_FATAL in case of error.
1849 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001850static int create_cond_regex_rule(const char *file, int line,
1851 struct proxy *px, int dir, int action, int flags,
1852 const char *cmd, const char *reg, const char *repl,
1853 const char **cond_start)
1854{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001855 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001856 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001857 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001858 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001859 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001860 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001861 int cs;
1862 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001863
1864 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001865 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001866 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001867 goto err;
1868 }
1869
1870 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001871 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001872 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001873 goto err;
1874 }
1875
Christopher Faulet898566e2016-10-26 11:06:28 +02001876 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001877 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001878
Willy Tarreau5321c422010-01-28 20:35:13 +01001879 if (cond_start &&
1880 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001881 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001882 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1883 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001884 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001885 goto err;
1886 }
1887 }
1888 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001889 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1890 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001891 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001892 goto err;
1893 }
1894
Willy Tarreau63af98d2014-05-18 08:11:41 +02001895 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001896 (dir == SMP_OPT_DIR_REQ) ?
1897 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1898 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1899 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001900
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001901 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001902 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001903 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001904 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001905 goto err;
1906 }
1907
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001908 cs = !(flags & REG_ICASE);
1909 cap = !(flags & REG_NOSUB);
1910 error = NULL;
1911 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001912 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001913 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001914 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001915 goto err;
1916 }
1917
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001918 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001919 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001920 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001921 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1922 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001923 ret_code |= ERR_ALERT | ERR_FATAL;
1924 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001925 }
1926
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001927 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001928 ret_code |= ERR_WARN;
1929
1930 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001931
Willy Tarreau63af98d2014-05-18 08:11:41 +02001932 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001933 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001934 err:
1935 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001936 free(errmsg);
1937 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001938}
1939
Willy Tarreaubaaee002006-06-26 02:48:02 +02001940/*
William Lallemand51097192015-04-14 16:35:22 +02001941 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001942 * Returns the error code, 0 if OK, or any combination of :
1943 * - ERR_ABORT: must abort ASAP
1944 * - ERR_FATAL: we can continue parsing but not start the service
1945 * - ERR_WARN: a warning has been emitted
1946 * - ERR_ALERT: an alert has been emitted
1947 * Only the two first ones can stop processing, the two others are just
1948 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001949 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001950int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1951{
1952 static struct peers *curpeers = NULL;
1953 struct peer *newpeer = NULL;
1954 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001955 struct bind_conf *bind_conf;
1956 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001957 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001958 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001959
1960 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001961 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001962 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001963 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001964 goto out;
1965 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001966
William Lallemand6e62fb62015-04-28 16:55:23 +02001967 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1968 goto out;
1969
Emeric Brun32da3c42010-09-23 18:39:19 +02001970 err = invalid_char(args[1]);
1971 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001972 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1973 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001974 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001975 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02001976 }
1977
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02001978 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02001979 /*
1980 * If there are two proxies with the same name only following
1981 * combinations are allowed:
1982 */
1983 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001984 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
1985 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02001986 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001987 }
1988 }
1989
Vincent Bernat02779b62016-04-03 13:48:43 +02001990 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001991 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02001992 err_code |= ERR_ALERT | ERR_ABORT;
1993 goto out;
1994 }
1995
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02001996 curpeers->next = cfg_peers;
1997 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02001998 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02001999 curpeers->conf.line = linenum;
2000 curpeers->last_change = now.tv_sec;
2001 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002002 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002003 }
2004 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002005 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002006 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002007 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002008
2009 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002010 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2011 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002012 err_code |= ERR_ALERT | ERR_FATAL;
2013 goto out;
2014 }
2015
2016 err = invalid_char(args[1]);
2017 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002018 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2019 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002020 err_code |= ERR_ALERT | ERR_FATAL;
2021 goto out;
2022 }
2023
Vincent Bernat02779b62016-04-03 13:48:43 +02002024 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002025 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002026 err_code |= ERR_ALERT | ERR_ABORT;
2027 goto out;
2028 }
2029
2030 /* the peers are linked backwards first */
2031 curpeers->count++;
2032 newpeer->next = curpeers->remote;
2033 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002034 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002035 newpeer->conf.line = linenum;
2036
2037 newpeer->last_change = now.tv_sec;
2038 newpeer->id = strdup(args[1]);
2039
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002040 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002041 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002042 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002043 err_code |= ERR_ALERT | ERR_FATAL;
2044 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002045 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002046
2047 proto = protocol_by_family(sk->ss_family);
2048 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002049 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2050 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002051 err_code |= ERR_ALERT | ERR_FATAL;
2052 goto out;
2053 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002054
2055 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002056 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2057 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002058 err_code |= ERR_ALERT | ERR_FATAL;
2059 goto out;
2060 }
2061
Willy Tarreau2aa38802013-02-20 19:20:59 +01002062 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002063 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2064 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002065 err_code |= ERR_ALERT | ERR_FATAL;
2066 goto out;
2067 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002068
Emeric Brun32da3c42010-09-23 18:39:19 +02002069 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002070 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002071 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002072 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002073 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002074
Emeric Brun32da3c42010-09-23 18:39:19 +02002075 if (strcmp(newpeer->id, localpeer) == 0) {
2076 /* Current is local peer, it define a frontend */
2077 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002078 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002079
2080 if (!curpeers->peers_fe) {
2081 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002082 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002083 err_code |= ERR_ALERT | ERR_ABORT;
2084 goto out;
2085 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002086
Willy Tarreau237250c2011-07-29 01:49:03 +02002087 init_new_proxy(curpeers->peers_fe);
2088 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002089 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002090 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2091 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002092 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002093
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002094 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002095
Willy Tarreau902636f2013-03-10 19:44:48 +01002096 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2097 if (errmsg && *errmsg) {
2098 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002099 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002100 }
2101 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002102 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2103 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002104 err_code |= ERR_FATAL;
2105 goto out;
2106 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002107
2108 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002109 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002110 l->maxconn = curpeers->peers_fe->maxconn;
2111 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002112 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002113 l->analysers |= curpeers->peers_fe->fe_req_ana;
2114 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002115 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2116 global.maxsock += l->maxconn;
2117 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002118 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002119 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002120 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2121 file, linenum, args[0], args[1],
2122 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002123 err_code |= ERR_FATAL;
2124 goto out;
2125 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002126 }
2127 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002128 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2129 curpeers->state = PR_STSTOPPED;
2130 }
2131 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2132 curpeers->state = PR_STNEW;
2133 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002134 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002135 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002136 err_code |= ERR_ALERT | ERR_FATAL;
2137 goto out;
2138 }
2139
2140out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002141 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002142 return err_code;
2143}
2144
Baptiste Assmann325137d2015-04-13 23:40:55 +02002145/*
2146 * Parse a <resolvers> section.
2147 * Returns the error code, 0 if OK, or any combination of :
2148 * - ERR_ABORT: must abort ASAP
2149 * - ERR_FATAL: we can continue parsing but not start the service
2150 * - ERR_WARN: a warning has been emitted
2151 * - ERR_ALERT: an alert has been emitted
2152 * Only the two first ones can stop processing, the two others are just
2153 * indicators.
2154 */
2155int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2156{
2157 static struct dns_resolvers *curr_resolvers = NULL;
2158 struct dns_nameserver *newnameserver = NULL;
2159 const char *err;
2160 int err_code = 0;
2161 char *errmsg = NULL;
2162
2163 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2164 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002165 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002166 err_code |= ERR_ALERT | ERR_ABORT;
2167 goto out;
2168 }
2169
2170 err = invalid_char(args[1]);
2171 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002172 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2173 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002174 err_code |= ERR_ALERT | ERR_ABORT;
2175 goto out;
2176 }
2177
2178 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2179 /* Error if two resolvers owns the same name */
2180 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002181 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2182 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002183 err_code |= ERR_ALERT | ERR_ABORT;
2184 }
2185 }
2186
Vincent Bernat02779b62016-04-03 13:48:43 +02002187 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002188 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002189 err_code |= ERR_ALERT | ERR_ABORT;
2190 goto out;
2191 }
2192
2193 /* default values */
2194 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2195 curr_resolvers->conf.file = strdup(file);
2196 curr_resolvers->conf.line = linenum;
2197 curr_resolvers->id = strdup(args[1]);
2198 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002199 /* default maximum response size */
2200 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002201 /* default hold period for nx, other, refuse and timeout is 30s */
2202 curr_resolvers->hold.nx = 30000;
2203 curr_resolvers->hold.other = 30000;
2204 curr_resolvers->hold.refused = 30000;
2205 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002206 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002207 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002208 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002209 curr_resolvers->timeout.resolve = 1000;
2210 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002211 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002212 curr_resolvers->nb_nameservers = 0;
2213 LIST_INIT(&curr_resolvers->nameservers);
2214 LIST_INIT(&curr_resolvers->resolutions.curr);
2215 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002216 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002217 }
2218 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2219 struct sockaddr_storage *sk;
2220 int port1, port2;
2221 struct protocol *proto;
2222
2223 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002224 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2225 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002226 err_code |= ERR_ALERT | ERR_FATAL;
2227 goto out;
2228 }
2229
2230 err = invalid_char(args[1]);
2231 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002232 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2233 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002234 err_code |= ERR_ALERT | ERR_FATAL;
2235 goto out;
2236 }
2237
Christopher Faulet67957bd2017-09-27 11:00:59 +02002238 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002239 /* Error if two resolvers owns the same name */
2240 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002241 ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
2242 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002243 err_code |= ERR_ALERT | ERR_FATAL;
2244 }
2245 }
2246
Vincent Bernat02779b62016-04-03 13:48:43 +02002247 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002248 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002249 err_code |= ERR_ALERT | ERR_ABORT;
2250 goto out;
2251 }
2252
2253 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002254 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002255 newnameserver->resolvers = curr_resolvers;
2256 newnameserver->conf.file = strdup(file);
2257 newnameserver->conf.line = linenum;
2258 newnameserver->id = strdup(args[1]);
2259
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002260 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002261 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002262 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002263 err_code |= ERR_ALERT | ERR_FATAL;
2264 goto out;
2265 }
2266
2267 proto = protocol_by_family(sk->ss_family);
2268 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002269 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002270 file, linenum, args[0], args[1]);
2271 err_code |= ERR_ALERT | ERR_FATAL;
2272 goto out;
2273 }
2274
2275 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002276 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2277 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002278 err_code |= ERR_ALERT | ERR_FATAL;
2279 goto out;
2280 }
2281
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002282 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002283 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2284 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002285 err_code |= ERR_ALERT | ERR_FATAL;
2286 goto out;
2287 }
2288
Baptiste Assmann325137d2015-04-13 23:40:55 +02002289 newnameserver->addr = *sk;
2290 }
2291 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2292 const char *res;
2293 unsigned int time;
2294
2295 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002296 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2297 file, linenum, args[0]);
2298 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002299 err_code |= ERR_ALERT | ERR_FATAL;
2300 goto out;
2301 }
2302 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2303 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002304 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2305 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002306 err_code |= ERR_ALERT | ERR_FATAL;
2307 goto out;
2308 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002309 if (strcmp(args[1], "nx") == 0)
2310 curr_resolvers->hold.nx = time;
2311 else if (strcmp(args[1], "other") == 0)
2312 curr_resolvers->hold.other = time;
2313 else if (strcmp(args[1], "refused") == 0)
2314 curr_resolvers->hold.refused = time;
2315 else if (strcmp(args[1], "timeout") == 0)
2316 curr_resolvers->hold.timeout = time;
2317 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002318 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002319 else if (strcmp(args[1], "obsolete") == 0)
2320 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002321 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002322 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2323 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002324 err_code |= ERR_ALERT | ERR_FATAL;
2325 goto out;
2326 }
2327
2328 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002329 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002330 int i = 0;
2331
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002332 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002333 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2334 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002335 err_code |= ERR_ALERT | ERR_FATAL;
2336 goto out;
2337 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002338
2339 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002340 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002341 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2342 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002343 err_code |= ERR_ALERT | ERR_FATAL;
2344 goto out;
2345 }
2346
2347 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002348 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002349 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002350 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2351 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002352 err_code |= ERR_WARN;
2353 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002354 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002355 else if (strcmp(args[0], "resolve_retries") == 0) {
2356 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002357 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2358 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002359 err_code |= ERR_ALERT | ERR_FATAL;
2360 goto out;
2361 }
2362 curr_resolvers->resolve_retries = atoi(args[1]);
2363 }
2364 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002365 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002366 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2367 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002368 err_code |= ERR_ALERT | ERR_FATAL;
2369 goto out;
2370 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002371 else if (strcmp(args[1], "retry") == 0 ||
2372 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002373 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002374 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002375
2376 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002377 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2378 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002379 err_code |= ERR_ALERT | ERR_FATAL;
2380 goto out;
2381 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002382 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002383 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002384 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2385 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002386 err_code |= ERR_ALERT | ERR_FATAL;
2387 goto out;
2388 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002389 if (args[1][2] == 't')
2390 curr_resolvers->timeout.retry = tout;
2391 else
2392 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002393 }
2394 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002395 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2396 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002397 err_code |= ERR_ALERT | ERR_FATAL;
2398 goto out;
2399 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002400 } /* neither "nameserver" nor "resolvers" */
2401 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002402 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002403 err_code |= ERR_ALERT | ERR_FATAL;
2404 goto out;
2405 }
2406
2407 out:
2408 free(errmsg);
2409 return err_code;
2410}
Simon Horman0d16a402015-01-30 11:22:58 +09002411
2412/*
William Lallemand51097192015-04-14 16:35:22 +02002413 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002414 * Returns the error code, 0 if OK, or any combination of :
2415 * - ERR_ABORT: must abort ASAP
2416 * - ERR_FATAL: we can continue parsing but not start the service
2417 * - ERR_WARN: a warning has been emitted
2418 * - ERR_ALERT: an alert has been emitted
2419 * Only the two first ones can stop processing, the two others are just
2420 * indicators.
2421 */
2422int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2423{
2424 static struct mailers *curmailers = NULL;
2425 struct mailer *newmailer = NULL;
2426 const char *err;
2427 int err_code = 0;
2428 char *errmsg = NULL;
2429
2430 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2431 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002432 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002433 err_code |= ERR_ALERT | ERR_ABORT;
2434 goto out;
2435 }
2436
2437 err = invalid_char(args[1]);
2438 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002439 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2440 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002441 err_code |= ERR_ALERT | ERR_ABORT;
2442 goto out;
2443 }
2444
2445 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2446 /*
2447 * If there are two proxies with the same name only following
2448 * combinations are allowed:
2449 */
2450 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002451 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2452 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002453 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002454 }
2455 }
2456
Vincent Bernat02779b62016-04-03 13:48:43 +02002457 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002458 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002459 err_code |= ERR_ALERT | ERR_ABORT;
2460 goto out;
2461 }
2462
2463 curmailers->next = mailers;
2464 mailers = curmailers;
2465 curmailers->conf.file = strdup(file);
2466 curmailers->conf.line = linenum;
2467 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002468 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2469 * But need enough time so that timeouts don't occur
2470 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002471 }
2472 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2473 struct sockaddr_storage *sk;
2474 int port1, port2;
2475 struct protocol *proto;
2476
2477 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002478 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2479 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002480 err_code |= ERR_ALERT | ERR_FATAL;
2481 goto out;
2482 }
2483
2484 err = invalid_char(args[1]);
2485 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002486 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2487 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002488 err_code |= ERR_ALERT | ERR_FATAL;
2489 goto out;
2490 }
2491
Vincent Bernat02779b62016-04-03 13:48:43 +02002492 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002493 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002494 err_code |= ERR_ALERT | ERR_ABORT;
2495 goto out;
2496 }
2497
2498 /* the mailers are linked backwards first */
2499 curmailers->count++;
2500 newmailer->next = curmailers->mailer_list;
2501 curmailers->mailer_list = newmailer;
2502 newmailer->mailers = curmailers;
2503 newmailer->conf.file = strdup(file);
2504 newmailer->conf.line = linenum;
2505
2506 newmailer->id = strdup(args[1]);
2507
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002508 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002509 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002510 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002511 err_code |= ERR_ALERT | ERR_FATAL;
2512 goto out;
2513 }
2514
2515 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002516 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002517 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2518 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002519 err_code |= ERR_ALERT | ERR_FATAL;
2520 goto out;
2521 }
2522
2523 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002524 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2525 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002526 err_code |= ERR_ALERT | ERR_FATAL;
2527 goto out;
2528 }
2529
2530 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002531 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2532 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002533 err_code |= ERR_ALERT | ERR_FATAL;
2534 goto out;
2535 }
2536
2537 newmailer->addr = *sk;
2538 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002539 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002540 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002541 }
2542 else if (strcmp(args[0], "timeout") == 0) {
2543 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002544 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2545 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002546 err_code |= ERR_ALERT | ERR_FATAL;
2547 goto out;
2548 }
2549 else if (strcmp(args[1], "mail") == 0) {
2550 const char *res;
2551 unsigned int timeout_mail;
2552 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002553 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2554 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002555 err_code |= ERR_ALERT | ERR_FATAL;
2556 goto out;
2557 }
2558 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2559 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002560 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2561 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002562 err_code |= ERR_ALERT | ERR_FATAL;
2563 goto out;
2564 }
2565 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002566 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 +01002567 err_code |= ERR_ALERT | ERR_FATAL;
2568 goto out;
2569 }
2570 curmailers->timeout.mail = timeout_mail;
2571 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002572 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002573 file, linenum, args[0], args[1]);
2574 err_code |= ERR_ALERT | ERR_FATAL;
2575 goto out;
2576 }
2577 }
Simon Horman0d16a402015-01-30 11:22:58 +09002578 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002579 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002580 err_code |= ERR_ALERT | ERR_FATAL;
2581 goto out;
2582 }
2583
2584out:
2585 free(errmsg);
2586 return err_code;
2587}
2588
Simon Horman9dc49962015-01-30 11:22:59 +09002589static void free_email_alert(struct proxy *p)
2590{
2591 free(p->email_alert.mailers.name);
2592 p->email_alert.mailers.name = NULL;
2593 free(p->email_alert.from);
2594 p->email_alert.from = NULL;
2595 free(p->email_alert.to);
2596 p->email_alert.to = NULL;
2597 free(p->email_alert.myhostname);
2598 p->email_alert.myhostname = NULL;
2599}
2600
Willy Tarreau3842f002009-06-14 11:39:52 +02002601int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002602{
2603 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002604 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002605 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002606 int rc;
2607 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002608 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002609 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002610 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002611 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002612 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002613
Willy Tarreau977b8e42006-12-29 14:19:17 +01002614 if (!strcmp(args[0], "listen"))
2615 rc = PR_CAP_LISTEN;
2616 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002617 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002618 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002619 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002620 else
2621 rc = PR_CAP_NONE;
2622
2623 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002624 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002625 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2626 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2627 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002628 err_code |= ERR_ALERT | ERR_ABORT;
2629 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002630 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002631
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002632 err = invalid_char(args[1]);
2633 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002634 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2635 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002636 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002637 }
2638
Willy Tarreau8f50b682015-05-26 11:45:02 +02002639 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2640 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002641 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2642 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2643 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002644 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002645 }
2646
Vincent Bernat02779b62016-04-03 13:48:43 +02002647 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002648 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002649 err_code |= ERR_ALERT | ERR_ABORT;
2650 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002651 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002652
Willy Tarreau97cb7802010-01-03 20:23:58 +01002653 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002654 curproxy->next = proxies_list;
2655 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002656 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2657 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002658 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002659 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002660 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002661 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002662
William Lallemand6e62fb62015-04-28 16:55:23 +02002663 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2664 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002665 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002666 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002667 }
2668
2669 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002670 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002671 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002672
Willy Tarreaubaaee002006-06-26 02:48:02 +02002673 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002674 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002675 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002676 curproxy->no_options = defproxy.no_options;
2677 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002678 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002679 curproxy->except_net = defproxy.except_net;
2680 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002681 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002682 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002683
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002684 if (defproxy.fwdfor_hdr_len) {
2685 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2686 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2687 }
2688
Willy Tarreaub86db342009-11-30 11:50:16 +01002689 if (defproxy.orgto_hdr_len) {
2690 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2691 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2692 }
2693
Mark Lamourinec2247f02012-01-04 13:02:01 -05002694 if (defproxy.server_id_hdr_len) {
2695 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2696 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2697 }
2698
Willy Tarreau977b8e42006-12-29 14:19:17 +01002699 if (curproxy->cap & PR_CAP_FE) {
2700 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002701 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002702 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002703
2704 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002705 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2706 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002707
2708 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2709 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002710
Willy Tarreau977b8e42006-12-29 14:19:17 +01002711 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002712 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002713 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002714 curproxy->fullconn = defproxy.fullconn;
2715 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002716 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002717 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002718
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002719 if (defproxy.check_req) {
2720 curproxy->check_req = calloc(1, defproxy.check_len);
2721 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2722 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002723 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002724
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002725 if (defproxy.expect_str) {
2726 curproxy->expect_str = strdup(defproxy.expect_str);
2727 if (defproxy.expect_regex) {
2728 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002729 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2730 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002731 }
2732 }
2733
Willy Tarreau67402132012-05-31 20:40:20 +02002734 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002735 if (defproxy.cookie_name)
2736 curproxy->cookie_name = strdup(defproxy.cookie_name);
2737 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002738
2739 if (defproxy.dyncookie_key)
2740 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002741 if (defproxy.cookie_domain)
2742 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002743
Willy Tarreau31936852010-10-06 16:59:56 +02002744 if (defproxy.cookie_maxidle)
2745 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2746
2747 if (defproxy.cookie_maxlife)
2748 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2749
Emeric Brun647caf12009-06-30 17:57:00 +02002750 if (defproxy.rdp_cookie_name)
2751 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2752 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2753
Willy Tarreau01732802007-11-01 22:48:15 +01002754 if (defproxy.url_param_name)
2755 curproxy->url_param_name = strdup(defproxy.url_param_name);
2756 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002757
Benoitaffb4812009-03-25 13:02:10 +01002758 if (defproxy.hh_name)
2759 curproxy->hh_name = strdup(defproxy.hh_name);
2760 curproxy->hh_len = defproxy.hh_len;
2761 curproxy->hh_match_domain = defproxy.hh_match_domain;
2762
Willy Tarreauef9a3602012-12-08 22:29:20 +01002763 if (defproxy.conn_src.iface_name)
2764 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2765 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002766 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002767#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002768 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002769#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002770 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002771 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002772
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002773 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002774 if (defproxy.capture_name)
2775 curproxy->capture_name = strdup(defproxy.capture_name);
2776 curproxy->capture_namelen = defproxy.capture_namelen;
2777 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002778 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002779
Willy Tarreau977b8e42006-12-29 14:19:17 +01002780 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002781 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002782 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002783 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002784 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002785 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002786 curproxy->mon_net = defproxy.mon_net;
2787 curproxy->mon_mask = defproxy.mon_mask;
2788 if (defproxy.monitor_uri)
2789 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2790 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002791 if (defproxy.defbe.name)
2792 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002793
2794 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002795 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2796 if (curproxy->conf.logformat_string &&
2797 curproxy->conf.logformat_string != default_http_log_format &&
2798 curproxy->conf.logformat_string != default_tcp_log_format &&
2799 curproxy->conf.logformat_string != clf_http_log_format)
2800 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2801
2802 if (defproxy.conf.lfs_file) {
2803 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2804 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2805 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002806
2807 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2808 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2809 if (curproxy->conf.logformat_sd_string &&
2810 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2811 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2812
2813 if (defproxy.conf.lfsd_file) {
2814 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2815 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2816 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002817 }
2818
2819 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002820 curproxy->timeout.connect = defproxy.timeout.connect;
2821 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002822 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002823 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002824 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002825 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002826 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002827 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002828 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002829 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002830 }
2831
Willy Tarreaubaaee002006-06-26 02:48:02 +02002832 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002833 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002834
2835 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002836 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002837 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002838 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002839 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002840 LIST_INIT(&node->list);
2841 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2842 }
2843
Willy Tarreau62a61232013-04-12 18:13:46 +02002844 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2845 if (curproxy->conf.uniqueid_format_string)
2846 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2847
Dragan Dosen43885c72015-10-01 13:18:13 +02002848 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002849
Willy Tarreau62a61232013-04-12 18:13:46 +02002850 if (defproxy.conf.uif_file) {
2851 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2852 curproxy->conf.uif_line = defproxy.conf.uif_line;
2853 }
William Lallemanda73203e2012-03-12 12:48:57 +01002854
2855 /* copy default header unique id */
2856 if (defproxy.header_unique_id)
2857 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2858
William Lallemand82fe75c2012-10-23 10:25:10 +02002859 /* default compression options */
2860 if (defproxy.comp != NULL) {
2861 curproxy->comp = calloc(1, sizeof(struct comp));
2862 curproxy->comp->algos = defproxy.comp->algos;
2863 curproxy->comp->types = defproxy.comp->types;
2864 }
2865
Willy Tarreaubaaee002006-06-26 02:48:02 +02002866 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002867 curproxy->conf.used_listener_id = EB_ROOT;
2868 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002869
Simon Horman98637e52014-06-20 12:30:16 +09002870 if (defproxy.check_path)
2871 curproxy->check_path = strdup(defproxy.check_path);
2872 if (defproxy.check_command)
2873 curproxy->check_command = strdup(defproxy.check_command);
2874
Simon Horman9dc49962015-01-30 11:22:59 +09002875 if (defproxy.email_alert.mailers.name)
2876 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
2877 if (defproxy.email_alert.from)
2878 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
2879 if (defproxy.email_alert.to)
2880 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
2881 if (defproxy.email_alert.myhostname)
2882 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09002883 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01002884 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09002885
Willy Tarreau93893792009-07-23 13:19:11 +02002886 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002887 }
2888 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
2889 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002890 /* FIXME-20070101: we should do this too at the end of the
2891 * config parsing to free all default values.
2892 */
William Lallemand6e62fb62015-04-28 16:55:23 +02002893 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2894 err_code |= ERR_ABORT;
2895 goto out;
2896 }
2897
Willy Tarreaua534fea2008-08-03 12:19:50 +02002898 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09002899 free(defproxy.check_command);
2900 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02002901 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02002902 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01002903 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002904 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02002905 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01002906 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02002907 free(defproxy.capture_name);
2908 free(defproxy.monitor_uri);
2909 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01002910 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002911 free(defproxy.fwdfor_hdr_name);
2912 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01002913 free(defproxy.orgto_hdr_name);
2914 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05002915 free(defproxy.server_id_hdr_name);
2916 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002917 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02002918 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002919 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02002920 free(defproxy.expect_regex);
2921 defproxy.expect_regex = NULL;
2922 }
Willy Tarreau0f772532006-12-23 20:51:41 +01002923
Willy Tarreau62a61232013-04-12 18:13:46 +02002924 if (defproxy.conf.logformat_string != default_http_log_format &&
2925 defproxy.conf.logformat_string != default_tcp_log_format &&
2926 defproxy.conf.logformat_string != clf_http_log_format)
2927 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02002928
Willy Tarreau62a61232013-04-12 18:13:46 +02002929 free(defproxy.conf.uniqueid_format_string);
2930 free(defproxy.conf.lfs_file);
2931 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02002932 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09002933 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02002934
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002935 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
2936 free(defproxy.conf.logformat_sd_string);
2937 free(defproxy.conf.lfsd_file);
2938
Willy Tarreaua534fea2008-08-03 12:19:50 +02002939 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002940 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01002941
Willy Tarreaubaaee002006-06-26 02:48:02 +02002942 /* we cannot free uri_auth because it might already be used */
2943 init_default_instance();
2944 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002945 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2946 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002947 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02002948 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002949 }
2950 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002951 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002952 err_code |= ERR_ALERT | ERR_FATAL;
2953 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002954 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002955
2956 /* update the current file and line being parsed */
2957 curproxy->conf.args.file = curproxy->conf.file;
2958 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002959
2960 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02002961 if (!strcmp(args[0], "server") ||
2962 !strcmp(args[0], "default-server") ||
2963 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02002964 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
2965 if (err_code & ERR_FATAL)
2966 goto out;
2967 }
2968 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002969 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01002970 int cur_arg;
2971
Willy Tarreaubaaee002006-06-26 02:48:02 +02002972 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002973 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002974 err_code |= ERR_ALERT | ERR_FATAL;
2975 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002976 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002977 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002978 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002979
Willy Tarreau24709282013-03-10 21:32:12 +01002980 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002981 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
2982 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002983 err_code |= ERR_ALERT | ERR_FATAL;
2984 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002985 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01002986
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002987 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01002988
2989 /* use default settings for unix sockets */
2990 bind_conf->ux.uid = global.unix_bind.ux.uid;
2991 bind_conf->ux.gid = global.unix_bind.ux.gid;
2992 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02002993
2994 /* NOTE: the following line might create several listeners if there
2995 * are comma-separated IPs or port ranges. So all further processing
2996 * will have to be applied to all listeners created after last_listen.
2997 */
Willy Tarreau902636f2013-03-10 19:44:48 +01002998 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
2999 if (errmsg && *errmsg) {
3000 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003001 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003002 }
3003 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003004 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3005 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003006 err_code |= ERR_ALERT | ERR_FATAL;
3007 goto out;
3008 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003009
Willy Tarreau4348fad2012-09-20 16:48:07 +02003010 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3011 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003012 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003013 }
3014
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003015 cur_arg = 2;
3016 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003017 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003018 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003019 char *err;
3020
Willy Tarreau26982662012-09-12 23:17:10 +02003021 kw = bind_find_kw(args[cur_arg]);
3022 if (kw) {
3023 char *err = NULL;
3024 int code;
3025
3026 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003027 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3028 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003029 cur_arg += 1 + kw->skip ;
3030 err_code |= ERR_ALERT | ERR_FATAL;
3031 goto out;
3032 }
3033
Willy Tarreau4348fad2012-09-20 16:48:07 +02003034 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003035 err_code |= code;
3036
3037 if (code) {
3038 if (err && *err) {
3039 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003040 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003041 }
3042 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003043 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3044 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003045 if (code & ERR_FATAL) {
3046 free(err);
3047 cur_arg += 1 + kw->skip;
3048 goto out;
3049 }
3050 }
3051 free(err);
3052 cur_arg += 1 + kw->skip;
3053 continue;
3054 }
3055
Willy Tarreau8638f482012-09-18 18:01:17 +02003056 err = NULL;
3057 if (!bind_dumped) {
3058 bind_dump_kws(&err);
3059 indent_msg(&err, 4);
3060 bind_dumped = 1;
3061 }
3062
Christopher Faulet767a84b2017-11-24 16:50:31 +01003063 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3064 file, linenum, args[0], args[1], args[cur_arg],
3065 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003066 free(err);
3067
Willy Tarreau93893792009-07-23 13:19:11 +02003068 err_code |= ERR_ALERT | ERR_FATAL;
3069 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003070 }
Willy Tarreau93893792009-07-23 13:19:11 +02003071 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003072 }
3073 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003074 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003075 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3076 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003077 err_code |= ERR_ALERT | ERR_FATAL;
3078 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003079 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003080 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003081 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003082
Willy Tarreaubaaee002006-06-26 02:48:02 +02003083 /* flush useless bits */
3084 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003085 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003086 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003087 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003088 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003089 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003090
William Lallemanddf1425a2015-04-28 20:17:49 +02003091 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3092 goto out;
3093
Willy Tarreau1c47f852006-07-09 08:22:27 +02003094 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003095 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3096 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003097 err_code |= ERR_ALERT | ERR_FATAL;
3098 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003099 }
3100
Willy Tarreaua534fea2008-08-03 12:19:50 +02003101 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003102 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003103 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003104 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003105 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3106
Willy Tarreau93893792009-07-23 13:19:11 +02003107 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003108 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003109 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003110 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3111 goto out;
3112
Willy Tarreaubaaee002006-06-26 02:48:02 +02003113 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3114 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3115 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3116 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003117 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003118 err_code |= ERR_ALERT | ERR_FATAL;
3119 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003120 }
3121 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003122 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003123 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003124
3125 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003126 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003127 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003128 err_code |= ERR_ALERT | ERR_FATAL;
3129 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003130 }
3131
William Lallemanddf1425a2015-04-28 20:17:49 +02003132 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3133 goto out;
3134
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003135 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003136 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3137 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003138 err_code |= ERR_ALERT | ERR_FATAL;
3139 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003140 }
3141
3142 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003143 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003144 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003145
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003146 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003147 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3148 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003149 err_code |= ERR_ALERT | ERR_FATAL;
3150 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003151 }
3152
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003153 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3154 if (node) {
3155 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003156 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3157 file, linenum, proxy_type_str(curproxy), curproxy->id,
3158 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003159 err_code |= ERR_ALERT | ERR_FATAL;
3160 goto out;
3161 }
3162 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003163 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003164 else if (!strcmp(args[0], "description")) {
3165 int i, len=0;
3166 char *d;
3167
Cyril Bonté99ed3272010-01-24 23:29:44 +01003168 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003169 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003170 file, linenum, args[0]);
3171 err_code |= ERR_ALERT | ERR_FATAL;
3172 goto out;
3173 }
3174
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003175 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003176 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3177 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003178 return -1;
3179 }
3180
Willy Tarreau348acfe2014-04-14 15:00:39 +02003181 for (i = 1; *args[i]; i++)
3182 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003183
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003184 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003185 curproxy->desc = d;
3186
Willy Tarreau348acfe2014-04-14 15:00:39 +02003187 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3188 for (i = 2; *args[i]; i++)
3189 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003190
3191 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003192 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003193 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3194 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003195 curproxy->state = PR_STSTOPPED;
3196 }
3197 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003198 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3199 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003200 curproxy->state = PR_STNEW;
3201 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003202 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3203 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003204 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003205
3206 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003207 if (strcmp(args[cur_arg], "all") == 0) {
3208 set = 0;
3209 break;
3210 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003211 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003212 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003213 err_code |= ERR_ALERT | ERR_FATAL;
3214 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003215 }
3216 cur_arg++;
3217 }
3218 curproxy->bind_proc = set;
3219 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003220 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003221 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003222 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003223 err_code |= ERR_ALERT | ERR_FATAL;
3224 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003225 }
3226
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003227 err = invalid_char(args[1]);
3228 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003229 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3230 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003231 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003232 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003233 }
3234
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003235 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003236 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3237 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003238 err_code |= ERR_ALERT | ERR_FATAL;
3239 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003240 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003241 }
3242 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3243
3244 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3245 err_code |= ERR_WARN;
3246
3247 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003248 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3249 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003250 err_code |= ERR_ALERT | ERR_FATAL;
3251 goto out;
3252 }
3253 free(curproxy->dyncookie_key);
3254 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003255 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003256 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3257 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003258
Willy Tarreau977b8e42006-12-29 14:19:17 +01003259 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003260 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003261
Willy Tarreaubaaee002006-06-26 02:48:02 +02003262 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003263 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3264 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003265 err_code |= ERR_ALERT | ERR_FATAL;
3266 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003267 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003268
Willy Tarreau67402132012-05-31 20:40:20 +02003269 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003270 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003271 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003272 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003273 curproxy->cookie_name = strdup(args[1]);
3274 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003275
Willy Tarreaubaaee002006-06-26 02:48:02 +02003276 cur_arg = 2;
3277 while (*(args[cur_arg])) {
3278 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003279 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003280 }
3281 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003282 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003283 }
3284 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003285 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003286 }
3287 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003288 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003289 }
3290 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003291 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003292 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003293 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003294 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003295 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003296 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003297 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003298 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003299 else if (!strcmp(args[cur_arg], "httponly")) {
3300 curproxy->ck_opts |= PR_CK_HTTPONLY;
3301 }
3302 else if (!strcmp(args[cur_arg], "secure")) {
3303 curproxy->ck_opts |= PR_CK_SECURE;
3304 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003305 else if (!strcmp(args[cur_arg], "domain")) {
3306 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003307 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3308 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003309 err_code |= ERR_ALERT | ERR_FATAL;
3310 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003311 }
3312
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003313 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003314 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003315 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3316 " dots nor does not start with a dot."
3317 " RFC forbids it, this configuration may not work properly.\n",
3318 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003319 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003320 }
3321
3322 err = invalid_domainchar(args[cur_arg + 1]);
3323 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003324 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3325 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003326 err_code |= ERR_ALERT | ERR_FATAL;
3327 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003328 }
3329
Willy Tarreau68a897b2009-12-03 23:28:34 +01003330 if (!curproxy->cookie_domain) {
3331 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3332 } else {
3333 /* one domain was already specified, add another one by
3334 * building the string which will be returned along with
3335 * the cookie.
3336 */
3337 char *new_ptr;
3338 int new_len = strlen(curproxy->cookie_domain) +
3339 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3340 new_ptr = malloc(new_len);
3341 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3342 free(curproxy->cookie_domain);
3343 curproxy->cookie_domain = new_ptr;
3344 }
Willy Tarreau31936852010-10-06 16:59:56 +02003345 cur_arg++;
3346 }
3347 else if (!strcmp(args[cur_arg], "maxidle")) {
3348 unsigned int maxidle;
3349 const char *res;
3350
3351 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003352 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3353 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003354 err_code |= ERR_ALERT | ERR_FATAL;
3355 goto out;
3356 }
3357
3358 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3359 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003360 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3361 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003362 err_code |= ERR_ALERT | ERR_FATAL;
3363 goto out;
3364 }
3365 curproxy->cookie_maxidle = maxidle;
3366 cur_arg++;
3367 }
3368 else if (!strcmp(args[cur_arg], "maxlife")) {
3369 unsigned int maxlife;
3370 const char *res;
3371
3372 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003373 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3374 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003375 err_code |= ERR_ALERT | ERR_FATAL;
3376 goto out;
3377 }
3378
3379 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3380 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003381 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3382 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003383 err_code |= ERR_ALERT | ERR_FATAL;
3384 goto out;
3385 }
3386 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003387 cur_arg++;
3388 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003389 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003390
3391 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3392 err_code |= ERR_WARN;
3393 curproxy->ck_opts |= PR_CK_DYNAMIC;
3394 }
3395
Willy Tarreaubaaee002006-06-26 02:48:02 +02003396 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003397 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3398 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003399 err_code |= ERR_ALERT | ERR_FATAL;
3400 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003401 }
3402 cur_arg++;
3403 }
Willy Tarreau67402132012-05-31 20:40:20 +02003404 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003405 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3406 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003407 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003408 }
3409
Willy Tarreau67402132012-05-31 20:40:20 +02003410 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003411 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3412 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003413 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003414 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003415
Willy Tarreau67402132012-05-31 20:40:20 +02003416 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003417 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3418 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003419 err_code |= ERR_ALERT | ERR_FATAL;
3420 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003421 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003422 else if (!strcmp(args[0], "email-alert")) {
3423 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003424 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3425 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003426 err_code |= ERR_ALERT | ERR_FATAL;
3427 goto out;
3428 }
3429
3430 if (!strcmp(args[1], "from")) {
3431 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003432 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3433 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003434 err_code |= ERR_ALERT | ERR_FATAL;
3435 goto out;
3436 }
3437 free(curproxy->email_alert.from);
3438 curproxy->email_alert.from = strdup(args[2]);
3439 }
3440 else if (!strcmp(args[1], "mailers")) {
3441 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003442 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3443 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003444 err_code |= ERR_ALERT | ERR_FATAL;
3445 goto out;
3446 }
3447 free(curproxy->email_alert.mailers.name);
3448 curproxy->email_alert.mailers.name = strdup(args[2]);
3449 }
3450 else if (!strcmp(args[1], "myhostname")) {
3451 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003452 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3453 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003454 err_code |= ERR_ALERT | ERR_FATAL;
3455 goto out;
3456 }
3457 free(curproxy->email_alert.myhostname);
3458 curproxy->email_alert.myhostname = strdup(args[2]);
3459 }
Simon Horman64e34162015-02-06 11:11:57 +09003460 else if (!strcmp(args[1], "level")) {
3461 curproxy->email_alert.level = get_log_level(args[2]);
3462 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003463 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3464 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003465 err_code |= ERR_ALERT | ERR_FATAL;
3466 goto out;
3467 }
3468 }
Simon Horman9dc49962015-01-30 11:22:59 +09003469 else if (!strcmp(args[1], "to")) {
3470 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003471 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3472 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003473 err_code |= ERR_ALERT | ERR_FATAL;
3474 goto out;
3475 }
3476 free(curproxy->email_alert.to);
3477 curproxy->email_alert.to = strdup(args[2]);
3478 }
3479 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003480 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3481 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003482 err_code |= ERR_ALERT | ERR_FATAL;
3483 goto out;
3484 }
Simon Horman64e34162015-02-06 11:11:57 +09003485 /* Indicate that the email_alert is at least partially configured */
3486 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003487 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003488 else if (!strcmp(args[0], "external-check")) {
3489 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003490 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3491 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003492 err_code |= ERR_ALERT | ERR_FATAL;
3493 goto out;
3494 }
3495
3496 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003497 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003498 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003499 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003500 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3501 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003502 err_code |= ERR_ALERT | ERR_FATAL;
3503 goto out;
3504 }
3505 free(curproxy->check_command);
3506 curproxy->check_command = strdup(args[2]);
3507 }
3508 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003509 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003510 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003511 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003512 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3513 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003514 err_code |= ERR_ALERT | ERR_FATAL;
3515 goto out;
3516 }
3517 free(curproxy->check_path);
3518 curproxy->check_path = strdup(args[2]);
3519 }
3520 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003521 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3522 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003523 err_code |= ERR_ALERT | ERR_FATAL;
3524 goto out;
3525 }
3526 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003527 else if (!strcmp(args[0], "persist")) { /* persist */
3528 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003529 ha_alert("parsing [%s:%d] : missing persist method.\n",
3530 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003531 err_code |= ERR_ALERT | ERR_FATAL;
3532 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003533 }
3534
3535 if (!strncmp(args[1], "rdp-cookie", 10)) {
3536 curproxy->options2 |= PR_O2_RDPC_PRST;
3537
Emeric Brunb982a3d2010-01-04 15:45:53 +01003538 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003539 const char *beg, *end;
3540
3541 beg = args[1] + 11;
3542 end = strchr(beg, ')');
3543
William Lallemanddf1425a2015-04-28 20:17:49 +02003544 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3545 goto out;
3546
Emeric Brun647caf12009-06-30 17:57:00 +02003547 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003548 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3549 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003550 err_code |= ERR_ALERT | ERR_FATAL;
3551 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003552 }
3553
3554 free(curproxy->rdp_cookie_name);
3555 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3556 curproxy->rdp_cookie_len = end-beg;
3557 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003558 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003559 free(curproxy->rdp_cookie_name);
3560 curproxy->rdp_cookie_name = strdup("msts");
3561 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3562 }
3563 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003564 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3565 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003566 err_code |= ERR_ALERT | ERR_FATAL;
3567 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003568 }
3569 }
3570 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003571 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3572 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003573 err_code |= ERR_ALERT | ERR_FATAL;
3574 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003575 }
3576 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003577 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003578 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 +02003579 err_code |= ERR_ALERT | ERR_FATAL;
3580 goto out;
3581 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003582 else if (!strcmp(args[0], "load-server-state-from-file")) {
3583 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3584 err_code |= ERR_WARN;
3585 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3586 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3587 }
3588 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3589 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3590 }
3591 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3592 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3593 }
3594 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003595 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3596 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003597 err_code |= ERR_ALERT | ERR_FATAL;
3598 goto out;
3599 }
3600 }
3601 else if (!strcmp(args[0], "server-state-file-name")) {
3602 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3603 err_code |= ERR_WARN;
3604 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003605 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3606 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003607 err_code |= ERR_ALERT | ERR_FATAL;
3608 goto out;
3609 }
3610 else if (!strcmp(args[1], "use-backend-name"))
3611 curproxy->server_state_file_name = strdup(curproxy->id);
3612 else
3613 curproxy->server_state_file_name = strdup(args[1]);
3614 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003615 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003616 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003617 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003618
Willy Tarreaubaaee002006-06-26 02:48:02 +02003619 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003620 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003621 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 +01003622 err_code |= ERR_ALERT | ERR_FATAL;
3623 goto out;
3624 }
3625
William Lallemand1a748ae2015-05-19 16:37:23 +02003626 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3627 goto out;
3628
Willy Tarreaubaaee002006-06-26 02:48:02 +02003629 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003630 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3631 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003632 err_code |= ERR_ALERT | ERR_FATAL;
3633 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003634 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003635 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003636 curproxy->capture_name = strdup(args[2]);
3637 curproxy->capture_namelen = strlen(curproxy->capture_name);
3638 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003639 curproxy->to_log |= LW_COOKIE;
3640 }
3641 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3642 struct cap_hdr *hdr;
3643
3644 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003645 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 +02003646 err_code |= ERR_ALERT | ERR_FATAL;
3647 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003648 }
3649
William Lallemand1a748ae2015-05-19 16:37:23 +02003650 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3651 goto out;
3652
Willy Tarreaubaaee002006-06-26 02:48:02 +02003653 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003654 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3655 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003656 err_code |= ERR_ALERT | ERR_FATAL;
3657 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003658 }
3659
Vincent Bernat02779b62016-04-03 13:48:43 +02003660 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003661 hdr->next = curproxy->req_cap;
3662 hdr->name = strdup(args[3]);
3663 hdr->namelen = strlen(args[3]);
3664 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003665 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003666 hdr->index = curproxy->nb_req_cap++;
3667 curproxy->req_cap = hdr;
3668 curproxy->to_log |= LW_REQHDR;
3669 }
3670 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3671 struct cap_hdr *hdr;
3672
3673 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003674 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 +02003675 err_code |= ERR_ALERT | ERR_FATAL;
3676 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003677 }
3678
William Lallemand1a748ae2015-05-19 16:37:23 +02003679 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3680 goto out;
3681
Willy Tarreaubaaee002006-06-26 02:48:02 +02003682 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003683 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3684 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003685 err_code |= ERR_ALERT | ERR_FATAL;
3686 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003687 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003688 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003689 hdr->next = curproxy->rsp_cap;
3690 hdr->name = strdup(args[3]);
3691 hdr->namelen = strlen(args[3]);
3692 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003693 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003694 hdr->index = curproxy->nb_rsp_cap++;
3695 curproxy->rsp_cap = hdr;
3696 curproxy->to_log |= LW_RSPHDR;
3697 }
3698 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003699 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3700 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003701 err_code |= ERR_ALERT | ERR_FATAL;
3702 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003703 }
3704 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003705 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003706 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003707 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003708
William Lallemanddf1425a2015-04-28 20:17:49 +02003709 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3710 goto out;
3711
Willy Tarreaubaaee002006-06-26 02:48:02 +02003712 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003713 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3714 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003715 err_code |= ERR_ALERT | ERR_FATAL;
3716 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003717 }
3718 curproxy->conn_retries = atol(args[1]);
3719 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003720 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003721 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003722
3723 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003724 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003725 err_code |= ERR_ALERT | ERR_FATAL;
3726 goto out;
3727 }
3728
Willy Tarreau20b0de52012-12-24 15:45:22 +01003729 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003730 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003731 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3732 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3733 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3734 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003735 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3736 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003737 err_code |= ERR_WARN;
3738 }
3739
Willy Tarreauff011f22011-01-06 17:51:27 +01003740 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003741
Willy Tarreauff011f22011-01-06 17:51:27 +01003742 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003743 err_code |= ERR_ALERT | ERR_ABORT;
3744 goto out;
3745 }
3746
Willy Tarreau5002f572014-04-23 01:32:02 +02003747 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003748 err_code |= warnif_cond_conflicts(rule->cond,
3749 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3750 file, linenum);
3751
Willy Tarreauff011f22011-01-06 17:51:27 +01003752 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003753 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003754 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003755 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003756
3757 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003758 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003759 err_code |= ERR_ALERT | ERR_FATAL;
3760 goto out;
3761 }
3762
3763 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003764 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003765 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3766 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003767 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3768 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003769 err_code |= ERR_WARN;
3770 }
3771
3772 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3773
3774 if (!rule) {
3775 err_code |= ERR_ALERT | ERR_ABORT;
3776 goto out;
3777 }
3778
3779 err_code |= warnif_cond_conflicts(rule->cond,
3780 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3781 file, linenum);
3782
3783 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3784 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003785 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3786 /* set the header name and length into the proxy structure */
3787 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3788 err_code |= ERR_WARN;
3789
3790 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003791 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3792 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003793 err_code |= ERR_ALERT | ERR_FATAL;
3794 goto out;
3795 }
3796
3797 /* set the desired header name */
3798 free(curproxy->server_id_hdr_name);
3799 curproxy->server_id_hdr_name = strdup(args[1]);
3800 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3801 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003802 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003803 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003804
Willy Tarreaub099aca2008-10-12 17:26:37 +02003805 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003806 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003807 err_code |= ERR_ALERT | ERR_FATAL;
3808 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003809 }
3810
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003811 /* emulate "block" using "http-request block". Since these rules are supposed to
3812 * be processed before all http-request rules, we put them into their own list
3813 * and will insert them at the end.
3814 */
3815 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3816 if (!rule) {
3817 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003818 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003819 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003820 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3821 err_code |= warnif_cond_conflicts(rule->cond,
3822 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3823 file, linenum);
3824 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003825
3826 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003827 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 +02003828
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003829 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003830 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003831 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003832
Cyril Bonté99ed3272010-01-24 23:29:44 +01003833 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003834 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003835 err_code |= ERR_ALERT | ERR_FATAL;
3836 goto out;
3837 }
3838
Willy Tarreaube4653b2015-05-28 15:26:58 +02003839 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003840 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3841 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003842 err_code |= ERR_ALERT | ERR_FATAL;
3843 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003844 }
3845
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003846 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003847 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003848 err_code |= warnif_cond_conflicts(rule->cond,
3849 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3850 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003851 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003852 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003853 struct switching_rule *rule;
3854
Willy Tarreaub099aca2008-10-12 17:26:37 +02003855 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003856 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003857 err_code |= ERR_ALERT | ERR_FATAL;
3858 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003859 }
3860
Willy Tarreau55ea7572007-06-17 19:56:27 +02003861 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003862 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003863
3864 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003865 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003866 err_code |= ERR_ALERT | ERR_FATAL;
3867 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003868 }
3869
Willy Tarreauf51658d2014-04-23 01:21:56 +02003870 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003871 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003872 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3873 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02003874 err_code |= ERR_ALERT | ERR_FATAL;
3875 goto out;
3876 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003877
Willy Tarreauf51658d2014-04-23 01:21:56 +02003878 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02003879 }
Willy Tarreau4f862642017-02-28 09:34:39 +01003880 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003881 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
3882 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01003883 err_code |= ERR_ALERT | ERR_FATAL;
3884 goto out;
3885 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003886
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003887 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01003888 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003889 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01003890 goto out;
3891 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003892 rule->cond = cond;
3893 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01003894 rule->line = linenum;
3895 rule->file = strdup(file);
3896 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003897 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01003898 goto out;
3899 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003900 LIST_INIT(&rule->list);
3901 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
3902 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003903 else if (strcmp(args[0], "use-server") == 0) {
3904 struct server_rule *rule;
3905
3906 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003907 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003908 err_code |= ERR_ALERT | ERR_FATAL;
3909 goto out;
3910 }
3911
3912 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3913 err_code |= ERR_WARN;
3914
3915 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003916 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003917 err_code |= ERR_ALERT | ERR_FATAL;
3918 goto out;
3919 }
3920
3921 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003922 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
3923 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003924 err_code |= ERR_ALERT | ERR_FATAL;
3925 goto out;
3926 }
3927
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003928 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003929 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3930 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003931 err_code |= ERR_ALERT | ERR_FATAL;
3932 goto out;
3933 }
3934
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003935 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003936
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003937 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003938 rule->cond = cond;
3939 rule->srv.name = strdup(args[1]);
3940 LIST_INIT(&rule->list);
3941 LIST_ADDQ(&curproxy->server_rules, &rule->list);
3942 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
3943 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02003944 else if ((!strcmp(args[0], "force-persist")) ||
3945 (!strcmp(args[0], "ignore-persist"))) {
3946 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01003947
3948 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003949 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01003950 err_code |= ERR_ALERT | ERR_FATAL;
3951 goto out;
3952 }
3953
Cyril Bonté4288c5a2018-03-12 22:02:59 +01003954 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01003955 err_code |= ERR_WARN;
3956
Willy Tarreauef6494c2010-01-28 17:12:36 +01003957 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003958 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
3959 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01003960 err_code |= ERR_ALERT | ERR_FATAL;
3961 goto out;
3962 }
3963
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003964 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003965 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
3966 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01003967 err_code |= ERR_ALERT | ERR_FATAL;
3968 goto out;
3969 }
3970
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003971 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
3972 * where force-persist is applied.
3973 */
3974 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01003975
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003976 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01003977 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02003978 if (!strcmp(args[0], "force-persist")) {
3979 rule->type = PERSIST_TYPE_FORCE;
3980 } else {
3981 rule->type = PERSIST_TYPE_IGNORE;
3982 }
Willy Tarreau4de91492010-01-22 19:10:05 +01003983 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02003984 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01003985 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003986 else if (!strcmp(args[0], "stick-table")) {
3987 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02003988 struct proxy *other;
3989
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02003990 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02003991 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003992 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
3993 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02003994 err_code |= ERR_ALERT | ERR_FATAL;
3995 goto out;
3996 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003997
Emeric Brun32da3c42010-09-23 18:39:19 +02003998 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01003999 curproxy->table.type = (unsigned int)-1;
4000 while (*args[myidx]) {
4001 const char *err;
4002
4003 if (strcmp(args[myidx], "size") == 0) {
4004 myidx++;
4005 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004006 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4007 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004008 err_code |= ERR_ALERT | ERR_FATAL;
4009 goto out;
4010 }
4011 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004012 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4013 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004014 err_code |= ERR_ALERT | ERR_FATAL;
4015 goto out;
4016 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004017 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004018 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004019 else if (strcmp(args[myidx], "peers") == 0) {
4020 myidx++;
Godbach50523162013-12-11 19:48:57 +08004021 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004022 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4023 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004024 err_code |= ERR_ALERT | ERR_FATAL;
4025 goto out;
Godbach50523162013-12-11 19:48:57 +08004026 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004027 curproxy->table.peers.name = strdup(args[myidx++]);
4028 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004029 else if (strcmp(args[myidx], "expire") == 0) {
4030 myidx++;
4031 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004032 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4033 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004034 err_code |= ERR_ALERT | ERR_FATAL;
4035 goto out;
4036 }
4037 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4038 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004039 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4040 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004041 err_code |= ERR_ALERT | ERR_FATAL;
4042 goto out;
4043 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004044 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004045 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4046 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004047 err_code |= ERR_ALERT | ERR_FATAL;
4048 goto out;
4049 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004050 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004051 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004052 }
4053 else if (strcmp(args[myidx], "nopurge") == 0) {
4054 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004055 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004056 }
4057 else if (strcmp(args[myidx], "type") == 0) {
4058 myidx++;
4059 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004060 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4061 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004062 err_code |= ERR_ALERT | ERR_FATAL;
4063 goto out;
4064 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004065 /* myidx already points to next arg */
4066 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004067 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004068 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004069 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004070
4071 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004072 nw = args[myidx];
4073 while (*nw) {
4074 /* the "store" keyword supports a comma-separated list */
4075 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004076 sa = NULL; /* store arg */
4077 while (*nw && *nw != ',') {
4078 if (*nw == '(') {
4079 *nw = 0;
4080 sa = ++nw;
4081 while (*nw != ')') {
4082 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004083 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4084 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004085 err_code |= ERR_ALERT | ERR_FATAL;
4086 goto out;
4087 }
4088 nw++;
4089 }
4090 *nw = '\0';
4091 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004092 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004093 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004094 if (*nw)
4095 *nw++ = '\0';
4096 type = stktable_get_data_type(cw);
4097 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004098 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4099 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004100 err_code |= ERR_ALERT | ERR_FATAL;
4101 goto out;
4102 }
Willy Tarreauac782882010-06-20 10:41:54 +02004103
4104 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4105 switch (err) {
4106 case PE_NONE: break;
4107 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004108 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4109 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004110 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004111 break;
4112
4113 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004114 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4115 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004116 err_code |= ERR_ALERT | ERR_FATAL;
4117 goto out;
4118
4119 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004120 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4121 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004122 err_code |= ERR_ALERT | ERR_FATAL;
4123 goto out;
4124
4125 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004126 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4127 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004128 err_code |= ERR_ALERT | ERR_FATAL;
4129 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004130 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004131 }
4132 myidx++;
4133 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004134 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004135 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4136 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004137 err_code |= ERR_ALERT | ERR_FATAL;
4138 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004139 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004140 }
4141
4142 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004143 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4144 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004145 err_code |= ERR_ALERT | ERR_FATAL;
4146 goto out;
4147 }
4148
4149 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004150 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4151 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004152 err_code |= ERR_ALERT | ERR_FATAL;
4153 goto out;
4154 }
4155 }
4156 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004157 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004158 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004159 int myidx = 0;
4160 const char *name = NULL;
4161 int flags;
4162
4163 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004164 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004165 err_code |= ERR_ALERT | ERR_FATAL;
4166 goto out;
4167 }
4168
4169 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4170 err_code |= ERR_WARN;
4171 goto out;
4172 }
4173
4174 myidx++;
4175 if ((strcmp(args[myidx], "store") == 0) ||
4176 (strcmp(args[myidx], "store-request") == 0)) {
4177 myidx++;
4178 flags = STK_IS_STORE;
4179 }
4180 else if (strcmp(args[myidx], "store-response") == 0) {
4181 myidx++;
4182 flags = STK_IS_STORE | STK_ON_RSP;
4183 }
4184 else if (strcmp(args[myidx], "match") == 0) {
4185 myidx++;
4186 flags = STK_IS_MATCH;
4187 }
4188 else if (strcmp(args[myidx], "on") == 0) {
4189 myidx++;
4190 flags = STK_IS_MATCH | STK_IS_STORE;
4191 }
4192 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004193 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004194 err_code |= ERR_ALERT | ERR_FATAL;
4195 goto out;
4196 }
4197
4198 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004199 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004200 err_code |= ERR_ALERT | ERR_FATAL;
4201 goto out;
4202 }
4203
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004204 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004205 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004206 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004207 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004208 err_code |= ERR_ALERT | ERR_FATAL;
4209 goto out;
4210 }
4211
4212 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004213 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004214 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4215 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004216 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004217 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004218 goto out;
4219 }
4220 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004221 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004222 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4223 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004224 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004225 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004226 goto out;
4227 }
4228 }
4229
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004230 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004231 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004232
Emeric Brunb982a3d2010-01-04 15:45:53 +01004233 if (strcmp(args[myidx], "table") == 0) {
4234 myidx++;
4235 name = args[myidx++];
4236 }
4237
Willy Tarreauef6494c2010-01-28 17:12:36 +01004238 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004239 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004240 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4241 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004242 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004243 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004244 goto out;
4245 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004246 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004247 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004248 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4249 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004250 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004251 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004252 goto out;
4253 }
Emeric Brun97679e72010-09-23 17:56:44 +02004254 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004255 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004256 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004257 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004258
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004259 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004260 rule->cond = cond;
4261 rule->expr = expr;
4262 rule->flags = flags;
4263 rule->table.name = name ? strdup(name) : NULL;
4264 LIST_INIT(&rule->list);
4265 if (flags & STK_ON_RSP)
4266 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4267 else
4268 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4269 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004270 else if (!strcmp(args[0], "stats")) {
4271 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4272 curproxy->uri_auth = NULL; /* we must detach from the default config */
4273
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004274 if (!*args[1]) {
4275 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004276 } else if (!strcmp(args[1], "admin")) {
4277 struct stats_admin_rule *rule;
4278
4279 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004280 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 +02004281 err_code |= ERR_ALERT | ERR_FATAL;
4282 goto out;
4283 }
4284
4285 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004286 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004287 err_code |= ERR_ALERT | ERR_ABORT;
4288 goto out;
4289 }
4290
4291 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004292 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4293 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004294 err_code |= ERR_ALERT | ERR_FATAL;
4295 goto out;
4296 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004297 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004298 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4299 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004300 err_code |= ERR_ALERT | ERR_FATAL;
4301 goto out;
4302 }
4303
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004304 err_code |= warnif_cond_conflicts(cond,
4305 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4306 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004307
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004308 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004309 rule->cond = cond;
4310 LIST_INIT(&rule->list);
4311 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004312 } else if (!strcmp(args[1], "uri")) {
4313 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004314 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004315 err_code |= ERR_ALERT | ERR_FATAL;
4316 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004317 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004318 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004319 err_code |= ERR_ALERT | ERR_ABORT;
4320 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004321 }
4322 } else if (!strcmp(args[1], "realm")) {
4323 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004324 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004325 err_code |= ERR_ALERT | ERR_FATAL;
4326 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004327 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004328 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004329 err_code |= ERR_ALERT | ERR_ABORT;
4330 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004331 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004332 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004333 unsigned interval;
4334
4335 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4336 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004337 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4338 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004339 err_code |= ERR_ALERT | ERR_FATAL;
4340 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004341 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004342 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004343 err_code |= ERR_ALERT | ERR_ABORT;
4344 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004345 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004346 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004347 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004348
4349 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004350 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004351 err_code |= ERR_ALERT | ERR_FATAL;
4352 goto out;
4353 }
4354
4355 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004356 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004357 err_code |= ERR_ALERT | ERR_ABORT;
4358 goto out;
4359 }
4360
Willy Tarreauff011f22011-01-06 17:51:27 +01004361 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004362 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004363 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4364 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004365 err_code |= ERR_WARN;
4366 }
4367
Willy Tarreauff011f22011-01-06 17:51:27 +01004368 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004369
Willy Tarreauff011f22011-01-06 17:51:27 +01004370 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004371 err_code |= ERR_ALERT | ERR_ABORT;
4372 goto out;
4373 }
4374
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004375 err_code |= warnif_cond_conflicts(rule->cond,
4376 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4377 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004378 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004379
Willy Tarreaubaaee002006-06-26 02:48:02 +02004380 } else if (!strcmp(args[1], "auth")) {
4381 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004382 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004383 err_code |= ERR_ALERT | ERR_FATAL;
4384 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004385 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004386 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004387 err_code |= ERR_ALERT | ERR_ABORT;
4388 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004389 }
4390 } else if (!strcmp(args[1], "scope")) {
4391 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004392 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004393 err_code |= ERR_ALERT | ERR_FATAL;
4394 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004395 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004396 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004397 err_code |= ERR_ALERT | ERR_ABORT;
4398 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004399 }
4400 } else if (!strcmp(args[1], "enable")) {
4401 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004402 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004403 err_code |= ERR_ALERT | ERR_ABORT;
4404 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004405 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004406 } else if (!strcmp(args[1], "hide-version")) {
4407 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004408 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004409 err_code |= ERR_ALERT | ERR_ABORT;
4410 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004411 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004412 } else if (!strcmp(args[1], "show-legends")) {
4413 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004414 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004415 err_code |= ERR_ALERT | ERR_ABORT;
4416 goto out;
4417 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004418 } else if (!strcmp(args[1], "show-node")) {
4419
4420 if (*args[2]) {
4421 int i;
4422 char c;
4423
4424 for (i=0; args[2][i]; i++) {
4425 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004426 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4427 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004428 break;
4429 }
4430
4431 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004432 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4433 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4434 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004435 err_code |= ERR_ALERT | ERR_FATAL;
4436 goto out;
4437 }
4438 }
4439
4440 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004441 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004442 err_code |= ERR_ALERT | ERR_ABORT;
4443 goto out;
4444 }
4445 } else if (!strcmp(args[1], "show-desc")) {
4446 char *desc = NULL;
4447
4448 if (*args[2]) {
4449 int i, len=0;
4450 char *d;
4451
Willy Tarreau348acfe2014-04-14 15:00:39 +02004452 for (i = 2; *args[i]; i++)
4453 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004454
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004455 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004456
Willy Tarreau348acfe2014-04-14 15:00:39 +02004457 d += snprintf(d, desc + len - d, "%s", args[2]);
4458 for (i = 3; *args[i]; i++)
4459 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004460 }
4461
4462 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004463 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4464 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004465 else {
4466 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4467 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004468 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004469 err_code |= ERR_ALERT | ERR_ABORT;
4470 goto out;
4471 }
4472 free(desc);
4473 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004474 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004475stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004476 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4477 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004478 err_code |= ERR_ALERT | ERR_FATAL;
4479 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004480 }
4481 }
4482 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004483 int optnum;
4484
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004485 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004486 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4487 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004488 err_code |= ERR_ALERT | ERR_FATAL;
4489 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004490 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004491
4492 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4493 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004494 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004495 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4496 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004497 err_code |= ERR_ALERT | ERR_FATAL;
4498 goto out;
4499 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004500 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4501 goto out;
4502
Willy Tarreau93893792009-07-23 13:19:11 +02004503 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4504 err_code |= ERR_WARN;
4505 goto out;
4506 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004507
Willy Tarreau3842f002009-06-14 11:39:52 +02004508 curproxy->no_options &= ~cfg_opts[optnum].val;
4509 curproxy->options &= ~cfg_opts[optnum].val;
4510
4511 switch (kwm) {
4512 case KWM_STD:
4513 curproxy->options |= cfg_opts[optnum].val;
4514 break;
4515 case KWM_NO:
4516 curproxy->no_options |= cfg_opts[optnum].val;
4517 break;
4518 case KWM_DEF: /* already cleared */
4519 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004520 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004521
Willy Tarreau93893792009-07-23 13:19:11 +02004522 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004523 }
4524 }
4525
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004526 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4527 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004528 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004529 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4530 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004531 err_code |= ERR_ALERT | ERR_FATAL;
4532 goto out;
4533 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004534 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4535 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004536 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4537 err_code |= ERR_WARN;
4538 goto out;
4539 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004540
Willy Tarreau3842f002009-06-14 11:39:52 +02004541 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4542 curproxy->options2 &= ~cfg_opts2[optnum].val;
4543
4544 switch (kwm) {
4545 case KWM_STD:
4546 curproxy->options2 |= cfg_opts2[optnum].val;
4547 break;
4548 case KWM_NO:
4549 curproxy->no_options2 |= cfg_opts2[optnum].val;
4550 break;
4551 case KWM_DEF: /* already cleared */
4552 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004553 }
Willy Tarreau93893792009-07-23 13:19:11 +02004554 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004555 }
4556 }
4557
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004558 /* HTTP options override each other. They can be cancelled using
4559 * "no option xxx" which only switches to default mode if the mode
4560 * was this one (useful for cancelling options set in defaults
4561 * sections).
4562 */
4563 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004564 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4565 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004566 if (kwm == KWM_STD) {
4567 curproxy->options &= ~PR_O_HTTP_MODE;
4568 curproxy->options |= PR_O_HTTP_PCL;
4569 goto out;
4570 }
4571 else if (kwm == KWM_NO) {
4572 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4573 curproxy->options &= ~PR_O_HTTP_MODE;
4574 goto out;
4575 }
4576 }
4577 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004578 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4579 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004580 if (kwm == KWM_STD) {
4581 curproxy->options &= ~PR_O_HTTP_MODE;
4582 curproxy->options |= PR_O_HTTP_FCL;
4583 goto out;
4584 }
4585 else if (kwm == KWM_NO) {
4586 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4587 curproxy->options &= ~PR_O_HTTP_MODE;
4588 goto out;
4589 }
4590 }
4591 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004592 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4593 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004594 if (kwm == KWM_STD) {
4595 curproxy->options &= ~PR_O_HTTP_MODE;
4596 curproxy->options |= PR_O_HTTP_SCL;
4597 goto out;
4598 }
4599 else if (kwm == KWM_NO) {
4600 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4601 curproxy->options &= ~PR_O_HTTP_MODE;
4602 goto out;
4603 }
4604 }
4605 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004606 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4607 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004608 if (kwm == KWM_STD) {
4609 curproxy->options &= ~PR_O_HTTP_MODE;
4610 curproxy->options |= PR_O_HTTP_KAL;
4611 goto out;
4612 }
4613 else if (kwm == KWM_NO) {
4614 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4615 curproxy->options &= ~PR_O_HTTP_MODE;
4616 goto out;
4617 }
4618 }
4619 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004620 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4621 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004622 if (kwm == KWM_STD) {
4623 curproxy->options &= ~PR_O_HTTP_MODE;
4624 curproxy->options |= PR_O_HTTP_TUN;
4625 goto out;
4626 }
4627 else if (kwm == KWM_NO) {
4628 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4629 curproxy->options &= ~PR_O_HTTP_MODE;
4630 goto out;
4631 }
4632 }
4633
Joseph Lynch726ab712015-05-11 23:25:34 -07004634 /* Redispatch can take an integer argument that control when the
4635 * resispatch occurs. All values are relative to the retries option.
4636 * This can be cancelled using "no option xxx".
4637 */
4638 if (strcmp(args[1], "redispatch") == 0) {
4639 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4640 err_code |= ERR_WARN;
4641 goto out;
4642 }
4643
4644 curproxy->no_options &= ~PR_O_REDISP;
4645 curproxy->options &= ~PR_O_REDISP;
4646
4647 switch (kwm) {
4648 case KWM_STD:
4649 curproxy->options |= PR_O_REDISP;
4650 curproxy->redispatch_after = -1;
4651 if(*args[2]) {
4652 curproxy->redispatch_after = atol(args[2]);
4653 }
4654 break;
4655 case KWM_NO:
4656 curproxy->no_options |= PR_O_REDISP;
4657 curproxy->redispatch_after = 0;
4658 break;
4659 case KWM_DEF: /* already cleared */
4660 break;
4661 }
4662 goto out;
4663 }
4664
Willy Tarreau3842f002009-06-14 11:39:52 +02004665 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004666 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4667 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004668 err_code |= ERR_ALERT | ERR_FATAL;
4669 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004670 }
4671
Emeric Brun3a058f32009-06-30 18:26:00 +02004672 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004673 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004674 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004675 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004676 if (*(args[2]) != '\0') {
4677 if (!strcmp(args[2], "clf")) {
4678 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004679 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004680 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004681 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004682 err_code |= ERR_ALERT | ERR_FATAL;
4683 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004684 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004685 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4686 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004687 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004688 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4689 char *oldlogformat = "log-format";
4690 char *clflogformat = "";
4691
4692 if (curproxy->conf.logformat_string == default_http_log_format)
4693 oldlogformat = "option httplog";
4694 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4695 oldlogformat = "option tcplog";
4696 else if (curproxy->conf.logformat_string == clf_http_log_format)
4697 oldlogformat = "option httplog clf";
4698 if (logformat == clf_http_log_format)
4699 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004700 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4701 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004702 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004703 if (curproxy->conf.logformat_string != default_http_log_format &&
4704 curproxy->conf.logformat_string != default_tcp_log_format &&
4705 curproxy->conf.logformat_string != clf_http_log_format)
4706 free(curproxy->conf.logformat_string);
4707 curproxy->conf.logformat_string = logformat;
4708
4709 free(curproxy->conf.lfs_file);
4710 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4711 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004712
4713 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4714 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4715 file, linenum, curproxy->id);
4716 err_code |= ERR_WARN;
4717 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004718 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004719 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004720 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4721 char *oldlogformat = "log-format";
4722
4723 if (curproxy->conf.logformat_string == default_http_log_format)
4724 oldlogformat = "option httplog";
4725 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4726 oldlogformat = "option tcplog";
4727 else if (curproxy->conf.logformat_string == clf_http_log_format)
4728 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004729 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4730 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004731 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004732 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004733 if (curproxy->conf.logformat_string != default_http_log_format &&
4734 curproxy->conf.logformat_string != default_tcp_log_format &&
4735 curproxy->conf.logformat_string != clf_http_log_format)
4736 free(curproxy->conf.logformat_string);
4737 curproxy->conf.logformat_string = default_tcp_log_format;
4738
4739 free(curproxy->conf.lfs_file);
4740 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4741 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004742
4743 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4744 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004745
4746 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4747 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4748 file, linenum, curproxy->id);
4749 err_code |= ERR_WARN;
4750 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004751 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004752 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004753 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004754 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004755 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004756
William Lallemanddf1425a2015-04-28 20:17:49 +02004757 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4758 goto out;
4759
Willy Tarreau13943ab2006-12-31 00:24:10 +01004760 if (curproxy->cap & PR_CAP_FE)
4761 curproxy->options |= PR_O_TCP_CLI_KA;
4762 if (curproxy->cap & PR_CAP_BE)
4763 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004764 }
4765 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004766 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004767 err_code |= ERR_WARN;
4768
Willy Tarreaubaaee002006-06-26 02:48:02 +02004769 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004770 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004771 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004772 curproxy->options2 &= ~PR_O2_CHK_ANY;
4773 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004774 if (!*args[2]) { /* no argument */
4775 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4776 curproxy->check_len = strlen(DEF_CHECK_REQ);
4777 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004778 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004779 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004780 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004781 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004782 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004783 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004784 if (*args[4])
4785 reqlen += strlen(args[4]);
4786 else
4787 reqlen += strlen("HTTP/1.0");
4788
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004789 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004790 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004791 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004792 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004793 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4794 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004795 }
4796 else if (!strcmp(args[1], "ssl-hello-chk")) {
4797 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004798 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004799 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004800
Willy Tarreaua534fea2008-08-03 12:19:50 +02004801 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004802 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004803 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004804 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004805
4806 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4807 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004808 }
Willy Tarreau23677902007-05-08 23:50:35 +02004809 else if (!strcmp(args[1], "smtpchk")) {
4810 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004811 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004812 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004813 curproxy->options2 &= ~PR_O2_CHK_ANY;
4814 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004815
4816 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4817 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4818 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4819 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4820 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4821 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004822 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004823 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4824 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4825 } else {
4826 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4827 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4828 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4829 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4830 }
4831 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004832 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4833 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004834 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004835 else if (!strcmp(args[1], "pgsql-check")) {
4836 /* use PostgreSQL request to check servers' health */
4837 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4838 err_code |= ERR_WARN;
4839
4840 free(curproxy->check_req);
4841 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004842 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004843 curproxy->options2 |= PR_O2_PGSQL_CHK;
4844
4845 if (*(args[2])) {
4846 int cur_arg = 2;
4847
4848 while (*(args[cur_arg])) {
4849 if (strcmp(args[cur_arg], "user") == 0) {
4850 char * packet;
4851 uint32_t packet_len;
4852 uint32_t pv;
4853
4854 /* suboption header - needs additional argument for it */
4855 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004856 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4857 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004858 err_code |= ERR_ALERT | ERR_FATAL;
4859 goto out;
4860 }
4861
4862 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4863 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4864 pv = htonl(0x30000); /* protocol version 3.0 */
4865
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004866 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004867
4868 memcpy(packet + 4, &pv, 4);
4869
4870 /* copy "user" */
4871 memcpy(packet + 8, "user", 4);
4872
4873 /* copy username */
4874 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
4875
4876 free(curproxy->check_req);
4877 curproxy->check_req = packet;
4878 curproxy->check_len = packet_len;
4879
4880 packet_len = htonl(packet_len);
4881 memcpy(packet, &packet_len, 4);
4882 cur_arg += 2;
4883 } else {
4884 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004885 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
4886 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004887 err_code |= ERR_ALERT | ERR_FATAL;
4888 goto out;
4889 }
4890 } /* end while loop */
4891 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004892 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4893 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004894 }
4895
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004896 else if (!strcmp(args[1], "redis-check")) {
4897 /* use REDIS PING request to check servers' health */
4898 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4899 err_code |= ERR_WARN;
4900
4901 free(curproxy->check_req);
4902 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004903 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004904 curproxy->options2 |= PR_O2_REDIS_CHK;
4905
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004906 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004907 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
4908 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02004909
4910 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4911 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004912 }
4913
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004914 else if (!strcmp(args[1], "mysql-check")) {
4915 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004916 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4917 err_code |= ERR_WARN;
4918
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004919 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004920 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004921 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004922 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004923
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004924 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004925 * const char mysql40_client_auth_pkt[] = {
4926 * "\x0e\x00\x00" // packet length
4927 * "\x01" // packet number
4928 * "\x00\x00" // client capabilities
4929 * "\x00\x00\x01" // max packet
4930 * "haproxy\x00" // username (null terminated string)
4931 * "\x00" // filler (always 0x00)
4932 * "\x01\x00\x00" // packet length
4933 * "\x00" // packet number
4934 * "\x01" // COM_QUIT command
4935 * };
4936 */
4937
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004938 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
4939 * const char mysql41_client_auth_pkt[] = {
4940 * "\x0e\x00\x00\" // packet length
4941 * "\x01" // packet number
4942 * "\x00\x00\x00\x00" // client capabilities
4943 * "\x00\x00\x00\x01" // max packet
4944 * "\x21" // character set (UTF-8)
4945 * char[23] // All zeroes
4946 * "haproxy\x00" // username (null terminated string)
4947 * "\x00" // filler (always 0x00)
4948 * "\x01\x00\x00" // packet length
4949 * "\x00" // packet number
4950 * "\x01" // COM_QUIT command
4951 * };
4952 */
4953
4954
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004955 if (*(args[2])) {
4956 int cur_arg = 2;
4957
4958 while (*(args[cur_arg])) {
4959 if (strcmp(args[cur_arg], "user") == 0) {
4960 char *mysqluser;
4961 int packetlen, reqlen, userlen;
4962
4963 /* suboption header - needs additional argument for it */
4964 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004965 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4966 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004967 err_code |= ERR_ALERT | ERR_FATAL;
4968 goto out;
4969 }
4970 mysqluser = args[cur_arg + 1];
4971 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004972
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004973 if (*(args[cur_arg+2])) {
4974 if (!strcmp(args[cur_arg+2], "post-41")) {
4975 packetlen = userlen + 7 + 27;
4976 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004977
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004978 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004979 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004980 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004981
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004982 snprintf(curproxy->check_req, 4, "%c%c%c",
4983 ((unsigned char) packetlen & 0xff),
4984 ((unsigned char) (packetlen >> 8) & 0xff),
4985 ((unsigned char) (packetlen >> 16) & 0xff));
4986
4987 curproxy->check_req[3] = 1;
4988 curproxy->check_req[5] = 130;
4989 curproxy->check_req[11] = 1;
4990 curproxy->check_req[12] = 33;
4991 memcpy(&curproxy->check_req[36], mysqluser, userlen);
4992 curproxy->check_req[36 + userlen + 1 + 1] = 1;
4993 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
4994 cur_arg += 3;
4995 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004996 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 +02004997 err_code |= ERR_ALERT | ERR_FATAL;
4998 goto out;
4999 }
5000 } else {
5001 packetlen = userlen + 7;
5002 reqlen = packetlen + 9;
5003
5004 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005005 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005006 curproxy->check_len = reqlen;
5007
5008 snprintf(curproxy->check_req, 4, "%c%c%c",
5009 ((unsigned char) packetlen & 0xff),
5010 ((unsigned char) (packetlen >> 8) & 0xff),
5011 ((unsigned char) (packetlen >> 16) & 0xff));
5012
5013 curproxy->check_req[3] = 1;
5014 curproxy->check_req[5] = 128;
5015 curproxy->check_req[8] = 1;
5016 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5017 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5018 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5019 cur_arg += 2;
5020 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005021 } else {
5022 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005023 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5024 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005025 err_code |= ERR_ALERT | ERR_FATAL;
5026 goto out;
5027 }
5028 } /* end while loop */
5029 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005030 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005031 else if (!strcmp(args[1], "ldap-check")) {
5032 /* use LDAP request to check servers' health */
5033 free(curproxy->check_req);
5034 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005035 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005036 curproxy->options2 |= PR_O2_LDAP_CHK;
5037
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005038 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005039 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5040 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005041 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5042 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005043 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005044 else if (!strcmp(args[1], "spop-check")) {
5045 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005046 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5047 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005048 err_code |= ERR_ALERT | ERR_FATAL;
5049 goto out;
5050 }
5051 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005052 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5053 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005054 err_code |= ERR_ALERT | ERR_FATAL;
5055 goto out;
5056 }
5057
5058 /* use SPOE request to check servers' health */
5059 free(curproxy->check_req);
5060 curproxy->check_req = NULL;
5061 curproxy->options2 &= ~PR_O2_CHK_ANY;
5062 curproxy->options2 |= PR_O2_SPOP_CHK;
5063
Christopher Faulet8ef75252017-02-20 22:56:03 +01005064 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005065 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005066 err_code |= ERR_ALERT | ERR_FATAL;
5067 goto out;
5068 }
5069 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5070 goto out;
5071 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005072 else if (!strcmp(args[1], "tcp-check")) {
5073 /* use raw TCPCHK send/expect to check servers' health */
5074 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5075 err_code |= ERR_WARN;
5076
5077 free(curproxy->check_req);
5078 curproxy->check_req = NULL;
5079 curproxy->options2 &= ~PR_O2_CHK_ANY;
5080 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005081 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5082 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005083 }
Simon Horman98637e52014-06-20 12:30:16 +09005084 else if (!strcmp(args[1], "external-check")) {
5085 /* excute an external command to check servers' health */
5086 free(curproxy->check_req);
5087 curproxy->check_req = NULL;
5088 curproxy->options2 &= ~PR_O2_CHK_ANY;
5089 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005090 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5091 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005092 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005093 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005094 int cur_arg;
5095
5096 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5097 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005098 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005099
Willy Tarreau87cf5142011-08-19 22:57:24 +02005100 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005101
5102 free(curproxy->fwdfor_hdr_name);
5103 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5104 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5105
5106 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5107 cur_arg = 2;
5108 while (*(args[cur_arg])) {
5109 if (!strcmp(args[cur_arg], "except")) {
5110 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005111 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005112 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5113 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005114 err_code |= ERR_ALERT | ERR_FATAL;
5115 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005116 }
5117 /* flush useless bits */
5118 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005119 cur_arg += 2;
5120 } else if (!strcmp(args[cur_arg], "header")) {
5121 /* suboption header - needs additional argument for it */
5122 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005123 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5124 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005125 err_code |= ERR_ALERT | ERR_FATAL;
5126 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005127 }
5128 free(curproxy->fwdfor_hdr_name);
5129 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5130 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5131 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005132 } else if (!strcmp(args[cur_arg], "if-none")) {
5133 curproxy->options &= ~PR_O_FF_ALWAYS;
5134 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005135 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005136 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005137 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5138 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005139 err_code |= ERR_ALERT | ERR_FATAL;
5140 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005141 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005142 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005143 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005144 else if (!strcmp(args[1], "originalto")) {
5145 int cur_arg;
5146
5147 /* insert x-original-to field, but not for the IP address listed as an except.
5148 * set default options (ie: bitfield, header name, etc)
5149 */
5150
5151 curproxy->options |= PR_O_ORGTO;
5152
5153 free(curproxy->orgto_hdr_name);
5154 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5155 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5156
Willy Tarreau87cf5142011-08-19 22:57:24 +02005157 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005158 cur_arg = 2;
5159 while (*(args[cur_arg])) {
5160 if (!strcmp(args[cur_arg], "except")) {
5161 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005162 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 +01005163 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5164 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005165 err_code |= ERR_ALERT | ERR_FATAL;
5166 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005167 }
5168 /* flush useless bits */
5169 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5170 cur_arg += 2;
5171 } else if (!strcmp(args[cur_arg], "header")) {
5172 /* suboption header - needs additional argument for it */
5173 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005174 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5175 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005176 err_code |= ERR_ALERT | ERR_FATAL;
5177 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005178 }
5179 free(curproxy->orgto_hdr_name);
5180 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5181 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5182 cur_arg += 2;
5183 } else {
5184 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005185 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5186 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005187 err_code |= ERR_ALERT | ERR_FATAL;
5188 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005189 }
5190 } /* end while loop */
5191 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005192 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005193 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005194 err_code |= ERR_ALERT | ERR_FATAL;
5195 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005196 }
Willy Tarreau93893792009-07-23 13:19:11 +02005197 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005198 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005199 else if (!strcmp(args[0], "default_backend")) {
5200 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005201 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005202
5203 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005204 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005205 err_code |= ERR_ALERT | ERR_FATAL;
5206 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005207 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005208 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005209 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005210
5211 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5212 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005213 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005214 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005215 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005216 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005217
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005218 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005219 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5220 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005221 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005222 /* enable reconnections to dispatch */
5223 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005224
5225 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5226 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005227 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005228 else if (!strcmp(args[0], "http-reuse")) {
5229 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5230 err_code |= ERR_WARN;
5231
5232 if (strcmp(args[1], "never") == 0) {
5233 /* enable a graceful server shutdown on an HTTP 404 response */
5234 curproxy->options &= ~PR_O_REUSE_MASK;
5235 curproxy->options |= PR_O_REUSE_NEVR;
5236 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5237 goto out;
5238 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005239 else if (strcmp(args[1], "safe") == 0) {
5240 /* enable a graceful server shutdown on an HTTP 404 response */
5241 curproxy->options &= ~PR_O_REUSE_MASK;
5242 curproxy->options |= PR_O_REUSE_SAFE;
5243 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5244 goto out;
5245 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005246 else if (strcmp(args[1], "aggressive") == 0) {
5247 curproxy->options &= ~PR_O_REUSE_MASK;
5248 curproxy->options |= PR_O_REUSE_AGGR;
5249 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5250 goto out;
5251 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005252 else if (strcmp(args[1], "always") == 0) {
5253 /* enable a graceful server shutdown on an HTTP 404 response */
5254 curproxy->options &= ~PR_O_REUSE_MASK;
5255 curproxy->options |= PR_O_REUSE_ALWS;
5256 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5257 goto out;
5258 }
5259 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005260 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005261 err_code |= ERR_ALERT | ERR_FATAL;
5262 goto out;
5263 }
5264 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005265 else if (!strcmp(args[0], "http-check")) {
5266 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005267 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005268
5269 if (strcmp(args[1], "disable-on-404") == 0) {
5270 /* enable a graceful server shutdown on an HTTP 404 response */
5271 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005272 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5273 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005274 }
Willy Tarreauef781042010-01-27 11:53:01 +01005275 else if (strcmp(args[1], "send-state") == 0) {
5276 /* enable emission of the apparent state of a server in HTTP checks */
5277 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005278 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5279 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005280 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005281 else if (strcmp(args[1], "expect") == 0) {
5282 const char *ptr_arg;
5283 int cur_arg;
5284
5285 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005286 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005287 err_code |= ERR_ALERT | ERR_FATAL;
5288 goto out;
5289 }
5290
5291 cur_arg = 2;
5292 /* consider exclamation marks, sole or at the beginning of a word */
5293 while (*(ptr_arg = args[cur_arg])) {
5294 while (*ptr_arg == '!') {
5295 curproxy->options2 ^= PR_O2_EXP_INV;
5296 ptr_arg++;
5297 }
5298 if (*ptr_arg)
5299 break;
5300 cur_arg++;
5301 }
5302 /* now ptr_arg points to the beginning of a word past any possible
5303 * exclamation mark, and cur_arg is the argument which holds this word.
5304 */
5305 if (strcmp(ptr_arg, "status") == 0) {
5306 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005307 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5308 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005309 err_code |= ERR_ALERT | ERR_FATAL;
5310 goto out;
5311 }
5312 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005313 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005314 curproxy->expect_str = strdup(args[cur_arg + 1]);
5315 }
5316 else if (strcmp(ptr_arg, "string") == 0) {
5317 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005318 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5319 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005320 err_code |= ERR_ALERT | ERR_FATAL;
5321 goto out;
5322 }
5323 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005324 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005325 curproxy->expect_str = strdup(args[cur_arg + 1]);
5326 }
5327 else if (strcmp(ptr_arg, "rstatus") == 0) {
5328 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005329 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5330 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005331 err_code |= ERR_ALERT | ERR_FATAL;
5332 goto out;
5333 }
5334 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005335 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005336 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005337 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005338 free(curproxy->expect_regex);
5339 curproxy->expect_regex = NULL;
5340 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005341 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005342 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5343 error = NULL;
5344 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005345 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5346 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005347 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005348 err_code |= ERR_ALERT | ERR_FATAL;
5349 goto out;
5350 }
5351 }
5352 else if (strcmp(ptr_arg, "rstring") == 0) {
5353 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005354 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5355 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005356 err_code |= ERR_ALERT | ERR_FATAL;
5357 goto out;
5358 }
5359 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005360 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005361 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005362 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005363 free(curproxy->expect_regex);
5364 curproxy->expect_regex = NULL;
5365 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005366 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005367 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5368 error = NULL;
5369 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005370 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5371 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005372 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005373 err_code |= ERR_ALERT | ERR_FATAL;
5374 goto out;
5375 }
5376 }
5377 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005378 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5379 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005380 err_code |= ERR_ALERT | ERR_FATAL;
5381 goto out;
5382 }
5383 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005384 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005385 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 +02005386 err_code |= ERR_ALERT | ERR_FATAL;
5387 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005388 }
5389 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005390 else if (!strcmp(args[0], "tcp-check")) {
5391 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5392 err_code |= ERR_WARN;
5393
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005394 if (strcmp(args[1], "comment") == 0) {
5395 int cur_arg;
5396 struct tcpcheck_rule *tcpcheck;
5397
5398 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005399 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005400 tcpcheck->action = TCPCHK_ACT_COMMENT;
5401
5402 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005403 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5404 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005405 err_code |= ERR_ALERT | ERR_FATAL;
5406 goto out;
5407 }
5408
5409 tcpcheck->comment = strdup(args[cur_arg + 1]);
5410
5411 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005412 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5413 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005414 }
5415 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005416 const char *ptr_arg;
5417 int cur_arg;
5418 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005419
5420 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005421 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5422 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5423 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5424 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5425 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005426
Willy Tarreau5581c272015-05-13 12:24:53 +02005427 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5428 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005429 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5430 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005431 err_code |= ERR_ALERT | ERR_FATAL;
5432 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005433 }
5434
5435 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005436 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005437 tcpcheck->action = TCPCHK_ACT_CONNECT;
5438
5439 /* parsing each parameters to fill up the rule */
5440 while (*(ptr_arg = args[cur_arg])) {
5441 /* tcp port */
5442 if (strcmp(args[cur_arg], "port") == 0) {
5443 if ( (atol(args[cur_arg + 1]) > 65535) ||
5444 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005445 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5446 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005447 err_code |= ERR_ALERT | ERR_FATAL;
5448 goto out;
5449 }
5450 tcpcheck->port = atol(args[cur_arg + 1]);
5451 cur_arg += 2;
5452 }
5453 /* send proxy protocol */
5454 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5455 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5456 cur_arg++;
5457 }
5458#ifdef USE_OPENSSL
5459 else if (strcmp(args[cur_arg], "ssl") == 0) {
5460 curproxy->options |= PR_O_TCPCHK_SSL;
5461 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5462 cur_arg++;
5463 }
5464#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005465 /* comment for this tcpcheck line */
5466 else if (strcmp(args[cur_arg], "comment") == 0) {
5467 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005468 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5469 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005470 err_code |= ERR_ALERT | ERR_FATAL;
5471 goto out;
5472 }
5473 tcpcheck->comment = strdup(args[cur_arg + 1]);
5474 cur_arg += 2;
5475 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005476 else {
5477#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005478 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 +01005479#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005480 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 +01005481#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005482 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005483 err_code |= ERR_ALERT | ERR_FATAL;
5484 goto out;
5485 }
5486
5487 }
5488
5489 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5490 }
5491 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005492 if (! *(args[2]) ) {
5493 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005494 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5495 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005496 err_code |= ERR_ALERT | ERR_FATAL;
5497 goto out;
5498 } else {
5499 struct tcpcheck_rule *tcpcheck;
5500
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005501 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005502
5503 tcpcheck->action = TCPCHK_ACT_SEND;
5504 tcpcheck->string_len = strlen(args[2]);
5505 tcpcheck->string = strdup(args[2]);
5506 tcpcheck->expect_regex = NULL;
5507
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005508 /* comment for this tcpcheck line */
5509 if (strcmp(args[3], "comment") == 0) {
5510 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005511 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5512 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005513 err_code |= ERR_ALERT | ERR_FATAL;
5514 goto out;
5515 }
5516 tcpcheck->comment = strdup(args[4]);
5517 }
5518
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005519 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5520 }
5521 }
5522 else if (strcmp(args[1], "send-binary") == 0) {
5523 if (! *(args[2]) ) {
5524 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005525 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5526 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005527 err_code |= ERR_ALERT | ERR_FATAL;
5528 goto out;
5529 } else {
5530 struct tcpcheck_rule *tcpcheck;
5531 char *err = NULL;
5532
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005533 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005534
5535 tcpcheck->action = TCPCHK_ACT_SEND;
5536 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005537 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5538 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005539 err_code |= ERR_ALERT | ERR_FATAL;
5540 goto out;
5541 }
5542 tcpcheck->expect_regex = NULL;
5543
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005544 /* comment for this tcpcheck line */
5545 if (strcmp(args[3], "comment") == 0) {
5546 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005547 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5548 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005549 err_code |= ERR_ALERT | ERR_FATAL;
5550 goto out;
5551 }
5552 tcpcheck->comment = strdup(args[4]);
5553 }
5554
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005555 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5556 }
5557 }
5558 else if (strcmp(args[1], "expect") == 0) {
5559 const char *ptr_arg;
5560 int cur_arg;
5561 int inverse = 0;
5562
5563 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005564 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005565 err_code |= ERR_ALERT | ERR_FATAL;
5566 goto out;
5567 }
5568
5569 cur_arg = 2;
5570 /* consider exclamation marks, sole or at the beginning of a word */
5571 while (*(ptr_arg = args[cur_arg])) {
5572 while (*ptr_arg == '!') {
5573 inverse = !inverse;
5574 ptr_arg++;
5575 }
5576 if (*ptr_arg)
5577 break;
5578 cur_arg++;
5579 }
5580 /* now ptr_arg points to the beginning of a word past any possible
5581 * exclamation mark, and cur_arg is the argument which holds this word.
5582 */
5583 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005584 struct tcpcheck_rule *tcpcheck;
5585 char *err = NULL;
5586
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005587 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005588 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5589 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005590 err_code |= ERR_ALERT | ERR_FATAL;
5591 goto out;
5592 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005593
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005594 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005595
5596 tcpcheck->action = TCPCHK_ACT_EXPECT;
5597 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005598 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5599 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005600 err_code |= ERR_ALERT | ERR_FATAL;
5601 goto out;
5602 }
5603 tcpcheck->expect_regex = NULL;
5604 tcpcheck->inverse = inverse;
5605
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005606 /* tcpcheck comment */
5607 cur_arg += 2;
5608 if (strcmp(args[cur_arg], "comment") == 0) {
5609 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005610 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5611 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005612 err_code |= ERR_ALERT | ERR_FATAL;
5613 goto out;
5614 }
5615 tcpcheck->comment = strdup(args[cur_arg + 1]);
5616 }
5617
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005618 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5619 }
5620 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005621 struct tcpcheck_rule *tcpcheck;
5622
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005623 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005624 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5625 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005626 err_code |= ERR_ALERT | ERR_FATAL;
5627 goto out;
5628 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005629
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005630 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005631
5632 tcpcheck->action = TCPCHK_ACT_EXPECT;
5633 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5634 tcpcheck->string = strdup(args[cur_arg + 1]);
5635 tcpcheck->expect_regex = NULL;
5636 tcpcheck->inverse = inverse;
5637
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005638 /* tcpcheck comment */
5639 cur_arg += 2;
5640 if (strcmp(args[cur_arg], "comment") == 0) {
5641 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005642 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5643 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005644 err_code |= ERR_ALERT | ERR_FATAL;
5645 goto out;
5646 }
5647 tcpcheck->comment = strdup(args[cur_arg + 1]);
5648 }
5649
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005650 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5651 }
5652 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005653 struct tcpcheck_rule *tcpcheck;
5654
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005655 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005656 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5657 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005658 err_code |= ERR_ALERT | ERR_FATAL;
5659 goto out;
5660 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005661
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005662 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005663
5664 tcpcheck->action = TCPCHK_ACT_EXPECT;
5665 tcpcheck->string_len = 0;
5666 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005667 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5668 error = NULL;
5669 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005670 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5671 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005672 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005673 err_code |= ERR_ALERT | ERR_FATAL;
5674 goto out;
5675 }
5676 tcpcheck->inverse = inverse;
5677
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005678 /* tcpcheck comment */
5679 cur_arg += 2;
5680 if (strcmp(args[cur_arg], "comment") == 0) {
5681 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005682 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5683 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005684 err_code |= ERR_ALERT | ERR_FATAL;
5685 goto out;
5686 }
5687 tcpcheck->comment = strdup(args[cur_arg + 1]);
5688 }
5689
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005690 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5691 }
5692 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005693 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5694 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005695 err_code |= ERR_ALERT | ERR_FATAL;
5696 goto out;
5697 }
5698 }
5699 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005700 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 +02005701 err_code |= ERR_ALERT | ERR_FATAL;
5702 goto out;
5703 }
5704 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005705 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005706 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005707 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005708 err_code |= ERR_ALERT | ERR_FATAL;
5709 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005710 }
5711
Willy Tarreaub80c2302007-11-30 20:51:32 +01005712 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005713 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005714
5715 if (strcmp(args[1], "fail") == 0) {
5716 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005717 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005718 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5719 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005720 err_code |= ERR_ALERT | ERR_FATAL;
5721 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005722 }
5723
Willy Tarreau721d8e02017-12-01 18:25:08 +01005724 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005725 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005726 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5727 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005728 err_code |= ERR_ALERT | ERR_FATAL;
5729 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005730 }
5731 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5732 }
5733 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005734 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005735 err_code |= ERR_ALERT | ERR_FATAL;
5736 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005737 }
5738 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005739#ifdef TPROXY
5740 else if (!strcmp(args[0], "transparent")) {
5741 /* enable transparent proxy connections */
5742 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005743 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5744 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005745 }
5746#endif
5747 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005748 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005749 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005750
Willy Tarreaubaaee002006-06-26 02:48:02 +02005751 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005752 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005753 err_code |= ERR_ALERT | ERR_FATAL;
5754 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005755 }
5756 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005757 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5758 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005759 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005760 else if (!strcmp(args[0], "backlog")) { /* backlog */
5761 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005762 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005763
5764 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005765 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005766 err_code |= ERR_ALERT | ERR_FATAL;
5767 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005768 }
5769 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005770 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5771 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005772 }
Willy Tarreau86034312006-12-29 00:10:33 +01005773 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005774 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005775 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005776
Willy Tarreau86034312006-12-29 00:10:33 +01005777 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005778 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005779 err_code |= ERR_ALERT | ERR_FATAL;
5780 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005781 }
5782 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005783 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5784 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005785 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005786 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5787 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005788 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005789 err_code |= ERR_ALERT | ERR_FATAL;
5790 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005791 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005792 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5793 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005794 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5795 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005796 err_code |= ERR_ALERT | ERR_FATAL;
5797 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005798 }
5799 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005800 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5801 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005802 }
5803 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005804 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005805 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005806 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005807
Willy Tarreaubaaee002006-06-26 02:48:02 +02005808 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005809 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005810 err_code |= ERR_ALERT | ERR_FATAL;
5811 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005812 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005813 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005814 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005815
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005816 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005817 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005818 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005819 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005820 goto out;
5821 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005822
5823 proto = protocol_by_family(sk->ss_family);
5824 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005825 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5826 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005827 err_code |= ERR_ALERT | ERR_FATAL;
5828 goto out;
5829 }
5830
5831 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005832 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5833 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005834 err_code |= ERR_ALERT | ERR_FATAL;
5835 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005836 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005837
5838 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005839 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5840 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005841 err_code |= ERR_ALERT | ERR_FATAL;
5842 goto out;
5843 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005844
William Lallemanddf1425a2015-04-28 20:17:49 +02005845 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5846 goto out;
5847
Willy Tarreaud5191e72010-02-09 20:50:45 +01005848 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005849 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005850 }
5851 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005852 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005853 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005854
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005855 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005856 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005857 err_code |= ERR_ALERT | ERR_FATAL;
5858 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005859 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005860 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005861 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005862 /**
5863 * The syntax for hash-type config element is
5864 * hash-type {map-based|consistent} [[<algo>] avalanche]
5865 *
5866 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5867 */
5868 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005869
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005870 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5871 err_code |= ERR_WARN;
5872
5873 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005874 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
5875 }
5876 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005877 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
5878 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005879 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005880 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 -05005881 err_code |= ERR_ALERT | ERR_FATAL;
5882 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01005883 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005884 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005885 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005886 err_code |= ERR_ALERT | ERR_FATAL;
5887 goto out;
5888 }
Bhaskar98634f02013-10-29 23:30:51 -04005889
5890 /* set the hash function to use */
5891 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005892 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04005893 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005894
5895 /* if consistent with no argument, then avalanche modifier is also applied */
5896 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
5897 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04005898 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005899 /* set the hash function */
5900 if (!strcmp(args[2], "sdbm")) {
5901 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
5902 }
5903 else if (!strcmp(args[2], "djb2")) {
5904 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01005905 }
5906 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01005907 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005908 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01005909 else if (!strcmp(args[2], "crc32")) {
5910 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
5911 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005912 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005913 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 -05005914 err_code |= ERR_ALERT | ERR_FATAL;
5915 goto out;
5916 }
5917
5918 /* set the hash modifier */
5919 if (!strcmp(args[3], "avalanche")) {
5920 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
5921 }
5922 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005923 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 -05005924 err_code |= ERR_ALERT | ERR_FATAL;
5925 goto out;
5926 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01005927 }
William Lallemanda73203e2012-03-12 12:48:57 +01005928 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04005929 else if (strcmp(args[0], "hash-balance-factor") == 0) {
5930 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005931 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04005932 err_code |= ERR_ALERT | ERR_FATAL;
5933 goto out;
5934 }
5935 curproxy->lbprm.chash.balance_factor = atol(args[1]);
5936 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005937 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 -04005938 err_code |= ERR_ALERT | ERR_FATAL;
5939 goto out;
5940 }
5941 }
William Lallemanda73203e2012-03-12 12:48:57 +01005942 else if (strcmp(args[0], "unique-id-format") == 0) {
5943 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005944 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01005945 err_code |= ERR_ALERT | ERR_FATAL;
5946 goto out;
5947 }
William Lallemand3203ff42012-11-11 17:30:56 +01005948 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005949 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 +01005950 err_code |= ERR_ALERT | ERR_FATAL;
5951 goto out;
5952 }
Willy Tarreau62a61232013-04-12 18:13:46 +02005953 free(curproxy->conf.uniqueid_format_string);
5954 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02005955
Willy Tarreau62a61232013-04-12 18:13:46 +02005956 free(curproxy->conf.uif_file);
5957 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
5958 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01005959 }
William Lallemanda73203e2012-03-12 12:48:57 +01005960
5961 else if (strcmp(args[0], "unique-id-header") == 0) {
5962 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005963 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01005964 err_code |= ERR_ALERT | ERR_FATAL;
5965 goto out;
5966 }
5967 free(curproxy->header_unique_id);
5968 curproxy->header_unique_id = strdup(args[1]);
5969 }
5970
William Lallemand723b73a2012-02-08 16:37:49 +01005971 else if (strcmp(args[0], "log-format") == 0) {
5972 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005973 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01005974 err_code |= ERR_ALERT | ERR_FATAL;
5975 goto out;
5976 }
William Lallemand3203ff42012-11-11 17:30:56 +01005977 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005978 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 +01005979 err_code |= ERR_ALERT | ERR_FATAL;
5980 goto out;
5981 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02005982 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
5983 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02005984
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02005985 if (curproxy->conf.logformat_string == default_http_log_format)
5986 oldlogformat = "option httplog";
5987 else if (curproxy->conf.logformat_string == default_tcp_log_format)
5988 oldlogformat = "option tcplog";
5989 else if (curproxy->conf.logformat_string == clf_http_log_format)
5990 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01005991 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
5992 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02005993 }
Willy Tarreau62a61232013-04-12 18:13:46 +02005994 if (curproxy->conf.logformat_string != default_http_log_format &&
5995 curproxy->conf.logformat_string != default_tcp_log_format &&
5996 curproxy->conf.logformat_string != clf_http_log_format)
5997 free(curproxy->conf.logformat_string);
5998 curproxy->conf.logformat_string = strdup(args[1]);
5999
6000 free(curproxy->conf.lfs_file);
6001 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6002 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006003
6004 /* get a chance to improve log-format error reporting by
6005 * reporting the correct line-number when possible.
6006 */
6007 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006008 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6009 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006010 err_code |= ERR_WARN;
6011 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006012 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006013 else if (!strcmp(args[0], "log-format-sd")) {
6014 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006015 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006016 err_code |= ERR_ALERT | ERR_FATAL;
6017 goto out;
6018 }
6019 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006020 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 +02006021 err_code |= ERR_ALERT | ERR_FATAL;
6022 goto out;
6023 }
6024
6025 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6026 free(curproxy->conf.logformat_sd_string);
6027 curproxy->conf.logformat_sd_string = strdup(args[1]);
6028
6029 free(curproxy->conf.lfsd_file);
6030 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6031 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6032
6033 /* get a chance to improve log-format-sd error reporting by
6034 * reporting the correct line-number when possible.
6035 */
6036 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006037 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6038 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006039 err_code |= ERR_WARN;
6040 }
6041 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006042 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6043 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006044 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 +01006045 err_code |= ERR_ALERT | ERR_FATAL;
6046 goto out;
6047 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006048 chunk_destroy(&curproxy->log_tag);
6049 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006050 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006051 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6052 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6053 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006054 err_code |= ERR_ALERT | ERR_FATAL;
6055 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006056 }
6057 }
6058 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006059 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006060 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006061 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006062 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006063
Willy Tarreau977b8e42006-12-29 14:19:17 +01006064 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006065 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006066
Willy Tarreaubaaee002006-06-26 02:48:02 +02006067 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006068 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6069 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006070 err_code |= ERR_ALERT | ERR_FATAL;
6071 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006072 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006073
6074 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006075 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6076 free(curproxy->conn_src.iface_name);
6077 curproxy->conn_src.iface_name = NULL;
6078 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006079
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006080 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006081 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006082 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6083 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006084 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006085 goto out;
6086 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006087
6088 proto = protocol_by_family(sk->ss_family);
6089 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006090 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6091 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006092 err_code |= ERR_ALERT | ERR_FATAL;
6093 goto out;
6094 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006095
6096 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006097 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6098 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006099 err_code |= ERR_ALERT | ERR_FATAL;
6100 goto out;
6101 }
6102
Willy Tarreauef9a3602012-12-08 22:29:20 +01006103 curproxy->conn_src.source_addr = *sk;
6104 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006105
6106 cur_arg = 2;
6107 while (*(args[cur_arg])) {
6108 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006109#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006110 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006111 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6112 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006113 err_code |= ERR_ALERT | ERR_FATAL;
6114 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006115 }
6116
6117 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006118 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6119 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006120 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006121 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6122 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006123 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6124 char *name, *end;
6125
6126 name = args[cur_arg+1] + 7;
6127 while (isspace(*name))
6128 name++;
6129
6130 end = name;
6131 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6132 end++;
6133
Willy Tarreauef9a3602012-12-08 22:29:20 +01006134 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6135 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6136 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6137 curproxy->conn_src.bind_hdr_len = end - name;
6138 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6139 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6140 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006141
6142 /* now look for an occurrence number */
6143 while (isspace(*end))
6144 end++;
6145 if (*end == ',') {
6146 end++;
6147 name = end;
6148 if (*end == '-')
6149 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006150 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006151 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006152 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006153 }
6154
Willy Tarreauef9a3602012-12-08 22:29:20 +01006155 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006156 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6157 " occurrences values smaller than %d.\n",
6158 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006159 err_code |= ERR_ALERT | ERR_FATAL;
6160 goto out;
6161 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006162 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006163 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006164
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006165 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006166 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006167 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6168 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006169 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006170 goto out;
6171 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006172
6173 proto = protocol_by_family(sk->ss_family);
6174 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006175 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6176 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006177 err_code |= ERR_ALERT | ERR_FATAL;
6178 goto out;
6179 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006180
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006181 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006182 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6183 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006184 err_code |= ERR_ALERT | ERR_FATAL;
6185 goto out;
6186 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006187 curproxy->conn_src.tproxy_addr = *sk;
6188 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006189 }
6190 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006191#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006192 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6193 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006194 err_code |= ERR_ALERT | ERR_FATAL;
6195 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006196#endif
6197 cur_arg += 2;
6198 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006199 }
6200
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006201 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6202#ifdef SO_BINDTODEVICE
6203 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006204 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6205 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006206 err_code |= ERR_ALERT | ERR_FATAL;
6207 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006208 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006209 free(curproxy->conn_src.iface_name);
6210 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6211 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006212 global.last_checks |= LSTCHK_NETADM;
6213#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006214 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6215 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006216 err_code |= ERR_ALERT | ERR_FATAL;
6217 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006218#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006219 cur_arg += 2;
6220 continue;
6221 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006222 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6223 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006224 err_code |= ERR_ALERT | ERR_FATAL;
6225 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006226 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006227 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006228 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006229 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6230 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006231 err_code |= ERR_ALERT | ERR_FATAL;
6232 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006233 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006234 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006235 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006236 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6237 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006238 err_code |= ERR_ALERT | ERR_FATAL;
6239 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006240 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006241
6242 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006243 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006244 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006245 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006246 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006247 }
6248 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006249 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006250 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006251 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006252 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006253 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006254 }
6255 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006256 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006257 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006258 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006259 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006260 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006261 }
6262 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006263 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006264 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006265 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006266 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006267 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006268 }
6269 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006270 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006271 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006272 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006273 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006274 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006275 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006276 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006277 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006278 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006279 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006280 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006281 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006282 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006283 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006284 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006285 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6286 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006287 err_code |= ERR_ALERT | ERR_FATAL;
6288 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006289 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006290
6291 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006292 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006293 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006294 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006295 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006296 }
6297 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006298 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006299 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006300 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006301 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006302 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006303 }
6304 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006305 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006306 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006307 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006308 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006309 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006310 }
6311 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006312 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006313 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006314 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006315 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006316 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006317 }
6318 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006319 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006320 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006321 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006322 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006323 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006324 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006325 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006326 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006327 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006328 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006329 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006330 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006331 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006332 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006333 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006334
Willy Tarreaubaaee002006-06-26 02:48:02 +02006335 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006336 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006337 err_code |= ERR_ALERT | ERR_FATAL;
6338 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006339 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006340 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006341 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006342
Willy Tarreaubaaee002006-06-26 02:48:02 +02006343 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006344 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006345 err_code |= ERR_ALERT | ERR_FATAL;
6346 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006347 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006348
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006349 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006350 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006351 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6352 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006353 err_code |= ERR_ALERT | ERR_FATAL;
6354 goto out;
6355 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006356 err_code |= warnif_cond_conflicts(cond,
6357 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6358 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006359 }
6360 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006361 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6362 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006363 err_code |= ERR_ALERT | ERR_FATAL;
6364 goto out;
6365 }
6366
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006367 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006368 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006369 wl->s = strdup(args[1]);
6370 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006371 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006372 }
6373 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006374 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006375 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6376 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006377 err_code |= ERR_ALERT | ERR_FATAL;
6378 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006379 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006380
Willy Tarreauade5ec42010-01-28 19:33:49 +01006381 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006382 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006383 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006384 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006385 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006386 }
6387 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006388 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006389 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006390 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006391 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006392 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006393 }
6394 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006395 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006396 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006397 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006398 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006399 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006400 }
6401 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006402 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006403 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6404 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006405 err_code |= ERR_ALERT | ERR_FATAL;
6406 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006407 }
6408
Willy Tarreauade5ec42010-01-28 19:33:49 +01006409 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006410 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006411 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006412 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006413 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006414 }
6415 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006416 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006417 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006418 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006419 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006420 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006421 }
6422 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006423 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006424 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006425 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006426 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006427 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006428 }
6429 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006430 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006431
Willy Tarreaubaaee002006-06-26 02:48:02 +02006432 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006433 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006434 err_code |= ERR_ALERT | ERR_FATAL;
6435 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006436 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006437 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006438 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006439
Willy Tarreaubaaee002006-06-26 02:48:02 +02006440 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006441 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006442 err_code |= ERR_ALERT | ERR_FATAL;
6443 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006444 }
6445
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006446 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006447 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006448 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6449 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006450 err_code |= ERR_ALERT | ERR_FATAL;
6451 goto out;
6452 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006453 err_code |= warnif_cond_conflicts(cond,
6454 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6455 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006456 }
6457 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006458 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6459 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006460 err_code |= ERR_ALERT | ERR_FATAL;
6461 goto out;
6462 }
6463
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006464 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006465 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006466 wl->s = strdup(args[1]);
6467 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006468 }
6469 else if (!strcmp(args[0], "errorloc") ||
6470 !strcmp(args[0], "errorloc302") ||
6471 !strcmp(args[0], "errorloc303")) { /* error location */
6472 int errnum, errlen;
6473 char *err;
6474
Willy Tarreau977b8e42006-12-29 14:19:17 +01006475 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006476 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006477
Willy Tarreaubaaee002006-06-26 02:48:02 +02006478 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006479 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 +02006480 err_code |= ERR_ALERT | ERR_FATAL;
6481 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006482 }
6483
6484 errnum = atol(args[1]);
6485 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006486 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6487 err = malloc(errlen);
6488 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006489 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006490 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6491 err = malloc(errlen);
6492 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006493 }
6494
Willy Tarreau0f772532006-12-23 20:51:41 +01006495 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6496 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006497 chunk_destroy(&curproxy->errmsg[rc]);
6498 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006499 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006500 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006501 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006502
6503 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006504 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6505 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006506 free(err);
6507 }
6508 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006509 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6510 int errnum, errlen, fd;
6511 char *err;
6512 struct stat stat;
6513
6514 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006515 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006516
6517 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006518 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 +02006519 err_code |= ERR_ALERT | ERR_FATAL;
6520 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006521 }
6522
6523 fd = open(args[2], O_RDONLY);
6524 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006525 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6526 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006527 if (fd >= 0)
6528 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006529 err_code |= ERR_ALERT | ERR_FATAL;
6530 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006531 }
6532
Willy Tarreau27a674e2009-08-17 07:23:33 +02006533 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006534 errlen = stat.st_size;
6535 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006536 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6537 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006538 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006539 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006540 }
6541
6542 err = malloc(errlen); /* malloc() must succeed during parsing */
6543 errnum = read(fd, err, errlen);
6544 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006545 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6546 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006547 close(fd);
6548 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006549 err_code |= ERR_ALERT | ERR_FATAL;
6550 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006551 }
6552 close(fd);
6553
6554 errnum = atol(args[1]);
6555 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6556 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006557 chunk_destroy(&curproxy->errmsg[rc]);
6558 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006559 break;
6560 }
6561 }
6562
6563 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006564 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6565 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006566 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006567 free(err);
6568 }
6569 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006570 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006571 struct cfg_kw_list *kwl;
6572 int index;
6573
6574 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6575 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6576 if (kwl->kw[index].section != CFG_LISTEN)
6577 continue;
6578 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6579 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006580 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006581 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006582 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006583 err_code |= ERR_ALERT | ERR_FATAL;
6584 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006585 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006586 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006587 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006588 err_code |= ERR_WARN;
6589 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006590 }
Willy Tarreau93893792009-07-23 13:19:11 +02006591 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006592 }
6593 }
6594 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006595
Christopher Faulet767a84b2017-11-24 16:50:31 +01006596 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006597 err_code |= ERR_ALERT | ERR_FATAL;
6598 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006599 }
Willy Tarreau93893792009-07-23 13:19:11 +02006600 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006601 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006602 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006603}
6604
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006605int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006606cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6607{
6608#ifdef CONFIG_HAP_NS
6609 const char *err;
6610 const char *item = args[0];
6611
6612 if (!strcmp(item, "namespace_list")) {
6613 return 0;
6614 }
6615 else if (!strcmp(item, "namespace")) {
6616 size_t idx = 1;
6617 const char *current;
6618 while (*(current = args[idx++])) {
6619 err = invalid_char(current);
6620 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006621 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6622 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006623 return ERR_ALERT | ERR_FATAL;
6624 }
6625
6626 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006627 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6628 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006629 return ERR_ALERT | ERR_FATAL;
6630 }
6631 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006632 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6633 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006634 return ERR_ALERT | ERR_FATAL;
6635 }
6636 }
6637 }
6638
6639 return 0;
6640#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006641 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6642 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006643 return ERR_ALERT | ERR_FATAL;
6644#endif
6645}
6646
6647int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006648cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6649{
6650
6651 int err_code = 0;
6652 const char *err;
6653
6654 if (!strcmp(args[0], "userlist")) { /* new userlist */
6655 struct userlist *newul;
6656
6657 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006658 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6659 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006660 err_code |= ERR_ALERT | ERR_FATAL;
6661 goto out;
6662 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006663 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6664 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006665
6666 err = invalid_char(args[1]);
6667 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006668 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6669 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006670 err_code |= ERR_ALERT | ERR_FATAL;
6671 goto out;
6672 }
6673
6674 for (newul = userlist; newul; newul = newul->next)
6675 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006676 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6677 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006678 err_code |= ERR_WARN;
6679 goto out;
6680 }
6681
Vincent Bernat02779b62016-04-03 13:48:43 +02006682 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006683 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006684 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006685 err_code |= ERR_ALERT | ERR_ABORT;
6686 goto out;
6687 }
6688
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006689 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006690 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006691 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006692 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006693 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006694 goto out;
6695 }
6696
6697 newul->next = userlist;
6698 userlist = newul;
6699
6700 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006701 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006702 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006703 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006704
6705 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006706 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6707 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006708 err_code |= ERR_ALERT | ERR_FATAL;
6709 goto out;
6710 }
6711
6712 err = invalid_char(args[1]);
6713 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006714 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6715 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006716 err_code |= ERR_ALERT | ERR_FATAL;
6717 goto out;
6718 }
6719
William Lallemand4ac9f542015-05-28 18:03:51 +02006720 if (!userlist)
6721 goto out;
6722
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006723 for (ag = userlist->groups; ag; ag = ag->next)
6724 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006725 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6726 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006727 err_code |= ERR_ALERT;
6728 goto out;
6729 }
6730
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006731 ag = calloc(1, sizeof(*ag));
6732 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006733 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006734 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006735 goto out;
6736 }
6737
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006738 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006739 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006740 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006741 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006742 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006743 goto out;
6744 }
6745
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006746 cur_arg = 2;
6747
6748 while (*args[cur_arg]) {
6749 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006750 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006751 cur_arg += 2;
6752 continue;
6753 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006754 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6755 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006756 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006757 free(ag->groupusers);
6758 free(ag->name);
6759 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006760 goto out;
6761 }
6762 }
6763
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006764 ag->next = userlist->groups;
6765 userlist->groups = ag;
6766
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006767 } else if (!strcmp(args[0], "user")) { /* new user */
6768 struct auth_users *newuser;
6769 int cur_arg;
6770
6771 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006772 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6773 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006774 err_code |= ERR_ALERT | ERR_FATAL;
6775 goto out;
6776 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006777 if (!userlist)
6778 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006779
6780 for (newuser = userlist->users; newuser; newuser = newuser->next)
6781 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006782 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6783 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006784 err_code |= ERR_ALERT;
6785 goto out;
6786 }
6787
Vincent Bernat02779b62016-04-03 13:48:43 +02006788 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006789 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006790 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006791 err_code |= ERR_ALERT | ERR_ABORT;
6792 goto out;
6793 }
6794
6795 newuser->user = strdup(args[1]);
6796
6797 newuser->next = userlist->users;
6798 userlist->users = newuser;
6799
6800 cur_arg = 2;
6801
6802 while (*args[cur_arg]) {
6803 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006804#ifdef CONFIG_HAP_CRYPT
6805 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006806 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6807 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006808 err_code |= ERR_ALERT | ERR_FATAL;
6809 goto out;
6810 }
6811#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006812 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6813 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006814 err_code |= ERR_ALERT;
6815#endif
6816 newuser->pass = strdup(args[cur_arg + 1]);
6817 cur_arg += 2;
6818 continue;
6819 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6820 newuser->pass = strdup(args[cur_arg + 1]);
6821 newuser->flags |= AU_O_INSECURE;
6822 cur_arg += 2;
6823 continue;
6824 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006825 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006826 cur_arg += 2;
6827 continue;
6828 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006829 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6830 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006831 err_code |= ERR_ALERT | ERR_FATAL;
6832 goto out;
6833 }
6834 }
6835 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006836 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 +01006837 err_code |= ERR_ALERT | ERR_FATAL;
6838 }
6839
6840out:
6841 return err_code;
6842}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006843
Christopher Faulet79bdef32016-11-04 22:36:15 +01006844int
6845cfg_parse_scope(const char *file, int linenum, char *line)
6846{
6847 char *beg, *end, *scope = NULL;
6848 int err_code = 0;
6849 const char *err;
6850
6851 beg = line + 1;
6852 end = strchr(beg, ']');
6853
6854 /* Detect end of scope declaration */
6855 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006856 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
6857 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006858 err_code |= ERR_ALERT | ERR_FATAL;
6859 goto out;
6860 }
6861
6862 /* Get scope name and check its validity */
6863 scope = my_strndup(beg, end-beg);
6864 err = invalid_char(scope);
6865 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006866 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
6867 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006868 err_code |= ERR_ALERT | ERR_ABORT;
6869 goto out;
6870 }
6871
6872 /* Be sure to have a scope declaration alone on its line */
6873 line = end+1;
6874 while (isspace((unsigned char)*line))
6875 line++;
6876 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006877 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
6878 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006879 err_code |= ERR_ALERT | ERR_ABORT;
6880 goto out;
6881 }
6882
6883 /* We have a valid scope declaration, save it */
6884 free(cfg_scope);
6885 cfg_scope = scope;
6886 scope = NULL;
6887
6888 out:
6889 free(scope);
6890 return err_code;
6891}
6892
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01006893int
6894cfg_parse_track_sc_num(unsigned int *track_sc_num,
6895 const char *arg, const char *end, char **errmsg)
6896{
6897 const char *p;
6898 unsigned int num;
6899
6900 p = arg;
6901 num = read_uint64(&arg, end);
6902
6903 if (arg != end) {
6904 memprintf(errmsg, "Wrong track-sc number '%s'", p);
6905 return -1;
6906 }
6907
6908 if (num >= MAX_SESS_STKCTR) {
6909 memprintf(errmsg, "%u track-sc number exceeding "
6910 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
6911 return -1;
6912 }
6913
6914 *track_sc_num = num;
6915 return 0;
6916}
6917
Willy Tarreaubaaee002006-06-26 02:48:02 +02006918/*
6919 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02006920 * Returns the error code, 0 if OK, or any combination of :
6921 * - ERR_ABORT: must abort ASAP
6922 * - ERR_FATAL: we can continue parsing but not start the service
6923 * - ERR_WARN: a warning has been emitted
6924 * - ERR_ALERT: an alert has been emitted
6925 * Only the two first ones can stop processing, the two others are just
6926 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02006927 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02006928int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02006929{
William Lallemand64e84512015-05-12 14:25:37 +02006930 char *thisline;
6931 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006932 FILE *f;
6933 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02006934 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02006935 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01006936 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02006937 int readbytes = 0;
6938
6939 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006940 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02006941 return -1;
6942 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01006943
David Carlier97880bb2016-04-08 10:35:26 +01006944 if ((f=fopen(file,"r")) == NULL) {
6945 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006946 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01006947 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006948
William Lallemandb2f07452015-05-12 14:27:13 +02006949next_line:
William Lallemand64e84512015-05-12 14:25:37 +02006950 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02006951 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006952 char *end;
6953 char *args[MAX_LINE_ARGS + 1];
6954 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02006955 int dquote = 0; /* double quote */
6956 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006957
Willy Tarreaubaaee002006-06-26 02:48:02 +02006958 linenum++;
6959
6960 end = line + strlen(line);
6961
William Lallemand64e84512015-05-12 14:25:37 +02006962 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006963 /* Check if we reached the limit and the last char is not \n.
6964 * Watch out for the last line without the terminating '\n'!
6965 */
William Lallemand64e84512015-05-12 14:25:37 +02006966 char *newline;
6967 int newlinesize = linesize * 2;
6968
6969 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
6970 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006971 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
6972 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02006973 err_code |= ERR_ALERT | ERR_FATAL;
6974 continue;
6975 }
6976
6977 readbytes = linesize - 1;
6978 linesize = newlinesize;
6979 thisline = newline;
6980 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006981 }
6982
William Lallemand64e84512015-05-12 14:25:37 +02006983 readbytes = 0;
6984
Willy Tarreaubaaee002006-06-26 02:48:02 +02006985 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02006986 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02006987 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02006988
Christopher Faulet79bdef32016-11-04 22:36:15 +01006989
6990 if (*line == '[') {/* This is the begining if a scope */
6991 err_code |= cfg_parse_scope(file, linenum, line);
6992 goto next_line;
6993 }
6994
Willy Tarreaubaaee002006-06-26 02:48:02 +02006995 arg = 0;
6996 args[arg] = line;
6997
6998 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02006999 if (*line == '"' && !squote) { /* double quote outside single quotes */
7000 if (dquote)
7001 dquote = 0;
7002 else
7003 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007004 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007005 end--;
7006 }
7007 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7008 if (squote)
7009 squote = 0;
7010 else
7011 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007012 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007013 end--;
7014 }
7015 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007016 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7017 * C equivalent value. Other combinations left unchanged (eg: \1).
7018 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007019 int skip = 0;
7020 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7021 *line = line[1];
7022 skip = 1;
7023 }
7024 else if (line[1] == 'r') {
7025 *line = '\r';
7026 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007027 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007028 else if (line[1] == 'n') {
7029 *line = '\n';
7030 skip = 1;
7031 }
7032 else if (line[1] == 't') {
7033 *line = '\t';
7034 skip = 1;
7035 }
7036 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007037 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007038 unsigned char hex1, hex2;
7039 hex1 = toupper(line[2]) - '0';
7040 hex2 = toupper(line[3]) - '0';
7041 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7042 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7043 *line = (hex1<<4) + hex2;
7044 skip = 3;
7045 }
7046 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007047 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007048 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007049 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007050 } else if (line[1] == '"') {
7051 *line = '"';
7052 skip = 1;
7053 } else if (line[1] == '\'') {
7054 *line = '\'';
7055 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007056 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7057 *line = '$';
7058 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007059 }
7060 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007061 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007062 end -= skip;
7063 }
7064 line++;
7065 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007066 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007067 /* end of string, end of loop */
7068 *line = 0;
7069 break;
7070 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007071 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007072 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007073 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007074 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007075 line++;
7076 args[++arg] = line;
7077 }
William Lallemandb2f07452015-05-12 14:27:13 +02007078 else if (dquote && *line == '$') {
7079 /* environment variables are evaluated inside double quotes */
7080 char *var_beg;
7081 char *var_end;
7082 char save_char;
7083 char *value;
7084 int val_len;
7085 int newlinesize;
7086 int braces = 0;
7087
7088 var_beg = line + 1;
7089 var_end = var_beg;
7090
7091 if (*var_beg == '{') {
7092 var_beg++;
7093 var_end++;
7094 braces = 1;
7095 }
7096
7097 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007098 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 +02007099 err_code |= ERR_ALERT | ERR_FATAL;
7100 goto next_line; /* skip current line */
7101 }
7102
7103 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7104 var_end++;
7105
7106 save_char = *var_end;
7107 *var_end = '\0';
7108 value = getenv(var_beg);
7109 *var_end = save_char;
7110 val_len = value ? strlen(value) : 0;
7111
7112 if (braces) {
7113 if (*var_end == '}') {
7114 var_end++;
7115 braces = 0;
7116 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007117 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007118 err_code |= ERR_ALERT | ERR_FATAL;
7119 goto next_line; /* skip current line */
7120 }
7121 }
7122
7123 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7124
7125 /* if not enough space in thisline */
7126 if (newlinesize > linesize) {
7127 char *newline;
7128
7129 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7130 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007131 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007132 err_code |= ERR_ALERT | ERR_FATAL;
7133 goto next_line; /* slip current line */
7134 }
7135 /* recompute pointers if realloc returns a new pointer */
7136 if (newline != thisline) {
7137 int i;
7138 int diff;
7139
7140 for (i = 0; i <= arg; i++) {
7141 diff = args[i] - thisline;
7142 args[i] = newline + diff;
7143 }
7144
7145 diff = var_end - thisline;
7146 var_end = newline + diff;
7147 diff = end - thisline;
7148 end = newline + diff;
7149 diff = line - thisline;
7150 line = newline + diff;
7151 thisline = newline;
7152 }
7153 linesize = newlinesize;
7154 }
7155
7156 /* insert value inside the line */
7157 memmove(line + val_len, var_end, end - var_end + 1);
7158 memcpy(line, value, val_len);
7159 end += val_len - (var_end - line);
7160 line += val_len;
7161 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007162 else {
7163 line++;
7164 }
7165 }
William Lallemandb2f07452015-05-12 14:27:13 +02007166
William Lallemandf9873ba2015-05-05 17:37:14 +02007167 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007168 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007169 err_code |= ERR_ALERT | ERR_FATAL;
7170 }
7171
7172 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007173 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007174 err_code |= ERR_ALERT | ERR_FATAL;
7175 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007176
7177 /* empty line */
7178 if (!**args)
7179 continue;
7180
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007181 if (*line) {
7182 /* we had to stop due to too many args.
7183 * Let's terminate the string, print the offending part then cut the
7184 * last arg.
7185 */
7186 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7187 line++;
7188 *line = '\0';
7189
Christopher Faulet767a84b2017-11-24 16:50:31 +01007190 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7191 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007192 err_code |= ERR_ALERT | ERR_FATAL;
7193 args[arg] = line;
7194 }
7195
Willy Tarreau540abe42007-05-02 20:50:16 +02007196 /* zero out remaining args and ensure that at least one entry
7197 * is zeroed out.
7198 */
7199 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007200 args[arg] = line;
7201 }
7202
Willy Tarreau3842f002009-06-14 11:39:52 +02007203 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007204 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007205 char *tmp;
7206
Willy Tarreau3842f002009-06-14 11:39:52 +02007207 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007208 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007209 for (arg=0; *args[arg+1]; arg++)
7210 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007211 *tmp = '\0'; // fix the next arg to \0
7212 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007213 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007214 else if (!strcmp(args[0], "default")) {
7215 kwm = KWM_DEF;
7216 for (arg=0; *args[arg+1]; arg++)
7217 args[arg] = args[arg+1]; // shift args after inversion
7218 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007219
William Lallemand0f99e342011-10-12 17:50:54 +02007220 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7221 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007222 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007223 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007224 }
7225
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007226 /* detect section start */
7227 list_for_each_entry(ics, &sections, list) {
7228 if (strcmp(args[0], ics->section_name) == 0) {
7229 cursection = ics->section_name;
7230 cs = ics;
7231 break;
7232 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007233 }
7234
William Lallemandd2ff56d2017-10-16 11:06:50 +02007235 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007236 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007237 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007238 } else {
7239 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007240
William Lallemandd2ff56d2017-10-16 11:06:50 +02007241 if (pcs != cs && pcs && pcs->post_section_parser) {
7242 err_code |= pcs->post_section_parser();
7243 if (err_code & ERR_ABORT)
7244 goto err;
7245 }
7246
7247 err_code |= cs->section_parser(file, linenum, args, kwm);
7248 if (err_code & ERR_ABORT)
7249 goto err;
7250 }
7251 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007252 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007253
7254 if (pcs == cs && pcs && pcs->post_section_parser)
7255 err_code |= pcs->post_section_parser();
7256
7257err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007258 free(cfg_scope);
7259 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007260 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007261 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007262 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007263 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007264}
7265
Willy Tarreau64ab6072014-09-16 12:17:36 +02007266/* This function propagates processes from frontend <from> to backend <to> so
7267 * that it is always guaranteed that a backend pointed to by a frontend is
7268 * bound to all of its processes. After that, if the target is a "listen"
7269 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007270 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007271 * checked first to ensure that <to> is already bound to all processes of
7272 * <from>, there is no risk of looping and we ensure to follow the shortest
7273 * path to the destination.
7274 *
7275 * It is possible to set <to> to NULL for the first call so that the function
7276 * takes care of visiting the initial frontend in <from>.
7277 *
7278 * It is important to note that the function relies on the fact that all names
7279 * have already been resolved.
7280 */
7281void propagate_processes(struct proxy *from, struct proxy *to)
7282{
7283 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007284
7285 if (to) {
7286 /* check whether we need to go down */
7287 if (from->bind_proc &&
7288 (from->bind_proc & to->bind_proc) == from->bind_proc)
7289 return;
7290
7291 if (!from->bind_proc && !to->bind_proc)
7292 return;
7293
7294 to->bind_proc = from->bind_proc ?
7295 (to->bind_proc | from->bind_proc) : 0;
7296
7297 /* now propagate down */
7298 from = to;
7299 }
7300
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007301 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007302 return;
7303
Willy Tarreauf6b70012014-12-18 14:00:43 +01007304 if (from->state == PR_STSTOPPED)
7305 return;
7306
Willy Tarreau64ab6072014-09-16 12:17:36 +02007307 /* default_backend */
7308 if (from->defbe.be)
7309 propagate_processes(from, from->defbe.be);
7310
7311 /* use_backend */
7312 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007313 if (rule->dynamic)
7314 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007315 to = rule->be.backend;
7316 propagate_processes(from, to);
7317 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007318}
7319
Willy Tarreaubb925012009-07-23 13:36:36 +02007320/*
7321 * Returns the error code, 0 if OK, or any combination of :
7322 * - ERR_ABORT: must abort ASAP
7323 * - ERR_FATAL: we can continue parsing but not start the service
7324 * - ERR_WARN: a warning has been emitted
7325 * - ERR_ALERT: an alert has been emitted
7326 * Only the two first ones can stop processing, the two others are just
7327 * indicators.
7328 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007329int check_config_validity()
7330{
7331 int cfgerr = 0;
7332 struct proxy *curproxy = NULL;
7333 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007334 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007335 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007336 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007337 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007338 struct cfg_postparser *postparser;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007339
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007340 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007341 /*
7342 * Now, check for the integrity of all that we have collected.
7343 */
7344
7345 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007346 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007347
Willy Tarreau193b8c62012-11-22 00:17:38 +01007348 if (!global.tune.max_http_hdr)
7349 global.tune.max_http_hdr = MAX_HTTP_HDR;
7350
7351 if (!global.tune.cookie_len)
7352 global.tune.cookie_len = CAPTURE_LEN;
7353
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007354 if (!global.tune.requri_len)
7355 global.tune.requri_len = REQURI_LEN;
7356
Willy Tarreaubafbe012017-11-24 17:34:44 +01007357 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007358
Willy Tarreaubafbe012017-11-24 17:34:44 +01007359 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007360
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007361 /* Post initialisation of the users and groups lists. */
7362 err_code = userlist_postinit();
7363 if (err_code != ERR_NONE)
7364 goto out;
7365
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007366 /* first, we will invert the proxy list order */
7367 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007368 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007369 struct proxy *next;
7370
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007371 next = proxies_list->next;
7372 proxies_list->next = curproxy;
7373 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007374 if (!next)
7375 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007376 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007377 }
7378
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007379 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007380 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007381 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007382 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007383 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007384 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007385 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007386 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007387
Willy Tarreau050536d2012-10-04 08:47:34 +02007388 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007389 /* proxy ID not set, use automatic numbering with first
7390 * spare entry starting with next_pxid.
7391 */
7392 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7393 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7394 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007395 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007396 next_pxid++;
7397
Willy Tarreau55ea7572007-06-17 19:56:27 +02007398
Willy Tarreaubaaee002006-06-26 02:48:02 +02007399 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007400 /* ensure we don't keep listeners uselessly bound */
7401 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007402 free((void *)curproxy->table.peers.name);
7403 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007404 continue;
7405 }
7406
Willy Tarreau102df612014-05-07 23:56:38 +02007407 /* Check multi-process mode compatibility for the current proxy */
7408
7409 if (curproxy->bind_proc) {
7410 /* an explicit bind-process was specified, let's check how many
7411 * processes remain.
7412 */
David Carliere6c39412015-07-02 07:00:17 +00007413 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007414
7415 curproxy->bind_proc &= nbits(global.nbproc);
7416 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007417 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 +02007418 curproxy->bind_proc = 1;
7419 }
7420 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007421 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 +02007422 curproxy->bind_proc = 0;
7423 }
7424 }
7425
Willy Tarreau3d209582014-05-09 17:06:11 +02007426 /* check and reduce the bind-proc of each listener */
7427 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7428 unsigned long mask;
7429
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007430 /* HTTP frontends with "h2" as ALPN/NPN will work in
7431 * HTTP/2 and absolutely require buffers 16kB or larger.
7432 */
7433#ifdef USE_OPENSSL
7434 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7435#ifdef OPENSSL_NPN_NEGOTIATED
7436 /* check NPN */
7437 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007438 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",
7439 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007440 cfgerr++;
7441 }
7442#endif
7443#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7444 /* check ALPN */
7445 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007446 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",
7447 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007448 cfgerr++;
7449 }
7450#endif
7451 } /* HTTP && bufsize < 16384 */
7452#endif
7453
Willy Tarreau3d209582014-05-09 17:06:11 +02007454 if (!bind_conf->bind_proc)
7455 continue;
7456
7457 mask = nbits(global.nbproc);
7458 if (curproxy->bind_proc)
7459 mask &= curproxy->bind_proc;
7460 /* mask cannot be null here thanks to the previous checks */
7461
David Carliere6c39412015-07-02 07:00:17 +00007462 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007463 bind_conf->bind_proc &= mask;
7464
7465 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007466 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",
7467 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007468 bind_conf->bind_proc = mask & ~(mask - 1);
7469 }
7470 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007471 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",
7472 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007473 bind_conf->bind_proc = 0;
7474 }
7475 }
7476
Willy Tarreauff01a212009-03-15 13:46:16 +01007477 switch (curproxy->mode) {
7478 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007479 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007480 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007481 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7482 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007483 cfgerr++;
7484 }
7485
7486 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007487 ha_warning("config : servers will be ignored for %s '%s'.\n",
7488 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007489 break;
7490
7491 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007492 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007493 break;
7494
7495 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007496 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007497 break;
7498 }
7499
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007500 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007501 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7502 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007503 err_code |= ERR_WARN;
7504 }
7505
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007506 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007507 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007508 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007509 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7510 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007511 cfgerr++;
7512 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007513#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007514 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007515 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7516 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007517 cfgerr++;
7518 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007519#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007520 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007521 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7522 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007523 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007524 }
7525 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007526 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007527 /* If no LB algo is set in a backend, and we're not in
7528 * transparent mode, dispatch mode nor proxy mode, we
7529 * want to use balance roundrobin by default.
7530 */
7531 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7532 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007533 }
7534 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007535
Willy Tarreau1620ec32011-08-06 17:05:02 +02007536 if (curproxy->options & PR_O_DISPATCH)
7537 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7538 else if (curproxy->options & PR_O_HTTP_PROXY)
7539 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7540 else if (curproxy->options & PR_O_TRANSP)
7541 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007542
Willy Tarreau1620ec32011-08-06 17:05:02 +02007543 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7544 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007545 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7546 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007547 err_code |= ERR_WARN;
7548 curproxy->options &= ~PR_O_DISABLE404;
7549 }
7550 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007551 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7552 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007553 err_code |= ERR_WARN;
7554 curproxy->options &= ~PR_O2_CHK_SNDST;
7555 }
Willy Tarreauef781042010-01-27 11:53:01 +01007556 }
7557
Simon Horman98637e52014-06-20 12:30:16 +09007558 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7559 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007560 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7561 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007562 cfgerr++;
7563 }
7564 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007565 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7566 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007567 cfgerr++;
7568 }
7569 }
7570
Simon Horman64e34162015-02-06 11:11:57 +09007571 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007572 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007573 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7574 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7575 "'email-alert myhostname', or 'email-alert to' "
7576 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7577 "to be present).\n",
7578 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007579 err_code |= ERR_WARN;
7580 free_email_alert(curproxy);
7581 }
7582 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007583 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007584 }
7585
Simon Horman98637e52014-06-20 12:30:16 +09007586 if (curproxy->check_command) {
7587 int clear = 0;
7588 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007589 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7590 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007591 err_code |= ERR_WARN;
7592 clear = 1;
7593 }
7594 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007595 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7596 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007597 cfgerr++;
7598 }
7599 if (clear) {
7600 free(curproxy->check_command);
7601 curproxy->check_command = NULL;
7602 }
7603 }
7604
7605 if (curproxy->check_path) {
7606 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007607 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7608 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007609 err_code |= ERR_WARN;
7610 free(curproxy->check_path);
7611 curproxy->check_path = NULL;
7612 }
7613 }
7614
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007615 /* if a default backend was specified, let's find it */
7616 if (curproxy->defbe.name) {
7617 struct proxy *target;
7618
Willy Tarreauafb39922015-05-26 12:04:09 +02007619 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007620 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007621 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7622 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007623 cfgerr++;
7624 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007625 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7626 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007627 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007628 } else if (target->mode != curproxy->mode &&
7629 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7630
Christopher Faulet767a84b2017-11-24 16:50:31 +01007631 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7632 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7633 curproxy->conf.file, curproxy->conf.line,
7634 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7635 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007636 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007637 } else {
7638 free(curproxy->defbe.name);
7639 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007640 /* Update tot_fe_maxconn for a further fullconn's computation */
7641 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007642 /* Emit a warning if this proxy also has some servers */
7643 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007644 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7645 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007646 err_code |= ERR_WARN;
7647 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007648 }
7649 }
7650
Emeric Brun3f783572017-01-12 11:21:28 +01007651 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7652 /* Case of listen without default backend
7653 * The curproxy will be its own default backend
7654 * so we update tot_fe_maxconn for a further
7655 * fullconn's computation */
7656 curproxy->tot_fe_maxconn += curproxy->maxconn;
7657 }
7658
Willy Tarreau55ea7572007-06-17 19:56:27 +02007659 /* find the target proxy for 'use_backend' rules */
7660 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007661 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007662 struct logformat_node *node;
7663 char *pxname;
7664
7665 /* Try to parse the string as a log format expression. If the result
7666 * of the parsing is only one entry containing a simple string, then
7667 * it's a standard string corresponding to a static rule, thus the
7668 * parsing is cancelled and be.name is restored to be resolved.
7669 */
7670 pxname = rule->be.name;
7671 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007672 curproxy->conf.args.ctx = ARGC_UBK;
7673 curproxy->conf.args.file = rule->file;
7674 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007675 err = NULL;
7676 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007677 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7678 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007679 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007680 cfgerr++;
7681 continue;
7682 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007683 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7684
7685 if (!LIST_ISEMPTY(&rule->be.expr)) {
7686 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7687 rule->dynamic = 1;
7688 free(pxname);
7689 continue;
7690 }
7691 /* simple string: free the expression and fall back to static rule */
7692 free(node->arg);
7693 free(node);
7694 }
7695
7696 rule->dynamic = 0;
7697 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007698
Willy Tarreauafb39922015-05-26 12:04:09 +02007699 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007700 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007701 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7702 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007703 cfgerr++;
7704 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007705 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7706 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007707 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007708 } else if (target->mode != curproxy->mode &&
7709 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7710
Christopher Faulet767a84b2017-11-24 16:50:31 +01007711 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7712 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7713 curproxy->conf.file, curproxy->conf.line,
7714 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7715 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007716 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007717 } else {
7718 free((void *)rule->be.name);
7719 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007720 /* For each target of switching rules, we update
7721 * their tot_fe_maxconn, except if a previous rule point
7722 * on the same backend or on the default backend */
7723 if (rule->be.backend != curproxy->defbe.be) {
7724 struct switching_rule *swrule;
7725
7726 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7727 if (rule == swrule) {
7728 target->tot_fe_maxconn += curproxy->maxconn;
7729 break;
7730 }
7731 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7732 /* there is multiple ref of this backend */
7733 break;
7734 }
7735 }
7736 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007737 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007738 }
7739
Willy Tarreau64ab6072014-09-16 12:17:36 +02007740 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007741 list_for_each_entry(srule, &curproxy->server_rules, list) {
7742 struct server *target = findserver(curproxy, srule->srv.name);
7743
7744 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007745 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7746 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007747 cfgerr++;
7748 continue;
7749 }
7750 free((void *)srule->srv.name);
7751 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007752 }
7753
Emeric Brunb982a3d2010-01-04 15:45:53 +01007754 /* find the target table for 'stick' rules */
7755 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7756 struct proxy *target;
7757
Emeric Brun1d33b292010-01-04 15:47:17 +01007758 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7759 if (mrule->flags & STK_IS_STORE)
7760 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7761
Emeric Brunb982a3d2010-01-04 15:45:53 +01007762 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007763 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007764 else
7765 target = curproxy;
7766
7767 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007768 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7769 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007770 cfgerr++;
7771 }
7772 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007773 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7774 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007775 cfgerr++;
7776 }
Willy Tarreau12785782012-04-27 21:37:17 +02007777 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007778 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7779 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007780 cfgerr++;
7781 }
7782 else {
7783 free((void *)mrule->table.name);
7784 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007785 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007786 }
7787 }
7788
7789 /* find the target table for 'store response' rules */
7790 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7791 struct proxy *target;
7792
Emeric Brun1d33b292010-01-04 15:47:17 +01007793 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7794
Emeric Brunb982a3d2010-01-04 15:45:53 +01007795 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007796 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007797 else
7798 target = curproxy;
7799
7800 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007801 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7802 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007803 cfgerr++;
7804 }
7805 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007806 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7807 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007808 cfgerr++;
7809 }
Willy Tarreau12785782012-04-27 21:37:17 +02007810 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007811 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7812 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007813 cfgerr++;
7814 }
7815 else {
7816 free((void *)mrule->table.name);
7817 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007818 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007819 }
7820 }
7821
Christopher Faulete4e830d2017-09-18 14:51:41 +02007822 /* check validity for 'tcp-request' layer 4 rules */
7823 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
7824 err = NULL;
7825 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007826 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007827 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01007828 cfgerr++;
7829 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02007830 }
7831
Christopher Faulete4e830d2017-09-18 14:51:41 +02007832 /* check validity for 'tcp-request' layer 5 rules */
7833 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
7834 err = NULL;
7835 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007836 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007837 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007838 cfgerr++;
7839 }
7840 }
7841
Christopher Faulete4e830d2017-09-18 14:51:41 +02007842 /* check validity for 'tcp-request' layer 6 rules */
7843 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
7844 err = NULL;
7845 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007846 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007847 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007848 cfgerr++;
7849 }
7850 }
7851
Christopher Faulete4e830d2017-09-18 14:51:41 +02007852 /* check validity for 'http-request' layer 7 rules */
7853 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
7854 err = NULL;
7855 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007856 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007857 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007858 cfgerr++;
7859 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08007860 }
7861
Christopher Faulete4e830d2017-09-18 14:51:41 +02007862 /* check validity for 'http-response' layer 7 rules */
7863 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
7864 err = NULL;
7865 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007866 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007867 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02007868 cfgerr++;
7869 }
Willy Tarreau09448f72014-06-25 18:12:15 +02007870 }
7871
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02007872 /* move any "block" rules at the beginning of the http-request rules */
7873 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
7874 /* insert block_rules into http_req_rules at the beginning */
7875 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
7876 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
7877 curproxy->block_rules.n->p = &curproxy->http_req_rules;
7878 curproxy->http_req_rules.n = curproxy->block_rules.n;
7879 LIST_INIT(&curproxy->block_rules);
7880 }
7881
Emeric Brun32da3c42010-09-23 18:39:19 +02007882 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02007883 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02007884
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02007885 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02007886 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
7887 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01007888 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02007889 break;
7890 }
7891 }
7892
7893 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007894 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
7895 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02007896 free((void *)curproxy->table.peers.name);
7897 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02007898 cfgerr++;
7899 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02007900 else if (curpeers->state == PR_STSTOPPED) {
7901 /* silently disable this peers section */
7902 curproxy->table.peers.p = NULL;
7903 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007904 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007905 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
7906 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02007907 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02007908 cfgerr++;
7909 }
7910 }
7911
Simon Horman9dc49962015-01-30 11:22:59 +09007912
7913 if (curproxy->email_alert.mailers.name) {
7914 struct mailers *curmailers = mailers;
7915
7916 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02007917 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09007918 break;
Simon Horman9dc49962015-01-30 11:22:59 +09007919 }
Simon Horman9dc49962015-01-30 11:22:59 +09007920 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007921 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
7922 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09007923 free_email_alert(curproxy);
7924 cfgerr++;
7925 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02007926 else {
7927 err = NULL;
7928 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007929 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02007930 free(err);
7931 cfgerr++;
7932 }
7933 }
Simon Horman9dc49962015-01-30 11:22:59 +09007934 }
7935
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01007936 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01007937 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007938 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007939 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
7940 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007941 cfgerr++;
7942 goto out_uri_auth_compat;
7943 }
7944
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01007945 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01007946 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02007947 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01007948 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007949
Willy Tarreau95fa4692010-02-01 13:05:50 +01007950 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
7951 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007952
7953 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01007954 uri_auth_compat_req[i++] = "realm";
7955 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
7956 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007957
Willy Tarreau95fa4692010-02-01 13:05:50 +01007958 uri_auth_compat_req[i++] = "unless";
7959 uri_auth_compat_req[i++] = "{";
7960 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
7961 uri_auth_compat_req[i++] = "}";
7962 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007963
Willy Tarreauff011f22011-01-06 17:51:27 +01007964 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
7965 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01007966 cfgerr++;
7967 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007968 }
7969
Willy Tarreauff011f22011-01-06 17:51:27 +01007970 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01007971
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007972 if (curproxy->uri_auth->auth_realm) {
7973 free(curproxy->uri_auth->auth_realm);
7974 curproxy->uri_auth->auth_realm = NULL;
7975 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01007976
7977 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007978 }
7979out_uri_auth_compat:
7980
Dragan Dosen43885c72015-10-01 13:18:13 +02007981 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02007982 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02007983 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
7984 if (!curproxy->conf.logformat_sd_string) {
7985 /* set the default logformat_sd_string */
7986 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
7987 }
Dragan Dosen1322d092015-09-22 16:05:32 +02007988 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02007989 }
Dragan Dosen1322d092015-09-22 16:05:32 +02007990 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02007991
Willy Tarreaua4312fa2013-04-02 16:34:32 +02007992 /* compile the log format */
7993 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02007994 if (curproxy->conf.logformat_string != default_http_log_format &&
7995 curproxy->conf.logformat_string != default_tcp_log_format &&
7996 curproxy->conf.logformat_string != clf_http_log_format)
7997 free(curproxy->conf.logformat_string);
7998 curproxy->conf.logformat_string = NULL;
7999 free(curproxy->conf.lfs_file);
8000 curproxy->conf.lfs_file = NULL;
8001 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008002
8003 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8004 free(curproxy->conf.logformat_sd_string);
8005 curproxy->conf.logformat_sd_string = NULL;
8006 free(curproxy->conf.lfsd_file);
8007 curproxy->conf.lfsd_file = NULL;
8008 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008009 }
8010
Willy Tarreau62a61232013-04-12 18:13:46 +02008011 if (curproxy->conf.logformat_string) {
8012 curproxy->conf.args.ctx = ARGC_LOG;
8013 curproxy->conf.args.file = curproxy->conf.lfs_file;
8014 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008015 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008016 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008017 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008018 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8019 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008020 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008021 cfgerr++;
8022 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008023 curproxy->conf.args.file = NULL;
8024 curproxy->conf.args.line = 0;
8025 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008026
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008027 if (curproxy->conf.logformat_sd_string) {
8028 curproxy->conf.args.ctx = ARGC_LOGSD;
8029 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8030 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008031 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008032 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 +01008033 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008034 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8035 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008036 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008037 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008038 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008039 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8040 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008041 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008042 cfgerr++;
8043 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008044 curproxy->conf.args.file = NULL;
8045 curproxy->conf.args.line = 0;
8046 }
8047
Willy Tarreau62a61232013-04-12 18:13:46 +02008048 if (curproxy->conf.uniqueid_format_string) {
8049 curproxy->conf.args.ctx = ARGC_UIF;
8050 curproxy->conf.args.file = curproxy->conf.uif_file;
8051 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008052 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008053 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 +01008054 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008055 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8056 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008057 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008058 cfgerr++;
8059 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008060 curproxy->conf.args.file = NULL;
8061 curproxy->conf.args.line = 0;
8062 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008063
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008064 /* only now we can check if some args remain unresolved.
8065 * This must be done after the users and groups resolution.
8066 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008067 cfgerr += smp_resolve_args(curproxy);
8068 if (!cfgerr)
8069 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008070
Willy Tarreau2738a142006-07-08 17:28:09 +02008071 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008072 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008073 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008074 (!curproxy->timeout.connect ||
8075 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008076 ha_warning("config : missing timeouts for %s '%s'.\n"
8077 " | While not properly invalid, you will certainly encounter various problems\n"
8078 " | with such a configuration. To fix this, please ensure that all following\n"
8079 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8080 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008081 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008082 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008083
Willy Tarreau1fa31262007-12-03 00:36:16 +01008084 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8085 * We must still support older configurations, so let's find out whether those
8086 * parameters have been set or must be copied from contimeouts.
8087 */
8088 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008089 if (!curproxy->timeout.tarpit ||
8090 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008091 /* tarpit timeout not set. We search in the following order:
8092 * default.tarpit, curr.connect, default.connect.
8093 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008094 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008095 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008096 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008097 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008098 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008099 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008100 }
8101 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008102 (!curproxy->timeout.queue ||
8103 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008104 /* queue timeout not set. We search in the following order:
8105 * default.queue, curr.connect, default.connect.
8106 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008107 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008108 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008109 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008110 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008111 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008112 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008113 }
8114 }
8115
Willy Tarreau1620ec32011-08-06 17:05:02 +02008116 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008117 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008118 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008119 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008120 }
8121
Willy Tarreau215663d2014-06-13 18:30:23 +02008122 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8123 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008124 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8125 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008126 err_code |= ERR_WARN;
8127 }
8128
Willy Tarreau193b8c62012-11-22 00:17:38 +01008129 /* ensure that cookie capture length is not too large */
8130 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008131 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8132 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008133 err_code |= ERR_WARN;
8134 curproxy->capture_len = global.tune.cookie_len - 1;
8135 }
8136
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008137 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008138 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008139 curproxy->req_cap_pool = create_pool("ptrcap",
8140 curproxy->nb_req_cap * sizeof(char *),
8141 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008142 }
8143
8144 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008145 curproxy->rsp_cap_pool = create_pool("ptrcap",
8146 curproxy->nb_rsp_cap * sizeof(char *),
8147 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008148 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008149
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008150 switch (curproxy->load_server_state_from_file) {
8151 case PR_SRV_STATE_FILE_UNSPEC:
8152 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8153 break;
8154 case PR_SRV_STATE_FILE_GLOBAL:
8155 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008156 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",
8157 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008158 err_code |= ERR_WARN;
8159 }
8160 break;
8161 }
8162
Willy Tarreaubaaee002006-06-26 02:48:02 +02008163 /* first, we will invert the servers list order */
8164 newsrv = NULL;
8165 while (curproxy->srv) {
8166 struct server *next;
8167
8168 next = curproxy->srv->next;
8169 curproxy->srv->next = newsrv;
8170 newsrv = curproxy->srv;
8171 if (!next)
8172 break;
8173 curproxy->srv = next;
8174 }
8175
Willy Tarreau17edc812014-01-03 12:14:34 +01008176 /* Check that no server name conflicts. This causes trouble in the stats.
8177 * We only emit a warning for the first conflict affecting each server,
8178 * in order to avoid combinatory explosion if all servers have the same
8179 * name. We do that only for servers which do not have an explicit ID,
8180 * because these IDs were made also for distinguishing them and we don't
8181 * want to annoy people who correctly manage them.
8182 */
8183 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8184 struct server *other_srv;
8185
8186 if (newsrv->puid)
8187 continue;
8188
8189 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8190 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008191 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",
8192 newsrv->conf.file, newsrv->conf.line,
8193 proxy_type_str(curproxy), curproxy->id,
8194 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008195 break;
8196 }
8197 }
8198 }
8199
Willy Tarreaudd701652010-05-25 23:03:02 +02008200 /* assign automatic UIDs to servers which don't have one yet */
8201 next_id = 1;
8202 newsrv = curproxy->srv;
8203 while (newsrv != NULL) {
8204 if (!newsrv->puid) {
8205 /* server ID not set, use automatic numbering with first
8206 * spare entry starting with next_svid.
8207 */
8208 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8209 newsrv->conf.id.key = newsrv->puid = next_id;
8210 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8211 }
8212 next_id++;
8213 newsrv = newsrv->next;
8214 }
8215
Willy Tarreau20697042007-11-15 23:26:18 +01008216 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008217 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008218
Willy Tarreau62c3be22012-01-20 13:12:32 +01008219 /*
8220 * If this server supports a maxconn parameter, it needs a dedicated
8221 * tasks to fill the emptied slots when a connection leaves.
8222 * Also, resolve deferred tracking dependency if needed.
8223 */
8224 newsrv = curproxy->srv;
8225 while (newsrv != NULL) {
8226 if (newsrv->minconn > newsrv->maxconn) {
8227 /* Only 'minconn' was specified, or it was higher than or equal
8228 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8229 * this will avoid further useless expensive computations.
8230 */
8231 newsrv->maxconn = newsrv->minconn;
8232 } else if (newsrv->maxconn && !newsrv->minconn) {
8233 /* minconn was not specified, so we set it to maxconn */
8234 newsrv->minconn = newsrv->maxconn;
8235 }
8236
Willy Tarreau17d45382016-12-22 21:16:08 +01008237 /* this will also properly set the transport layer for prod and checks */
8238 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8239 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8240 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8241 }
Emeric Brun94324a42012-10-11 14:00:19 +02008242
Willy Tarreau2f075e92013-12-03 11:11:34 +01008243 /* set the check type on the server */
8244 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8245
Willy Tarreau62c3be22012-01-20 13:12:32 +01008246 if (newsrv->trackit) {
8247 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008248 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008249 char *pname, *sname;
8250
8251 pname = newsrv->trackit;
8252 sname = strrchr(pname, '/');
8253
8254 if (sname)
8255 *sname++ = '\0';
8256 else {
8257 sname = pname;
8258 pname = NULL;
8259 }
8260
8261 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008262 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008263 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008264 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8265 proxy_type_str(curproxy), curproxy->id,
8266 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008267 cfgerr++;
8268 goto next_srv;
8269 }
8270 } else
8271 px = curproxy;
8272
8273 srv = findserver(px, sname);
8274 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008275 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8276 proxy_type_str(curproxy), curproxy->id,
8277 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008278 cfgerr++;
8279 goto next_srv;
8280 }
8281
Willy Tarreau32091232014-05-16 13:52:00 +02008282 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8283 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8284 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008285 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8286 "tracking as it does not have any check nor agent enabled.\n",
8287 proxy_type_str(curproxy), curproxy->id,
8288 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008289 cfgerr++;
8290 goto next_srv;
8291 }
8292
8293 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8294
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008295 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008296 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8297 "belongs to a tracking chain looping back to %s/%s.\n",
8298 proxy_type_str(curproxy), curproxy->id,
8299 newsrv->id, px->id, srv->id, px->id,
8300 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008301 cfgerr++;
8302 goto next_srv;
8303 }
8304
8305 if (curproxy != px &&
8306 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008307 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8308 "tracking: disable-on-404 option inconsistency.\n",
8309 proxy_type_str(curproxy), curproxy->id,
8310 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008311 cfgerr++;
8312 goto next_srv;
8313 }
8314
Willy Tarreau62c3be22012-01-20 13:12:32 +01008315 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008316 newsrv->tracknext = srv->trackers;
8317 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008318
8319 free(newsrv->trackit);
8320 newsrv->trackit = NULL;
8321 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008322
Willy Tarreau62c3be22012-01-20 13:12:32 +01008323 next_srv:
8324 newsrv = newsrv->next;
8325 }
8326
Olivier Houchard4e694042017-03-14 20:01:29 +01008327 /*
8328 * Try to generate dynamic cookies for servers now.
8329 * It couldn't be done earlier, since at the time we parsed
8330 * the server line, we may not have known yet that we
8331 * should use dynamic cookies, or the secret key may not
8332 * have been provided yet.
8333 */
8334 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8335 newsrv = curproxy->srv;
8336 while (newsrv != NULL) {
8337 srv_set_dyncookie(newsrv);
8338 newsrv = newsrv->next;
8339 }
8340
8341 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008342 /* We have to initialize the server lookup mechanism depending
8343 * on what LB algorithm was choosen.
8344 */
8345
8346 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8347 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8348 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008349 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8350 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8351 init_server_map(curproxy);
8352 } else {
8353 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8354 fwrr_init_server_groups(curproxy);
8355 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008356 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008357
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008358 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008359 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8360 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8361 fwlc_init_server_tree(curproxy);
8362 } else {
8363 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8364 fas_init_server_tree(curproxy);
8365 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008366 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008367
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008368 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008369 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8370 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8371 chash_init_server_tree(curproxy);
8372 } else {
8373 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8374 init_server_map(curproxy);
8375 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008376 break;
8377 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008378 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008379
8380 if (curproxy->options & PR_O_LOGASAP)
8381 curproxy->to_log &= ~LW_BYTES;
8382
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008383 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008384 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8385 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008386 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8387 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008388 err_code |= ERR_WARN;
8389 }
8390
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008391 if (curproxy->mode != PR_MODE_HTTP) {
8392 int optnum;
8393
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008394 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008395 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8396 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008397 err_code |= ERR_WARN;
8398 curproxy->uri_auth = NULL;
8399 }
8400
Willy Tarreaude7dc882017-03-10 11:49:21 +01008401 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008402 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8403 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008404 err_code |= ERR_WARN;
8405 }
8406
8407 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008408 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8409 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008410 err_code |= ERR_WARN;
8411 }
8412
8413 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008414 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8415 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008416 err_code |= ERR_WARN;
8417 }
8418
8419 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008420 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8421 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008422 err_code |= ERR_WARN;
8423 }
8424
8425 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008426 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8427 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008428 err_code |= ERR_WARN;
8429 }
8430
Willy Tarreau87cf5142011-08-19 22:57:24 +02008431 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008432 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8433 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008434 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008435 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008436 }
8437
8438 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008439 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8440 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008441 err_code |= ERR_WARN;
8442 curproxy->options &= ~PR_O_ORGTO;
8443 }
8444
8445 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8446 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8447 (curproxy->cap & cfg_opts[optnum].cap) &&
8448 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008449 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8450 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008451 err_code |= ERR_WARN;
8452 curproxy->options &= ~cfg_opts[optnum].val;
8453 }
8454 }
8455
8456 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8457 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8458 (curproxy->cap & cfg_opts2[optnum].cap) &&
8459 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008460 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8461 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008462 err_code |= ERR_WARN;
8463 curproxy->options2 &= ~cfg_opts2[optnum].val;
8464 }
8465 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008466
Willy Tarreau29fbe512015-08-20 19:35:14 +02008467#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008468 if (curproxy->conn_src.bind_hdr_occ) {
8469 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008470 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8471 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008472 err_code |= ERR_WARN;
8473 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008474#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008475 }
8476
Willy Tarreaubaaee002006-06-26 02:48:02 +02008477 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008478 * ensure that we're not cross-dressing a TCP server into HTTP.
8479 */
8480 newsrv = curproxy->srv;
8481 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008482 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008483 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8484 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008485 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008486 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008487
Willy Tarreau0cec3312011-10-31 13:49:26 +01008488 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008489 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8490 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008491 err_code |= ERR_WARN;
8492 }
8493
Willy Tarreauc93cd162014-05-13 15:54:22 +02008494 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008495 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8496 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008497 err_code |= ERR_WARN;
8498 }
8499
Willy Tarreau29fbe512015-08-20 19:35:14 +02008500#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008501 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8502 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008503 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8504 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008505 err_code |= ERR_WARN;
8506 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008507#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008508
8509 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8510 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8511 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8512 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8513 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008514 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",
8515 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008516 err_code |= ERR_WARN;
8517 }
8518
8519
8520 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008521 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",
8522 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008523 err_code |= ERR_WARN;
8524 }
8525 }
8526
Willy Tarreau21d2af32008-02-14 20:25:24 +01008527 newsrv = newsrv->next;
8528 }
8529
Willy Tarreaue42bd962014-09-16 16:21:19 +02008530 /* check if we have a frontend with "tcp-request content" looking at L7
8531 * with no inspect-delay
8532 */
8533 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008534 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8535 if (arule->action == ACT_TCP_CAPTURE &&
8536 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008537 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008538 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8539 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008540 break;
8541 }
8542
Christopher Faulete4e830d2017-09-18 14:51:41 +02008543 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008544 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8545 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8546 " This means that these rules will randomly find their contents. This can be fixed by"
8547 " setting the tcp-request inspect-delay.\n",
8548 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008549 err_code |= ERR_WARN;
8550 }
8551 }
8552
Christopher Fauletd7c91962015-04-30 11:48:27 +02008553 /* Check filter configuration, if any */
8554 cfgerr += flt_check(curproxy);
8555
Willy Tarreauc1a21672009-08-16 22:37:44 +02008556 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008557 if (!curproxy->accept)
8558 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008559
Willy Tarreauc1a21672009-08-16 22:37:44 +02008560 if (curproxy->tcp_req.inspect_delay ||
8561 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008562 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008563
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008564 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008565 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008566 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008567 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008568
8569 /* both TCP and HTTP must check switching rules */
8570 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008571
8572 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008573 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008574 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8575 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 +01008576 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008577 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8578 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008579 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008580 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008581 }
8582
8583 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008584 if (curproxy->tcp_req.inspect_delay ||
8585 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8586 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8587
Emeric Brun97679e72010-09-23 17:56:44 +02008588 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8589 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8590
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008591 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008592 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008593 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008594 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008595
8596 /* If the backend does requires RDP cookie persistence, we have to
8597 * enable the corresponding analyser.
8598 */
8599 if (curproxy->options2 & PR_O2_RDPC_PRST)
8600 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008601
8602 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008603 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008604 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8605 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 +01008606 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008607 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8608 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008609 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008610 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008611 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008612 }
8613
8614 /***********************************************************/
8615 /* At this point, target names have already been resolved. */
8616 /***********************************************************/
8617
8618 /* Check multi-process mode compatibility */
8619
8620 if (global.nbproc > 1 && global.stats_fe) {
8621 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8622 unsigned long mask;
8623
8624 mask = nbits(global.nbproc);
8625 if (global.stats_fe->bind_proc)
8626 mask &= global.stats_fe->bind_proc;
8627
8628 if (bind_conf->bind_proc)
8629 mask &= bind_conf->bind_proc;
8630
8631 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008632 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008633 break;
8634 }
8635 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008636 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 +02008637 }
8638 }
8639
8640 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008641 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008642 if (curproxy->bind_proc)
8643 continue;
8644
8645 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8646 unsigned long mask;
8647
Willy Tarreaue428b082015-05-04 21:57:58 +02008648 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008649 curproxy->bind_proc |= mask;
8650 }
8651
8652 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008653 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008654 }
8655
8656 if (global.stats_fe) {
8657 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8658 unsigned long mask;
8659
Cyril Bonté06181952016-02-24 00:14:54 +01008660 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008661 global.stats_fe->bind_proc |= mask;
8662 }
8663 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008664 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008665 }
8666
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008667 /* propagate bindings from frontends to backends. Don't do it if there
8668 * are any fatal errors as we must not call it with unresolved proxies.
8669 */
8670 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008671 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008672 if (curproxy->cap & PR_CAP_FE)
8673 propagate_processes(curproxy, NULL);
8674 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008675 }
8676
8677 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008678 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008679 if (curproxy->bind_proc)
8680 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008681 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008682 }
8683
8684 /*******************************************************/
8685 /* At this step, all proxies have a non-null bind_proc */
8686 /*******************************************************/
8687
8688 /* perform the final checks before creating tasks */
8689
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008690 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008691 struct listener *listener;
8692 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008693
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008694 /* Configure SSL for each bind line.
8695 * Note: if configuration fails at some point, the ->ctx member
8696 * remains NULL so that listeners can later detach.
8697 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008698 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008699 if (bind_conf->xprt->prepare_bind_conf &&
8700 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008701 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008702 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008703
Willy Tarreaue6b98942007-10-29 01:09:36 +01008704 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008705 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008706 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008707 int nbproc;
8708
8709 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008710 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008711 nbits(global.nbproc));
8712
8713 if (!nbproc) /* no intersection between listener and frontend */
8714 nbproc = 1;
8715
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008716 if (!listener->luid) {
8717 /* listener ID not set, use automatic numbering with first
8718 * spare entry starting with next_luid.
8719 */
8720 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8721 listener->conf.id.key = listener->luid = next_id;
8722 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008723 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008724 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008725
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008726 /* enable separate counters */
8727 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008728 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008729 if (!listener->name)
8730 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008731 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008732
Willy Tarreaue6b98942007-10-29 01:09:36 +01008733 if (curproxy->options & PR_O_TCP_NOLING)
8734 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008735 if (!listener->maxconn)
8736 listener->maxconn = curproxy->maxconn;
8737 if (!listener->backlog)
8738 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008739 if (!listener->maxaccept)
8740 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8741
8742 /* we want to have an optimal behaviour on single process mode to
8743 * maximize the work at once, but in multi-process we want to keep
8744 * some fairness between processes, so we target half of the max
8745 * number of events to be balanced over all the processes the proxy
8746 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8747 * used to disable the limit.
8748 */
8749 if (listener->maxaccept > 0) {
8750 if (nbproc > 1)
8751 listener->maxaccept = (listener->maxaccept + 1) / 2;
8752 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8753 }
8754
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008755 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008756 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008757 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008758
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008759 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008760 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008761
Willy Tarreau620408f2016-10-21 16:37:51 +02008762 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8763 listener->options |= LI_O_TCP_L5_RULES;
8764
Willy Tarreaude3041d2010-05-31 10:56:17 +02008765 if (curproxy->mon_mask.s_addr)
8766 listener->options |= LI_O_CHK_MONNET;
8767
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008768 /* smart accept mode is automatic in HTTP mode */
8769 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008770 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008771 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8772 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008773 }
8774
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008775 /* Release unused SSL configs */
8776 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008777 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8778 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008779 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008780
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008781 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008782 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008783 int count, maxproc = 0;
8784
8785 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008786 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008787 if (count > maxproc)
8788 maxproc = count;
8789 }
8790 /* backends have 0, frontends have 1 or more */
8791 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008792 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8793 " limited to process assigned to the current request.\n",
8794 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008795
Willy Tarreau102df612014-05-07 23:56:38 +02008796 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008797 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
8798 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008799 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008800 }
Willy Tarreau102df612014-05-07 23:56:38 +02008801 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008802 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
8803 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008804 }
8805 }
Willy Tarreau918ff602011-07-25 16:33:49 +02008806
8807 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02008808 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02008809 if (curproxy->task) {
8810 curproxy->task->context = curproxy;
8811 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02008812 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008813 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
8814 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02008815 cfgerr++;
8816 }
Willy Tarreaub369a042014-09-16 13:21:03 +02008817 }
8818
Willy Tarreaufbb78422011-06-05 15:38:35 +02008819 /* automatically compute fullconn if not set. We must not do it in the
8820 * loop above because cross-references are not yet fully resolved.
8821 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008822 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008823 /* If <fullconn> is not set, let's set it to 10% of the sum of
8824 * the possible incoming frontend's maxconns.
8825 */
8826 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02008827 /* we have the sum of the maxconns in <total>. We only
8828 * keep 10% of that sum to set the default fullconn, with
8829 * a hard minimum of 1 (to avoid a divide by zero).
8830 */
Emeric Brun3f783572017-01-12 11:21:28 +01008831 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02008832 if (!curproxy->fullconn)
8833 curproxy->fullconn = 1;
8834 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01008835 }
8836
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008837 /*
8838 * Recount currently required checks.
8839 */
8840
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008841 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008842 int optnum;
8843
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008844 for (optnum = 0; cfg_opts[optnum].name; optnum++)
8845 if (curproxy->options & cfg_opts[optnum].val)
8846 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008847
Willy Tarreau66aa61f2009-01-18 21:44:07 +01008848 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
8849 if (curproxy->options2 & cfg_opts2[optnum].val)
8850 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01008851 }
8852
Willy Tarreau0fca4832015-05-01 19:12:05 +02008853 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008854 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02008855 if (curproxy->table.peers.p)
8856 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
8857
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008858 if (cfg_peers) {
8859 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02008860 struct peer *p, *pb;
8861
Willy Tarreau1e273012015-05-01 19:15:17 +02008862 /* Remove all peers sections which don't have a valid listener,
8863 * which are not used by any table, or which are bound to more
8864 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02008865 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008866 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02008867 while (*last) {
8868 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008869
8870 if (curpeers->state == PR_STSTOPPED) {
8871 /* the "disabled" keyword was present */
8872 if (curpeers->peers_fe)
8873 stop_proxy(curpeers->peers_fe);
8874 curpeers->peers_fe = NULL;
8875 }
8876 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008877 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
8878 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008879 }
David Carliere6c39412015-07-02 07:00:17 +00008880 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02008881 /* either it's totally stopped or too much used */
8882 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008883 ha_alert("Peers section '%s': peers referenced by sections "
8884 "running in different processes (%d different ones). "
8885 "Check global.nbproc and all tables' bind-process "
8886 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02008887 cfgerr++;
8888 }
8889 stop_proxy(curpeers->peers_fe);
8890 curpeers->peers_fe = NULL;
8891 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008892 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02008893 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02008894 last = &curpeers->next;
8895 continue;
8896 }
8897
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008898 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02008899 p = curpeers->remote;
8900 while (p) {
8901 pb = p->next;
8902 free(p->id);
8903 free(p);
8904 p = pb;
8905 }
8906
8907 /* Destroy and unlink this curpeers section.
8908 * Note: curpeers is backed up into *last.
8909 */
8910 free(curpeers->id);
8911 curpeers = curpeers->next;
8912 free(*last);
8913 *last = curpeers;
8914 }
8915 }
8916
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008917 /* initialize stick-tables on backend capable proxies. This must not
8918 * be done earlier because the data size may be discovered while parsing
8919 * other proxies.
8920 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008921 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008922 if (curproxy->state == PR_STSTOPPED)
8923 continue;
8924
8925 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008926 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008927 cfgerr++;
8928 }
8929 }
8930
Simon Horman0d16a402015-01-30 11:22:58 +09008931 if (mailers) {
8932 struct mailers *curmailers = mailers, **last;
8933 struct mailer *m, *mb;
8934
8935 /* Remove all mailers sections which don't have a valid listener.
8936 * This can happen when a mailers section is never referenced.
8937 */
8938 last = &mailers;
8939 while (*last) {
8940 curmailers = *last;
8941 if (curmailers->users) {
8942 last = &curmailers->next;
8943 continue;
8944 }
8945
Christopher Faulet767a84b2017-11-24 16:50:31 +01008946 ha_warning("Removing incomplete section 'mailers %s'.\n",
8947 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09008948
8949 m = curmailers->mailer_list;
8950 while (m) {
8951 mb = m->next;
8952 free(m->id);
8953 free(m);
8954 m = mb;
8955 }
8956
8957 /* Destroy and unlink this curmailers section.
8958 * Note: curmailers is backed up into *last.
8959 */
8960 free(curmailers->id);
8961 curmailers = curmailers->next;
8962 free(*last);
8963 *last = curmailers;
8964 }
8965 }
8966
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008967 /* Update server_state_file_name to backend name if backend is supposed to use
8968 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008969 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008970 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
8971 curproxy->server_state_file_name == NULL)
8972 curproxy->server_state_file_name = strdup(curproxy->id);
8973 }
8974
Willy Tarreaubafbe012017-11-24 17:34:44 +01008975 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02008976 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02008977 MEM_F_SHARED);
8978
William Lallemand48b4bb42017-10-23 14:36:34 +02008979 list_for_each_entry(postparser, &postparsers, list) {
8980 if (postparser->func)
8981 cfgerr += postparser->func();
8982 }
8983
Willy Tarreaubb925012009-07-23 13:36:36 +02008984 if (cfgerr > 0)
8985 err_code |= ERR_ALERT | ERR_FATAL;
8986 out:
8987 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02008988}
8989
Willy Tarreau5b2c3362008-07-09 19:39:06 +02008990/*
8991 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
8992 * parsing sessions.
8993 */
8994void cfg_register_keywords(struct cfg_kw_list *kwl)
8995{
8996 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
8997}
Willy Tarreaubaaee002006-06-26 02:48:02 +02008998
Willy Tarreau5b2c3362008-07-09 19:39:06 +02008999/*
9000 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9001 */
9002void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9003{
9004 LIST_DEL(&kwl->list);
9005 LIST_INIT(&kwl->list);
9006}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009007
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009008/* this function register new section in the haproxy configuration file.
9009 * <section_name> is the name of this new section and <section_parser>
9010 * is the called parser. If two section declaration have the same name,
9011 * only the first declared is used.
9012 */
9013int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009014 int (*section_parser)(const char *, int, char **, int),
9015 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009016{
9017 struct cfg_section *cs;
9018
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009019 list_for_each_entry(cs, &sections, list) {
9020 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009021 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009022 return 0;
9023 }
9024 }
9025
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009026 cs = calloc(1, sizeof(*cs));
9027 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009028 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009029 return 0;
9030 }
9031
9032 cs->section_name = section_name;
9033 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009034 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009035
9036 LIST_ADDQ(&sections, &cs->list);
9037
9038 return 1;
9039}
9040
William Lallemand48b4bb42017-10-23 14:36:34 +02009041/* this function register a new function which will be called once the haproxy
9042 * configuration file has been parsed. It's useful to check dependencies
9043 * between sections or to resolve items once everything is parsed.
9044 */
9045int cfg_register_postparser(char *name, int (*func)())
9046{
9047 struct cfg_postparser *cp;
9048
9049 cp = calloc(1, sizeof(*cp));
9050 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009051 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009052 return 0;
9053 }
9054 cp->name = name;
9055 cp->func = func;
9056
9057 LIST_ADDQ(&postparsers, &cp->list);
9058
9059 return 1;
9060}
9061
Willy Tarreaubaaee002006-06-26 02:48:02 +02009062/*
David Carlier845efb52015-09-25 11:49:18 +01009063 * free all config section entries
9064 */
9065void cfg_unregister_sections(void)
9066{
9067 struct cfg_section *cs, *ics;
9068
9069 list_for_each_entry_safe(cs, ics, &sections, list) {
9070 LIST_DEL(&cs->list);
9071 free(cs);
9072 }
9073}
9074
Christopher Faulet7110b402016-10-26 11:09:44 +02009075void cfg_backup_sections(struct list *backup_sections)
9076{
9077 struct cfg_section *cs, *ics;
9078
9079 list_for_each_entry_safe(cs, ics, &sections, list) {
9080 LIST_DEL(&cs->list);
9081 LIST_ADDQ(backup_sections, &cs->list);
9082 }
9083}
9084
9085void cfg_restore_sections(struct list *backup_sections)
9086{
9087 struct cfg_section *cs, *ics;
9088
9089 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9090 LIST_DEL(&cs->list);
9091 LIST_ADDQ(&sections, &cs->list);
9092 }
9093}
9094
Willy Tarreau659fbf02016-05-26 17:55:28 +02009095__attribute__((constructor))
9096static void cfgparse_init(void)
9097{
9098 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009099 cfg_register_section("listen", cfg_parse_listen, NULL);
9100 cfg_register_section("frontend", cfg_parse_listen, NULL);
9101 cfg_register_section("backend", cfg_parse_listen, NULL);
9102 cfg_register_section("defaults", cfg_parse_listen, NULL);
9103 cfg_register_section("global", cfg_parse_global, NULL);
9104 cfg_register_section("userlist", cfg_parse_users, NULL);
9105 cfg_register_section("peers", cfg_parse_peers, NULL);
9106 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9107 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9108 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009109}
9110
David Carlier845efb52015-09-25 11:49:18 +01009111/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009112 * Local variables:
9113 * c-indent-level: 8
9114 * c-basic-offset: 8
9115 * End:
9116 */