blob: e7e32cf9d2e414441b5371184f5efa0ed2b04e21 [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 Tarreau61d18892009-03-31 10:49:21 +0200409/* Report a warning if a rule is placed after a 'block' rule.
410 * Return 1 if the warning has been emitted, otherwise 0.
411 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100412int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200413{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200414 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100415 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
416 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200417 return 1;
418 }
419 return 0;
420}
421
Willy Tarreau5002f572014-04-23 01:32:02 +0200422/* Report a warning if a rule is placed after an 'http_request' rule.
423 * Return 1 if the warning has been emitted, otherwise 0.
424 */
425int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
426{
427 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100428 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
429 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200430 return 1;
431 }
432 return 0;
433}
434
Willy Tarreau61d18892009-03-31 10:49:21 +0200435/* Report a warning if a rule is placed after a reqrewrite rule.
436 * Return 1 if the warning has been emitted, otherwise 0.
437 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100438int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200439{
440 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100441 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
442 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200443 return 1;
444 }
445 return 0;
446}
447
448/* Report a warning if a rule is placed after a reqadd rule.
449 * Return 1 if the warning has been emitted, otherwise 0.
450 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100451int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200452{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100453 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100454 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' 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 redirect rule.
462 * Return 1 if the warning has been emitted, otherwise 0.
463 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100464int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200465{
466 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100467 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' 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 'use_backend' rule.
475 * Return 1 if the warning has been emitted, otherwise 0.
476 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100477int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200478{
479 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100480 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' 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
Willy Tarreauee445d92014-04-23 01:39:04 +0200487/* Report a warning if a rule is placed after a 'use-server' rule.
488 * Return 1 if the warning has been emitted, otherwise 0.
489 */
490int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
491{
492 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100493 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
494 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200495 return 1;
496 }
497 return 0;
498}
499
Willy Tarreaud39ad442016-11-25 15:16:12 +0100500/* report a warning if a redirect rule is dangerously placed */
501int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200502{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100503 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200504 warnif_rule_after_use_server(proxy, file, line, arg);
505}
506
Willy Tarreaud39ad442016-11-25 15:16:12 +0100507/* report a warning if a reqadd rule is dangerously placed */
508int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200509{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100510 return warnif_rule_after_redirect(proxy, file, line, arg) ||
511 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200512}
513
Willy Tarreaud39ad442016-11-25 15:16:12 +0100514/* report a warning if a reqxxx rule is dangerously placed */
515int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200516{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100517 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
518 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200519}
520
521/* report a warning if an http-request rule is dangerously placed */
522int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
523{
Willy Tarreau61d18892009-03-31 10:49:21 +0200524 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100525 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200526}
527
Willy Tarreaud39ad442016-11-25 15:16:12 +0100528/* report a warning if a block rule is dangerously placed */
529int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200530{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100531 return warnif_rule_after_http_req(proxy, file, line, arg) ||
532 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200533}
534
Willy Tarreaud39ad442016-11-25 15:16:12 +0100535/* report a warning if a "tcp request content" rule is dangerously placed */
536int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200537{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100538 return warnif_rule_after_block(proxy, file, line, arg) ||
539 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200540}
541
Willy Tarreaud39ad442016-11-25 15:16:12 +0100542/* report a warning if a "tcp request session" rule is dangerously placed */
543int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200544{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100545 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
546 warnif_misplaced_tcp_cont(proxy, file, line, arg);
547}
548
549/* report a warning if a "tcp request connection" rule is dangerously placed */
550int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
551{
552 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
553 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200554}
555
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100556/* Report it if a request ACL condition uses some keywords that are incompatible
557 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
558 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
559 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100560 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100561static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100562{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100563 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200564 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100565
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100566 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100567 return 0;
568
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100569 acl = acl_cond_conflicts(cond, where);
570 if (acl) {
571 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100572 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
573 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100574 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100575 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
576 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100577 return ERR_WARN;
578 }
579 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100580 return 0;
581
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100582 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100583 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
584 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100585 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100586 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
587 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100588 return ERR_WARN;
589}
590
Christopher Faulet62519022017-10-16 15:49:32 +0200591/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100592 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100593 * two such numbers delimited by a dash ('-'). On success, it returns
594 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200595 *
596 * Note: this function can also be used to parse a thread number or a set of
597 * threads.
598 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100599int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200600{
Christopher Faulet26028f62017-11-22 15:01:51 +0100601 if (autoinc) {
602 *autoinc = 0;
603 if (strncmp(arg, "auto:", 5) == 0) {
604 arg += 5;
605 *autoinc = 1;
606 }
607 }
608
Christopher Faulet62519022017-10-16 15:49:32 +0200609 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100610 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200611 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100612 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200613 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100614 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200615 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100616 char *dash;
617 unsigned int low, high;
618
Christopher Faulet5ab51772017-11-22 11:21:58 +0100619 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100620 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100621 return -1;
622 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100623
624 low = high = str2uic(arg);
625 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100626 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
627
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100628 if (high < low) {
629 unsigned int swap = low;
630 low = high;
631 high = swap;
632 }
633
Christopher Faulet5ab51772017-11-22 11:21:58 +0100634 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100635 memprintf(err, "'%s' is not a valid number/range."
636 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100637 arg, LONGBITS);
638 return 1;
639 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100640
641 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100642 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200643 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100644
645 end:
Christopher Faulet5ab51772017-11-22 11:21:58 +0100646 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200647}
648
649/* Parse cpu sets. Each CPU set is either a unique number between 0 and
650 * <LONGBITS> or a range with two such numbers delimited by a dash
651 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
652 * returns 0. otherwise it returns 1 with an error message in <err>.
653 */
654static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
655{
656 int cur_arg = 0;
657
658 *cpu_set = 0;
659 while (*args[cur_arg]) {
660 char *dash;
661 unsigned int low, high;
662
663 if (!isdigit((int)*args[cur_arg])) {
664 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
665 return -1;
666 }
667
668 low = high = str2uic(args[cur_arg]);
669 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100670 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200671
672 if (high < low) {
673 unsigned int swap = low;
674 low = high;
675 high = swap;
676 }
677
678 if (high >= LONGBITS) {
679 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
680 return 1;
681 }
682
683 while (low <= high)
684 *cpu_set |= 1UL << low++;
685
686 cur_arg++;
687 }
688 return 0;
689}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200690/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200691 * parse a line in a <global> section. Returns the error code, 0 if OK, or
692 * any combination of :
693 * - ERR_ABORT: must abort ASAP
694 * - ERR_FATAL: we can continue parsing but not start the service
695 * - ERR_WARN: a warning has been emitted
696 * - ERR_ALERT: an alert has been emitted
697 * Only the two first ones can stop processing, the two others are just
698 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200699 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200700int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200701{
Willy Tarreau058e9072009-07-20 09:30:05 +0200702 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200703 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200704
705 if (!strcmp(args[0], "global")) { /* new section */
706 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200707 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200708 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200709 }
710 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200711 if (alertif_too_many_args(0, file, linenum, args, &err_code))
712 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200713 global.mode |= MODE_DAEMON;
714 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200715 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200716 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200717 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200718 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100719 if (!strcmp(args[1], "no-exit-on-failure")) {
720 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200721 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100722 ha_alert("parsing [%s:%d] : '%s' only supports 'exit-on-failure' option.\n", file, linenum, args[0]);
William Lallemand69f9b3b2017-06-01 17:38:54 +0200723 err_code |= ERR_ALERT | ERR_FATAL;
724 goto out;
725 }
726 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200727 global.mode |= MODE_MWORKER;
728 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200729 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200730 if (alertif_too_many_args(0, file, linenum, args, &err_code))
731 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200732 global.mode |= MODE_DEBUG;
733 }
734 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200735 if (alertif_too_many_args(0, file, linenum, args, &err_code))
736 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100737 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200738 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200739 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200740 if (alertif_too_many_args(0, file, linenum, args, &err_code))
741 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100742 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200743 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200744 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200745 if (alertif_too_many_args(0, file, linenum, args, &err_code))
746 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100747 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200748 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100749 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200750 if (alertif_too_many_args(0, file, linenum, args, &err_code))
751 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100752 global.tune.options &= ~GTUNE_USE_SPLICE;
753 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200754 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200755 if (alertif_too_many_args(0, file, linenum, args, &err_code))
756 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200757 global.tune.options &= ~GTUNE_USE_GAI;
758 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000759 else if (!strcmp(args[0], "noreuseport")) {
760 if (alertif_too_many_args(0, file, linenum, args, &err_code))
761 goto out;
762 global.tune.options &= ~GTUNE_USE_REUSEPORT;
763 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200764 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200765 if (alertif_too_many_args(0, file, linenum, args, &err_code))
766 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200767 global.mode |= MODE_QUIET;
768 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200769 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200770 if (alertif_too_many_args(1, file, linenum, args, &err_code))
771 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200772 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100773 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200774 err_code |= ERR_ALERT;
775 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200776 }
777 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100778 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200779 err_code |= ERR_ALERT | ERR_FATAL;
780 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200781 }
782 global.tune.maxpollevents = atol(args[1]);
783 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100784 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200785 if (alertif_too_many_args(1, file, linenum, args, &err_code))
786 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100787 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100788 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200789 err_code |= ERR_ALERT;
790 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100791 }
792 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100793 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200794 err_code |= ERR_ALERT | ERR_FATAL;
795 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100796 }
797 global.tune.maxaccept = atol(args[1]);
798 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200799 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200800 if (alertif_too_many_args(1, file, linenum, args, &err_code))
801 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200802 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100803 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200804 err_code |= ERR_ALERT | ERR_FATAL;
805 goto out;
806 }
807 global.tune.chksize = atol(args[1]);
808 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100809 else if (!strcmp(args[0], "tune.recv_enough")) {
810 if (alertif_too_many_args(1, file, linenum, args, &err_code))
811 goto out;
812 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100813 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100814 err_code |= ERR_ALERT | ERR_FATAL;
815 goto out;
816 }
817 global.tune.recv_enough = atol(args[1]);
818 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100819 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200820 if (alertif_too_many_args(1, file, linenum, args, &err_code))
821 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100822 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100823 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100824 err_code |= ERR_ALERT | ERR_FATAL;
825 goto out;
826 }
827 global.tune.buf_limit = atol(args[1]);
828 if (global.tune.buf_limit) {
829 if (global.tune.buf_limit < 3)
830 global.tune.buf_limit = 3;
831 if (global.tune.buf_limit <= global.tune.reserved_bufs)
832 global.tune.buf_limit = global.tune.reserved_bufs + 1;
833 }
834 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100835 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200836 if (alertif_too_many_args(1, file, linenum, args, &err_code))
837 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100838 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100839 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100840 err_code |= ERR_ALERT | ERR_FATAL;
841 goto out;
842 }
843 global.tune.reserved_bufs = atol(args[1]);
844 if (global.tune.reserved_bufs < 2)
845 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100846 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
847 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100848 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200849 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200850 if (alertif_too_many_args(1, file, linenum, args, &err_code))
851 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200852 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100853 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200854 err_code |= ERR_ALERT | ERR_FATAL;
855 goto out;
856 }
857 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200858 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100859 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200860 err_code |= ERR_ALERT | ERR_FATAL;
861 goto out;
862 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200863 }
864 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200865 if (alertif_too_many_args(1, file, linenum, args, &err_code))
866 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200867 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100868 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200869 err_code |= ERR_ALERT | ERR_FATAL;
870 goto out;
871 }
872 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200873 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100874 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200875 err_code |= ERR_ALERT | ERR_FATAL;
876 goto out;
877 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200878 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100879 else if (!strcmp(args[0], "tune.idletimer")) {
880 unsigned int idle;
881 const char *res;
882
William Lallemand1a748ae2015-05-19 16:37:23 +0200883 if (alertif_too_many_args(1, file, linenum, args, &err_code))
884 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100885 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100886 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 +0100887 err_code |= ERR_ALERT | ERR_FATAL;
888 goto out;
889 }
890
891 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
892 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100893 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100894 file, linenum, *res, args[0]);
895 err_code |= ERR_ALERT | ERR_FATAL;
896 goto out;
897 }
898
899 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100900 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 +0100901 err_code |= ERR_ALERT | ERR_FATAL;
902 goto out;
903 }
904 global.tune.idle_timer = idle;
905 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100906 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200907 if (alertif_too_many_args(1, file, linenum, args, &err_code))
908 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100909 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100910 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100911 err_code |= ERR_ALERT;
912 goto out;
913 }
914 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100915 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100916 err_code |= ERR_ALERT | ERR_FATAL;
917 goto out;
918 }
919 global.tune.client_rcvbuf = atol(args[1]);
920 }
921 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200922 if (alertif_too_many_args(1, file, linenum, args, &err_code))
923 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100924 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100925 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100926 err_code |= ERR_ALERT;
927 goto out;
928 }
929 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100930 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100931 err_code |= ERR_ALERT | ERR_FATAL;
932 goto out;
933 }
934 global.tune.server_rcvbuf = atol(args[1]);
935 }
936 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200937 if (alertif_too_many_args(1, file, linenum, args, &err_code))
938 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100939 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100940 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100941 err_code |= ERR_ALERT;
942 goto out;
943 }
944 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100945 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100946 err_code |= ERR_ALERT | ERR_FATAL;
947 goto out;
948 }
949 global.tune.client_sndbuf = atol(args[1]);
950 }
951 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200952 if (alertif_too_many_args(1, file, linenum, args, &err_code))
953 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100954 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100955 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100956 err_code |= ERR_ALERT;
957 goto out;
958 }
959 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100960 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100961 err_code |= ERR_ALERT | ERR_FATAL;
962 goto out;
963 }
964 global.tune.server_sndbuf = atol(args[1]);
965 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200966 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200967 if (alertif_too_many_args(1, file, linenum, args, &err_code))
968 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200969 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100970 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +0200971 err_code |= ERR_ALERT | ERR_FATAL;
972 goto out;
973 }
974 global.tune.pipesize = atol(args[1]);
975 }
Willy Tarreau193b8c62012-11-22 00:17:38 +0100976 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200977 if (alertif_too_many_args(1, file, linenum, args, &err_code))
978 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +0100979 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100980 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +0100981 err_code |= ERR_ALERT | ERR_FATAL;
982 goto out;
983 }
984 global.tune.cookie_len = atol(args[1]) + 1;
985 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +0200986 else if (!strcmp(args[0], "tune.http.logurilen")) {
987 if (alertif_too_many_args(1, file, linenum, args, &err_code))
988 goto out;
989 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100990 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +0200991 err_code |= ERR_ALERT | ERR_FATAL;
992 goto out;
993 }
994 global.tune.requri_len = atol(args[1]) + 1;
995 }
Willy Tarreauac1932d2011-10-24 19:14:41 +0200996 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200997 if (alertif_too_many_args(1, file, linenum, args, &err_code))
998 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +0200999 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001000 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001001 err_code |= ERR_ALERT | ERR_FATAL;
1002 goto out;
1003 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001004 global.tune.max_http_hdr = atoi(args[1]);
1005 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001006 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1007 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001008 err_code |= ERR_ALERT | ERR_FATAL;
1009 goto out;
1010 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001011 }
William Lallemandf3747832012-11-09 12:33:10 +01001012 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001013 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1014 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001015 if (*args[1]) {
1016 global.tune.comp_maxlevel = atoi(args[1]);
1017 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001018 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1019 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001020 err_code |= ERR_ALERT | ERR_FATAL;
1021 goto out;
1022 }
1023 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001024 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1025 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001026 err_code |= ERR_ALERT | ERR_FATAL;
1027 goto out;
1028 }
1029 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001030 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1031 if (*args[1]) {
1032 global.tune.pattern_cache = atoi(args[1]);
1033 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001034 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1035 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001036 err_code |= ERR_ALERT | ERR_FATAL;
1037 goto out;
1038 }
1039 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001040 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1041 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001042 err_code |= ERR_ALERT | ERR_FATAL;
1043 goto out;
1044 }
1045 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001046 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001047 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1048 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001049 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001050 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001051 err_code |= ERR_ALERT;
1052 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001053 }
1054 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001055 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001056 err_code |= ERR_ALERT | ERR_FATAL;
1057 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001058 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001059 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001060 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 +01001061 err_code |= ERR_WARN;
1062 goto out;
1063 }
1064
Willy Tarreaubaaee002006-06-26 02:48:02 +02001065 }
1066 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001067 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1068 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001069 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001070 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001071 err_code |= ERR_ALERT;
1072 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001073 }
1074 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001075 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001076 err_code |= ERR_ALERT | ERR_FATAL;
1077 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001078 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001079 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001080 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 +01001081 err_code |= ERR_WARN;
1082 goto out;
1083 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001084 }
Simon Horman98637e52014-06-20 12:30:16 +09001085 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001086 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1087 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001088 global.external_check = 1;
1089 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001090 /* user/group name handling */
1091 else if (!strcmp(args[0], "user")) {
1092 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001093 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1094 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001095 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001096 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001097 err_code |= ERR_ALERT;
1098 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001099 }
1100 errno = 0;
1101 ha_user = getpwnam(args[1]);
1102 if (ha_user != NULL) {
1103 global.uid = (int)ha_user->pw_uid;
1104 }
1105 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001106 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 +02001107 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001108 }
1109 }
1110 else if (!strcmp(args[0], "group")) {
1111 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001112 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1113 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001114 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001115 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001116 err_code |= ERR_ALERT;
1117 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001118 }
1119 errno = 0;
1120 ha_group = getgrnam(args[1]);
1121 if (ha_group != NULL) {
1122 global.gid = (int)ha_group->gr_gid;
1123 }
1124 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001125 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 +02001126 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001127 }
1128 }
1129 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001130 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001131 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1132 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001133 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001134 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001135 err_code |= ERR_ALERT | ERR_FATAL;
1136 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001137 }
1138 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001139 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001140 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1141 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001142 err_code |= ERR_ALERT | ERR_FATAL;
1143 goto out;
1144 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001145 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001146 else if (!strcmp(args[0], "nbthread")) {
1147 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1148 goto out;
1149 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001150 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001151 err_code |= ERR_ALERT | ERR_FATAL;
1152 goto out;
1153 }
1154 global.nbthread = atol(args[1]);
1155 if (global.nbthread < 1 || global.nbthread > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001156 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1157 file, linenum, args[0], LONGBITS, global.nbthread);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001158 err_code |= ERR_ALERT | ERR_FATAL;
1159 goto out;
1160 }
1161#ifndef USE_THREAD
1162 if (global.nbthread > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001163 ha_alert("HAProxy is not compiled with threads support, please check build options for USE_THREAD.\n");
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001164 global.nbthread = 1;
1165 err_code |= ERR_ALERT | ERR_FATAL;
1166 goto out;
1167 }
1168#endif
1169 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001170 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001171 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1172 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001173 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001174 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001175 err_code |= ERR_ALERT;
1176 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001177 }
1178 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001180 err_code |= ERR_ALERT | ERR_FATAL;
1181 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001182 }
1183 global.maxconn = atol(args[1]);
1184#ifdef SYSTEM_MAXCONN
1185 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001186 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 +02001187 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001188 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001189 }
1190#endif /* SYSTEM_MAXCONN */
1191 }
Emeric Brun850efd52014-01-29 12:24:34 +01001192 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001193 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1194 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001195 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001196 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001197 err_code |= ERR_ALERT | ERR_FATAL;
1198 goto out;
1199 }
1200 if (strcmp(args[1],"none") == 0)
1201 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1202 else if (strcmp(args[1],"required") == 0)
1203 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1204 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001205 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001206 err_code |= ERR_ALERT | ERR_FATAL;
1207 goto out;
1208 }
1209 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001210 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001211 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1212 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001213 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001214 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001215 err_code |= ERR_ALERT;
1216 goto out;
1217 }
1218 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001219 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001220 err_code |= ERR_ALERT | ERR_FATAL;
1221 goto out;
1222 }
1223 global.cps_lim = atol(args[1]);
1224 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001225 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001226 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1227 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001228 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001229 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001230 err_code |= ERR_ALERT;
1231 goto out;
1232 }
1233 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001234 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001235 err_code |= ERR_ALERT | ERR_FATAL;
1236 goto out;
1237 }
1238 global.sps_lim = atol(args[1]);
1239 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001240 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001241 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1242 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001243 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001244 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001245 err_code |= ERR_ALERT;
1246 goto out;
1247 }
1248 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001249 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001250 err_code |= ERR_ALERT | ERR_FATAL;
1251 goto out;
1252 }
1253 global.ssl_lim = atol(args[1]);
1254 }
William Lallemandd85f9172012-11-09 17:05:39 +01001255 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001256 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1257 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001258 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001259 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 +01001260 err_code |= ERR_ALERT | ERR_FATAL;
1261 goto out;
1262 }
1263 global.comp_rate_lim = atoi(args[1]) * 1024;
1264 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001265 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001266 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1267 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001268 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001269 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001270 err_code |= ERR_ALERT;
1271 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001272 }
1273 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001274 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001275 err_code |= ERR_ALERT | ERR_FATAL;
1276 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001277 }
1278 global.maxpipes = atol(args[1]);
1279 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001280 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001281 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1282 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001283 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001284 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001285 err_code |= ERR_ALERT | ERR_FATAL;
1286 goto out;
1287 }
William Lallemande3a7d992012-11-20 11:25:20 +01001288 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001289 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001290 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001291 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1292 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001293 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001294 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 +01001295 err_code |= ERR_ALERT | ERR_FATAL;
1296 goto out;
1297 }
1298 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001299 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001300 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 +01001301 err_code |= ERR_ALERT | ERR_FATAL;
1302 goto out;
1303 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001304 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001305
Willy Tarreaubaaee002006-06-26 02:48:02 +02001306 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001307 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1308 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001309 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001310 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001311 err_code |= ERR_ALERT;
1312 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001313 }
1314 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001315 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001316 err_code |= ERR_ALERT | ERR_FATAL;
1317 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001318 }
1319 global.rlimit_nofile = atol(args[1]);
1320 }
1321 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001322 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1323 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001324 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001325 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001326 err_code |= ERR_ALERT;
1327 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001328 }
1329 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001330 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001331 err_code |= ERR_ALERT | ERR_FATAL;
1332 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001333 }
1334 global.chroot = strdup(args[1]);
1335 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001336 else if (!strcmp(args[0], "description")) {
1337 int i, len=0;
1338 char *d;
1339
1340 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001341 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1342 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001343 err_code |= ERR_ALERT | ERR_FATAL;
1344 goto out;
1345 }
1346
Willy Tarreau348acfe2014-04-14 15:00:39 +02001347 for (i = 1; *args[i]; i++)
1348 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001349
1350 if (global.desc)
1351 free(global.desc);
1352
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001353 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001354
Willy Tarreau348acfe2014-04-14 15:00:39 +02001355 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1356 for (i = 2; *args[i]; i++)
1357 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001358 }
1359 else if (!strcmp(args[0], "node")) {
1360 int i;
1361 char c;
1362
William Lallemand1a748ae2015-05-19 16:37:23 +02001363 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1364 goto out;
1365
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001366 for (i=0; args[1][i]; i++) {
1367 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001368 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1369 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001370 break;
1371 }
1372
1373 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001374 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1375 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1376 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001377 err_code |= ERR_ALERT | ERR_FATAL;
1378 goto out;
1379 }
1380
1381 if (global.node)
1382 free(global.node);
1383
1384 global.node = strdup(args[1]);
1385 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001386 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001387 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1388 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001389 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001390 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001391 err_code |= ERR_ALERT;
1392 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001393 }
1394 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001395 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 +02001396 err_code |= ERR_ALERT | ERR_FATAL;
1397 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001398 }
1399 global.pidfile = strdup(args[1]);
1400 }
Emeric Bruned760922010-10-22 17:59:25 +02001401 else if (!strcmp(args[0], "unix-bind")) {
1402 int cur_arg = 1;
1403 while (*(args[cur_arg])) {
1404 if (!strcmp(args[cur_arg], "prefix")) {
1405 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001406 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001407 err_code |= ERR_ALERT;
1408 cur_arg += 2;
1409 continue;
1410 }
1411
1412 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001413 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 +02001414 err_code |= ERR_ALERT | ERR_FATAL;
1415 goto out;
1416 }
1417 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1418 cur_arg += 2;
1419 continue;
1420 }
1421
1422 if (!strcmp(args[cur_arg], "mode")) {
1423
1424 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1425 cur_arg += 2;
1426 continue;
1427 }
1428
1429 if (!strcmp(args[cur_arg], "uid")) {
1430
1431 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1432 cur_arg += 2;
1433 continue;
1434 }
1435
1436 if (!strcmp(args[cur_arg], "gid")) {
1437
1438 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1439 cur_arg += 2;
1440 continue;
1441 }
1442
1443 if (!strcmp(args[cur_arg], "user")) {
1444 struct passwd *user;
1445
1446 user = getpwnam(args[cur_arg + 1]);
1447 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001448 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1449 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001450 err_code |= ERR_ALERT | ERR_FATAL;
1451 goto out;
1452 }
1453
1454 global.unix_bind.ux.uid = user->pw_uid;
1455 cur_arg += 2;
1456 continue;
1457 }
1458
1459 if (!strcmp(args[cur_arg], "group")) {
1460 struct group *group;
1461
1462 group = getgrnam(args[cur_arg + 1]);
1463 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001464 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1465 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001466 err_code |= ERR_ALERT | ERR_FATAL;
1467 goto out;
1468 }
1469
1470 global.unix_bind.ux.gid = group->gr_gid;
1471 cur_arg += 2;
1472 continue;
1473 }
1474
Christopher Faulet767a84b2017-11-24 16:50:31 +01001475 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1476 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001477 err_code |= ERR_ALERT | ERR_FATAL;
1478 goto out;
1479 }
1480 }
William Lallemand0f99e342011-10-12 17:50:54 +02001481 else if (!strcmp(args[0], "log") && kwm == KWM_NO) { /* no log */
1482 /* delete previous herited or defined syslog servers */
1483 struct logsrv *back;
1484 struct logsrv *tmp;
1485
1486 if (*(args[1]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001487 ha_alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
William Lallemand0f99e342011-10-12 17:50:54 +02001488 err_code |= ERR_ALERT | ERR_FATAL;
1489 goto out;
1490 }
1491
1492 list_for_each_entry_safe(tmp, back, &global.logsrvs, list) {
1493 LIST_DEL(&tmp->list);
1494 free(tmp);
1495 }
1496 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001497 else if (!strcmp(args[0], "log")) { /* syslog server address */
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001498 struct sockaddr_storage *sk;
1499 int port1, port2;
William Lallemand0f99e342011-10-12 17:50:54 +02001500 struct logsrv *logsrv;
Willy Tarreau18324f52014-06-27 18:10:07 +02001501 int arg = 0;
1502 int len = 0;
William Lallemand0f99e342011-10-12 17:50:54 +02001503
William Lallemand1a748ae2015-05-19 16:37:23 +02001504 if (alertif_too_many_args(8, file, linenum, args, &err_code)) /* does not strictly check optional arguments */
1505 goto out;
1506
Willy Tarreaubaaee002006-06-26 02:48:02 +02001507 if (*(args[1]) == 0 || *(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001508 ha_alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001509 err_code |= ERR_ALERT | ERR_FATAL;
1510 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001511 }
William Lallemand0f99e342011-10-12 17:50:54 +02001512
Vincent Bernat02779b62016-04-03 13:48:43 +02001513 logsrv = calloc(1, sizeof(*logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02001514
Willy Tarreau18324f52014-06-27 18:10:07 +02001515 /* just after the address, a length may be specified */
1516 if (strcmp(args[arg+2], "len") == 0) {
1517 len = atoi(args[arg+3]);
1518 if (len < 80 || len > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001519 ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
1520 file, linenum, args[arg+3]);
Willy Tarreau18324f52014-06-27 18:10:07 +02001521 err_code |= ERR_ALERT | ERR_FATAL;
1522 goto out;
1523 }
1524 logsrv->maxlen = len;
1525
1526 /* skip these two args */
1527 arg += 2;
1528 }
1529 else
1530 logsrv->maxlen = MAX_SYSLOG_LEN;
1531
Christopher Faulet084aa962017-08-29 16:54:41 +02001532 if (logsrv->maxlen > global.max_syslog_len)
Willy Tarreau18324f52014-06-27 18:10:07 +02001533 global.max_syslog_len = logsrv->maxlen;
Willy Tarreau18324f52014-06-27 18:10:07 +02001534
Dragan Dosen1322d092015-09-22 16:05:32 +02001535 /* after the length, a format may be specified */
1536 if (strcmp(args[arg+2], "format") == 0) {
1537 logsrv->format = get_log_format(args[arg+3]);
1538 if (logsrv->format < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001539 ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
Dragan Dosen1322d092015-09-22 16:05:32 +02001540 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01001541 free(logsrv);
Dragan Dosen1322d092015-09-22 16:05:32 +02001542 goto out;
1543 }
1544
1545 /* skip these two args */
1546 arg += 2;
1547 }
1548
David Carlier97880bb2016-04-08 10:35:26 +01001549 if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code)) {
1550 free(logsrv);
William Lallemand1a748ae2015-05-19 16:37:23 +02001551 goto out;
David Carlier97880bb2016-04-08 10:35:26 +01001552 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001553
Willy Tarreau18324f52014-06-27 18:10:07 +02001554 logsrv->facility = get_log_facility(args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02001555 if (logsrv->facility < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001556 ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001557 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001558 logsrv->facility = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001559 }
1560
William Lallemand0f99e342011-10-12 17:50:54 +02001561 logsrv->level = 7; /* max syslog level = debug */
Willy Tarreau18324f52014-06-27 18:10:07 +02001562 if (*(args[arg+3])) {
1563 logsrv->level = get_log_level(args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02001564 if (logsrv->level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001565 ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001566 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001567 logsrv->level = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001568 }
1569 }
1570
William Lallemand0f99e342011-10-12 17:50:54 +02001571 logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
Willy Tarreau18324f52014-06-27 18:10:07 +02001572 if (*(args[arg+4])) {
1573 logsrv->minlvl = get_log_level(args[arg+4]);
William Lallemand0f99e342011-10-12 17:50:54 +02001574 if (logsrv->minlvl < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001575 ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001576 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001577 logsrv->minlvl = 0;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02001578 }
1579 }
1580
Willy Tarreau48ef4c92017-01-06 18:32:38 +01001581 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001582 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001583 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001584 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001585 free(logsrv);
1586 goto out;
1587 }
1588 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001589
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001590 if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001591 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001592 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
1593 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01001594 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemand0f99e342011-10-12 17:50:54 +02001595 free(logsrv);
Willy Tarreaud5191e72010-02-09 20:50:45 +01001596 goto out;
1597 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001598
William Lallemand0f99e342011-10-12 17:50:54 +02001599 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01001600 if (!port1)
William Lallemand0f99e342011-10-12 17:50:54 +02001601 set_host_port(&logsrv->addr, SYSLOG_PORT);
Robert Tsai81ae1952007-12-05 10:47:29 +01001602 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001603
William Lallemand0f99e342011-10-12 17:50:54 +02001604 LIST_ADDQ(&global.logsrvs, &logsrv->list);
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001605 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001606 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1607 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001608
1609 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001610 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001611 err_code |= ERR_ALERT;
1612 goto out;
1613 }
1614
1615 if (*(args[1]))
1616 name = args[1];
1617 else
1618 name = hostname;
1619
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001620 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001621 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001622 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001623 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1624 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001625 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001626 err_code |= ERR_ALERT;
1627 goto out;
1628 }
1629
1630 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001631 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001632 err_code |= ERR_FATAL;
1633 goto out;
1634 }
1635
1636 global.server_state_base = strdup(args[1]);
1637 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001638 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1639 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001640 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001641 err_code |= ERR_ALERT;
1642 goto out;
1643 }
1644
1645 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001646 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001647 err_code |= ERR_FATAL;
1648 goto out;
1649 }
1650
1651 global.server_state_file = strdup(args[1]);
1652 }
Kevinm48936af2010-12-22 16:08:21 +00001653 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001654 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1655 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001656 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001657 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001658 err_code |= ERR_ALERT | ERR_FATAL;
1659 goto out;
1660 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001661 chunk_destroy(&global.log_tag);
1662 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001663 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001664 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001665 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1666 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001667 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001668 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001669 err_code |= ERR_ALERT;
1670 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001671 }
1672 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001673 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001674 err_code |= ERR_ALERT | ERR_FATAL;
1675 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001676 }
1677 global.spread_checks = atol(args[1]);
1678 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001679 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 +02001680 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001681 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001682 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001683 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1684 const char *err;
1685 unsigned int val;
1686
William Lallemand1a748ae2015-05-19 16:37:23 +02001687 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1688 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001689 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001690 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001691 err_code |= ERR_ALERT | ERR_FATAL;
1692 goto out;
1693 }
1694
1695 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1696 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001697 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 +02001698 err_code |= ERR_ALERT | ERR_FATAL;
1699 }
1700 global.max_spread_checks = val;
1701 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001702 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001703 err_code |= ERR_ALERT | ERR_FATAL;
1704 }
1705 }
Christopher Faulet62519022017-10-16 15:49:32 +02001706 else if (strcmp(args[0], "cpu-map") == 0) {
1707 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001708#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001709 char *slash;
1710 unsigned long proc = 0, thread = 0, cpus;
1711 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001712
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001713 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001714 ha_alert("parsing [%s:%d] : %s expects a process number "
1715 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1716 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1717 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001718 err_code |= ERR_ALERT | ERR_FATAL;
1719 goto out;
1720 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001721
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001722 if ((slash = strchr(args[1], '/')) != NULL)
1723 *slash = 0;
1724
Christopher Faulet26028f62017-11-22 15:01:51 +01001725 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001726 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001727 err_code |= ERR_ALERT | ERR_FATAL;
1728 goto out;
1729 }
1730
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001731 if (slash) {
1732 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001733 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001734 err_code |= ERR_ALERT | ERR_FATAL;
1735 goto out;
1736 }
1737 *slash = '/';
1738
1739 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001740 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1741 "a process range _AND_ a thread range\n",
1742 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001743 err_code |= ERR_ALERT | ERR_FATAL;
1744 goto out;
1745 }
1746 }
1747
Christopher Faulet62519022017-10-16 15:49:32 +02001748 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001749 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001750 err_code |= ERR_ALERT | ERR_FATAL;
1751 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001752 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001753
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001754 if (autoinc &&
1755 my_popcountl(proc) != my_popcountl(cpus) &&
1756 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001757 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1758 "must have the same size to be automatically bound\n",
1759 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001760 err_code |= ERR_ALERT | ERR_FATAL;
1761 goto out;
1762 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001763
Christopher Faulet26028f62017-11-22 15:01:51 +01001764 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001765 /* No mapping for this process */
1766 if (!(proc & (1UL << i)))
1767 continue;
1768
1769 /* Mapping at the process level */
1770 if (!thread) {
1771 if (!autoinc)
1772 global.cpu_map.proc[i] = cpus;
1773 else {
1774 n += my_ffsl(cpus >> n);
1775 global.cpu_map.proc[i] = (1UL << (n-1));
1776 }
1777 continue;
1778 }
1779
1780 /* Mapping at the thread level */
1781 for (j = 0; j < LONGBITS; j++) {
1782 /* Np mapping for this thread */
1783 if (!(thread & (1UL << j)))
1784 continue;
1785
1786 if (!autoinc)
1787 global.cpu_map.thread[i][j] = cpus;
1788 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001789 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001790 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001791 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001792 }
1793 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001794#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001795 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1796 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001797 err_code |= ERR_ALERT | ERR_FATAL;
1798 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001799#endif /* ! USE_CPU_AFFINITY */
1800 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001801 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1802 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1803 goto out;
1804
1805 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001806 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001807 err_code |= ERR_ALERT | ERR_FATAL;
1808 goto out;
1809 }
1810
1811 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1812 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001813 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 +01001814 err_code |= ERR_ALERT | ERR_FATAL;
1815 goto out;
1816 }
1817 }
1818 else if (!strcmp(args[0], "unsetenv")) {
1819 int arg;
1820
1821 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001822 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001823 err_code |= ERR_ALERT | ERR_FATAL;
1824 goto out;
1825 }
1826
1827 for (arg = 1; *args[arg]; arg++) {
1828 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001829 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 +01001830 err_code |= ERR_ALERT | ERR_FATAL;
1831 goto out;
1832 }
1833 }
1834 }
1835 else if (!strcmp(args[0], "resetenv")) {
1836 extern char **environ;
1837 char **env = environ;
1838
1839 /* args contain variable names to keep, one per argument */
1840 while (*env) {
1841 int arg;
1842
1843 /* look for current variable in among all those we want to keep */
1844 for (arg = 1; *args[arg]; arg++) {
1845 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1846 (*env)[strlen(args[arg])] == '=')
1847 break;
1848 }
1849
1850 /* delete this variable */
1851 if (!*args[arg]) {
1852 char *delim = strchr(*env, '=');
1853
1854 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001855 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 +01001856 err_code |= ERR_ALERT | ERR_FATAL;
1857 goto out;
1858 }
1859
1860 memcpy(trash.str, *env, delim - *env);
1861 trash.str[delim - *env] = 0;
1862
1863 if (unsetenv(trash.str) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001864 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 +01001865 err_code |= ERR_ALERT | ERR_FATAL;
1866 goto out;
1867 }
1868 }
1869 else
1870 env++;
1871 }
1872 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001873 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001874 struct cfg_kw_list *kwl;
1875 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001876 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001877
1878 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1879 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1880 if (kwl->kw[index].section != CFG_GLOBAL)
1881 continue;
1882 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001883 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001884 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001885 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001886 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001887 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001888 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001889 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001890 err_code |= ERR_WARN;
1891 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001892 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001893 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001894 }
1895 }
1896 }
1897
Christopher Faulet767a84b2017-11-24 16:50:31 +01001898 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001899 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001900 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001901
Willy Tarreau058e9072009-07-20 09:30:05 +02001902 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001903 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001904 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001905}
1906
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001907void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001908{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001909 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001910 defproxy.mode = PR_MODE_TCP;
1911 defproxy.state = PR_STNEW;
1912 defproxy.maxconn = cfg_maxpconn;
1913 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001914 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001915 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001916
Simon Horman66183002013-02-23 10:16:43 +09001917 defproxy.defsrv.check.inter = DEF_CHKINTR;
1918 defproxy.defsrv.check.fastinter = 0;
1919 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001920 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1921 defproxy.defsrv.agent.fastinter = 0;
1922 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001923 defproxy.defsrv.check.rise = DEF_RISETIME;
1924 defproxy.defsrv.check.fall = DEF_FALLTIME;
1925 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1926 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001927 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001928 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001929 defproxy.defsrv.maxqueue = 0;
1930 defproxy.defsrv.minconn = 0;
1931 defproxy.defsrv.maxconn = 0;
1932 defproxy.defsrv.slowstart = 0;
1933 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1934 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1935 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001936
1937 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001938 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001939}
1940
Willy Tarreauade5ec42010-01-28 19:33:49 +01001941
Willy Tarreau63af98d2014-05-18 08:11:41 +02001942/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1943 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1944 * ERR_FATAL in case of error.
1945 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001946static int create_cond_regex_rule(const char *file, int line,
1947 struct proxy *px, int dir, int action, int flags,
1948 const char *cmd, const char *reg, const char *repl,
1949 const char **cond_start)
1950{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001951 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001952 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001953 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001954 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001955 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001956 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001957 int cs;
1958 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001959
1960 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001961 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001962 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001963 goto err;
1964 }
1965
1966 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001967 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001968 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001969 goto err;
1970 }
1971
Christopher Faulet898566e2016-10-26 11:06:28 +02001972 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001973 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001974
Willy Tarreau5321c422010-01-28 20:35:13 +01001975 if (cond_start &&
1976 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001977 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001978 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1979 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001980 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001981 goto err;
1982 }
1983 }
1984 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001985 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1986 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001987 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001988 goto err;
1989 }
1990
Willy Tarreau63af98d2014-05-18 08:11:41 +02001991 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001992 (dir == SMP_OPT_DIR_REQ) ?
1993 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1994 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1995 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001996
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001997 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001998 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001999 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002000 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002001 goto err;
2002 }
2003
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002004 cs = !(flags & REG_ICASE);
2005 cap = !(flags & REG_NOSUB);
2006 error = NULL;
2007 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002008 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002009 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002010 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002011 goto err;
2012 }
2013
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02002014 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01002015 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01002016 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002017 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
2018 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002019 ret_code |= ERR_ALERT | ERR_FATAL;
2020 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002021 }
2022
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02002023 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02002024 ret_code |= ERR_WARN;
2025
2026 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002027
Willy Tarreau63af98d2014-05-18 08:11:41 +02002028 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002029 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01002030 err:
2031 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02002032 free(errmsg);
2033 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01002034}
2035
Willy Tarreaubaaee002006-06-26 02:48:02 +02002036/*
William Lallemand51097192015-04-14 16:35:22 +02002037 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02002038 * Returns the error code, 0 if OK, or any combination of :
2039 * - ERR_ABORT: must abort ASAP
2040 * - ERR_FATAL: we can continue parsing but not start the service
2041 * - ERR_WARN: a warning has been emitted
2042 * - ERR_ALERT: an alert has been emitted
2043 * Only the two first ones can stop processing, the two others are just
2044 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02002045 */
Emeric Brun32da3c42010-09-23 18:39:19 +02002046int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
2047{
2048 static struct peers *curpeers = NULL;
2049 struct peer *newpeer = NULL;
2050 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002051 struct bind_conf *bind_conf;
2052 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02002053 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01002054 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002055
2056 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002057 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002058 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01002059 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002060 goto out;
2061 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002062
William Lallemand6e62fb62015-04-28 16:55:23 +02002063 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2064 goto out;
2065
Emeric Brun32da3c42010-09-23 18:39:19 +02002066 err = invalid_char(args[1]);
2067 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002068 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2069 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01002070 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01002071 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002072 }
2073
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002074 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02002075 /*
2076 * If there are two proxies with the same name only following
2077 * combinations are allowed:
2078 */
2079 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002080 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
2081 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002082 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02002083 }
2084 }
2085
Vincent Bernat02779b62016-04-03 13:48:43 +02002086 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002087 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002088 err_code |= ERR_ALERT | ERR_ABORT;
2089 goto out;
2090 }
2091
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002092 curpeers->next = cfg_peers;
2093 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002094 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002095 curpeers->conf.line = linenum;
2096 curpeers->last_change = now.tv_sec;
2097 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002098 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002099 }
2100 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002101 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002102 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002103 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002104
2105 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002106 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2107 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002108 err_code |= ERR_ALERT | ERR_FATAL;
2109 goto out;
2110 }
2111
2112 err = invalid_char(args[1]);
2113 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002114 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2115 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002116 err_code |= ERR_ALERT | ERR_FATAL;
2117 goto out;
2118 }
2119
Vincent Bernat02779b62016-04-03 13:48:43 +02002120 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002121 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002122 err_code |= ERR_ALERT | ERR_ABORT;
2123 goto out;
2124 }
2125
2126 /* the peers are linked backwards first */
2127 curpeers->count++;
2128 newpeer->next = curpeers->remote;
2129 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002130 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002131 newpeer->conf.line = linenum;
2132
2133 newpeer->last_change = now.tv_sec;
2134 newpeer->id = strdup(args[1]);
2135
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002136 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002137 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002138 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002139 err_code |= ERR_ALERT | ERR_FATAL;
2140 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002141 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002142
2143 proto = protocol_by_family(sk->ss_family);
2144 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002145 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2146 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002147 err_code |= ERR_ALERT | ERR_FATAL;
2148 goto out;
2149 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002150
2151 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002152 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2153 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002154 err_code |= ERR_ALERT | ERR_FATAL;
2155 goto out;
2156 }
2157
Willy Tarreau2aa38802013-02-20 19:20:59 +01002158 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002159 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2160 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002161 err_code |= ERR_ALERT | ERR_FATAL;
2162 goto out;
2163 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002164
Emeric Brun32da3c42010-09-23 18:39:19 +02002165 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002166 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002167 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002168 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002169 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002170
Emeric Brun32da3c42010-09-23 18:39:19 +02002171 if (strcmp(newpeer->id, localpeer) == 0) {
2172 /* Current is local peer, it define a frontend */
2173 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002174 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002175
2176 if (!curpeers->peers_fe) {
2177 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002178 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002179 err_code |= ERR_ALERT | ERR_ABORT;
2180 goto out;
2181 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002182
Willy Tarreau237250c2011-07-29 01:49:03 +02002183 init_new_proxy(curpeers->peers_fe);
2184 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002185 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002186 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2187 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002188 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002189
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002190 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002191
Willy Tarreau902636f2013-03-10 19:44:48 +01002192 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2193 if (errmsg && *errmsg) {
2194 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002195 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002196 }
2197 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002198 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2199 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002200 err_code |= ERR_FATAL;
2201 goto out;
2202 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002203
2204 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002205 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002206 l->maxconn = curpeers->peers_fe->maxconn;
2207 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002208 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002209 l->analysers |= curpeers->peers_fe->fe_req_ana;
2210 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002211 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2212 global.maxsock += l->maxconn;
2213 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002214 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002215 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002216 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2217 file, linenum, args[0], args[1],
2218 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002219 err_code |= ERR_FATAL;
2220 goto out;
2221 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002222 }
2223 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002224 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2225 curpeers->state = PR_STSTOPPED;
2226 }
2227 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2228 curpeers->state = PR_STNEW;
2229 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002230 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002231 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002232 err_code |= ERR_ALERT | ERR_FATAL;
2233 goto out;
2234 }
2235
2236out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002237 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002238 return err_code;
2239}
2240
Baptiste Assmann325137d2015-04-13 23:40:55 +02002241/*
2242 * Parse a <resolvers> section.
2243 * Returns the error code, 0 if OK, or any combination of :
2244 * - ERR_ABORT: must abort ASAP
2245 * - ERR_FATAL: we can continue parsing but not start the service
2246 * - ERR_WARN: a warning has been emitted
2247 * - ERR_ALERT: an alert has been emitted
2248 * Only the two first ones can stop processing, the two others are just
2249 * indicators.
2250 */
2251int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2252{
2253 static struct dns_resolvers *curr_resolvers = NULL;
2254 struct dns_nameserver *newnameserver = NULL;
2255 const char *err;
2256 int err_code = 0;
2257 char *errmsg = NULL;
2258
2259 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2260 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002261 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002262 err_code |= ERR_ALERT | ERR_ABORT;
2263 goto out;
2264 }
2265
2266 err = invalid_char(args[1]);
2267 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002268 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2269 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002270 err_code |= ERR_ALERT | ERR_ABORT;
2271 goto out;
2272 }
2273
2274 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2275 /* Error if two resolvers owns the same name */
2276 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002277 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2278 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002279 err_code |= ERR_ALERT | ERR_ABORT;
2280 }
2281 }
2282
Vincent Bernat02779b62016-04-03 13:48:43 +02002283 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002284 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002285 err_code |= ERR_ALERT | ERR_ABORT;
2286 goto out;
2287 }
2288
2289 /* default values */
2290 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2291 curr_resolvers->conf.file = strdup(file);
2292 curr_resolvers->conf.line = linenum;
2293 curr_resolvers->id = strdup(args[1]);
2294 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002295 /* default maximum response size */
2296 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002297 /* default hold period for nx, other, refuse and timeout is 30s */
2298 curr_resolvers->hold.nx = 30000;
2299 curr_resolvers->hold.other = 30000;
2300 curr_resolvers->hold.refused = 30000;
2301 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002302 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002303 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002304 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002305 curr_resolvers->timeout.resolve = 1000;
2306 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002307 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002308 curr_resolvers->nb_nameservers = 0;
2309 LIST_INIT(&curr_resolvers->nameservers);
2310 LIST_INIT(&curr_resolvers->resolutions.curr);
2311 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002312 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002313 }
2314 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2315 struct sockaddr_storage *sk;
2316 int port1, port2;
2317 struct protocol *proto;
2318
2319 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002320 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2321 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002322 err_code |= ERR_ALERT | ERR_FATAL;
2323 goto out;
2324 }
2325
2326 err = invalid_char(args[1]);
2327 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002328 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2329 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002330 err_code |= ERR_ALERT | ERR_FATAL;
2331 goto out;
2332 }
2333
Christopher Faulet67957bd2017-09-27 11:00:59 +02002334 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002335 /* Error if two resolvers owns the same name */
2336 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002337 ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
2338 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002339 err_code |= ERR_ALERT | ERR_FATAL;
2340 }
2341 }
2342
Vincent Bernat02779b62016-04-03 13:48:43 +02002343 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002344 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002345 err_code |= ERR_ALERT | ERR_ABORT;
2346 goto out;
2347 }
2348
2349 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002350 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002351 newnameserver->resolvers = curr_resolvers;
2352 newnameserver->conf.file = strdup(file);
2353 newnameserver->conf.line = linenum;
2354 newnameserver->id = strdup(args[1]);
2355
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002356 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002357 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002358 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002359 err_code |= ERR_ALERT | ERR_FATAL;
2360 goto out;
2361 }
2362
2363 proto = protocol_by_family(sk->ss_family);
2364 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002365 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002366 file, linenum, args[0], args[1]);
2367 err_code |= ERR_ALERT | ERR_FATAL;
2368 goto out;
2369 }
2370
2371 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002372 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2373 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002374 err_code |= ERR_ALERT | ERR_FATAL;
2375 goto out;
2376 }
2377
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002378 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002379 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2380 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002381 err_code |= ERR_ALERT | ERR_FATAL;
2382 goto out;
2383 }
2384
Baptiste Assmann325137d2015-04-13 23:40:55 +02002385 newnameserver->addr = *sk;
2386 }
2387 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2388 const char *res;
2389 unsigned int time;
2390
2391 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002392 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2393 file, linenum, args[0]);
2394 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002395 err_code |= ERR_ALERT | ERR_FATAL;
2396 goto out;
2397 }
2398 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2399 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002400 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2401 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002402 err_code |= ERR_ALERT | ERR_FATAL;
2403 goto out;
2404 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002405 if (strcmp(args[1], "nx") == 0)
2406 curr_resolvers->hold.nx = time;
2407 else if (strcmp(args[1], "other") == 0)
2408 curr_resolvers->hold.other = time;
2409 else if (strcmp(args[1], "refused") == 0)
2410 curr_resolvers->hold.refused = time;
2411 else if (strcmp(args[1], "timeout") == 0)
2412 curr_resolvers->hold.timeout = time;
2413 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002414 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002415 else if (strcmp(args[1], "obsolete") == 0)
2416 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002417 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002418 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2419 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002420 err_code |= ERR_ALERT | ERR_FATAL;
2421 goto out;
2422 }
2423
2424 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002425 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002426 int i = 0;
2427
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002428 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002429 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2430 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002431 err_code |= ERR_ALERT | ERR_FATAL;
2432 goto out;
2433 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002434
2435 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002436 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002437 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2438 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002439 err_code |= ERR_ALERT | ERR_FATAL;
2440 goto out;
2441 }
2442
2443 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002444 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002445 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002446 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2447 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002448 err_code |= ERR_WARN;
2449 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002450 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002451 else if (strcmp(args[0], "resolve_retries") == 0) {
2452 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002453 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2454 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002455 err_code |= ERR_ALERT | ERR_FATAL;
2456 goto out;
2457 }
2458 curr_resolvers->resolve_retries = atoi(args[1]);
2459 }
2460 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002461 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002462 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2463 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002464 err_code |= ERR_ALERT | ERR_FATAL;
2465 goto out;
2466 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002467 else if (strcmp(args[1], "retry") == 0 ||
2468 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002469 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002470 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002471
2472 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002473 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2474 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002475 err_code |= ERR_ALERT | ERR_FATAL;
2476 goto out;
2477 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002478 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002479 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002480 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2481 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002482 err_code |= ERR_ALERT | ERR_FATAL;
2483 goto out;
2484 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002485 if (args[1][2] == 't')
2486 curr_resolvers->timeout.retry = tout;
2487 else
2488 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002489 }
2490 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002491 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2492 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002493 err_code |= ERR_ALERT | ERR_FATAL;
2494 goto out;
2495 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002496 } /* neither "nameserver" nor "resolvers" */
2497 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002498 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002499 err_code |= ERR_ALERT | ERR_FATAL;
2500 goto out;
2501 }
2502
2503 out:
2504 free(errmsg);
2505 return err_code;
2506}
Simon Horman0d16a402015-01-30 11:22:58 +09002507
2508/*
William Lallemand51097192015-04-14 16:35:22 +02002509 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002510 * Returns the error code, 0 if OK, or any combination of :
2511 * - ERR_ABORT: must abort ASAP
2512 * - ERR_FATAL: we can continue parsing but not start the service
2513 * - ERR_WARN: a warning has been emitted
2514 * - ERR_ALERT: an alert has been emitted
2515 * Only the two first ones can stop processing, the two others are just
2516 * indicators.
2517 */
2518int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2519{
2520 static struct mailers *curmailers = NULL;
2521 struct mailer *newmailer = NULL;
2522 const char *err;
2523 int err_code = 0;
2524 char *errmsg = NULL;
2525
2526 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2527 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002528 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002529 err_code |= ERR_ALERT | ERR_ABORT;
2530 goto out;
2531 }
2532
2533 err = invalid_char(args[1]);
2534 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002535 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2536 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002537 err_code |= ERR_ALERT | ERR_ABORT;
2538 goto out;
2539 }
2540
2541 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2542 /*
2543 * If there are two proxies with the same name only following
2544 * combinations are allowed:
2545 */
2546 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002547 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2548 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002549 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002550 }
2551 }
2552
Vincent Bernat02779b62016-04-03 13:48:43 +02002553 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002554 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002555 err_code |= ERR_ALERT | ERR_ABORT;
2556 goto out;
2557 }
2558
2559 curmailers->next = mailers;
2560 mailers = curmailers;
2561 curmailers->conf.file = strdup(file);
2562 curmailers->conf.line = linenum;
2563 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002564 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2565 * But need enough time so that timeouts don't occur
2566 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002567 }
2568 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2569 struct sockaddr_storage *sk;
2570 int port1, port2;
2571 struct protocol *proto;
2572
2573 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002574 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2575 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002576 err_code |= ERR_ALERT | ERR_FATAL;
2577 goto out;
2578 }
2579
2580 err = invalid_char(args[1]);
2581 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002582 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2583 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002584 err_code |= ERR_ALERT | ERR_FATAL;
2585 goto out;
2586 }
2587
Vincent Bernat02779b62016-04-03 13:48:43 +02002588 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002589 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002590 err_code |= ERR_ALERT | ERR_ABORT;
2591 goto out;
2592 }
2593
2594 /* the mailers are linked backwards first */
2595 curmailers->count++;
2596 newmailer->next = curmailers->mailer_list;
2597 curmailers->mailer_list = newmailer;
2598 newmailer->mailers = curmailers;
2599 newmailer->conf.file = strdup(file);
2600 newmailer->conf.line = linenum;
2601
2602 newmailer->id = strdup(args[1]);
2603
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002604 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002605 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002606 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002607 err_code |= ERR_ALERT | ERR_FATAL;
2608 goto out;
2609 }
2610
2611 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002612 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002613 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2614 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002615 err_code |= ERR_ALERT | ERR_FATAL;
2616 goto out;
2617 }
2618
2619 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002620 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2621 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002622 err_code |= ERR_ALERT | ERR_FATAL;
2623 goto out;
2624 }
2625
2626 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002627 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2628 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002629 err_code |= ERR_ALERT | ERR_FATAL;
2630 goto out;
2631 }
2632
2633 newmailer->addr = *sk;
2634 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002635 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002636 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002637 }
2638 else if (strcmp(args[0], "timeout") == 0) {
2639 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002640 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2641 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002642 err_code |= ERR_ALERT | ERR_FATAL;
2643 goto out;
2644 }
2645 else if (strcmp(args[1], "mail") == 0) {
2646 const char *res;
2647 unsigned int timeout_mail;
2648 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002649 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2650 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002651 err_code |= ERR_ALERT | ERR_FATAL;
2652 goto out;
2653 }
2654 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2655 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002656 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2657 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002658 err_code |= ERR_ALERT | ERR_FATAL;
2659 goto out;
2660 }
2661 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002662 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 +01002663 err_code |= ERR_ALERT | ERR_FATAL;
2664 goto out;
2665 }
2666 curmailers->timeout.mail = timeout_mail;
2667 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002668 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002669 file, linenum, args[0], args[1]);
2670 err_code |= ERR_ALERT | ERR_FATAL;
2671 goto out;
2672 }
2673 }
Simon Horman0d16a402015-01-30 11:22:58 +09002674 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002675 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002676 err_code |= ERR_ALERT | ERR_FATAL;
2677 goto out;
2678 }
2679
2680out:
2681 free(errmsg);
2682 return err_code;
2683}
2684
Simon Horman9dc49962015-01-30 11:22:59 +09002685static void free_email_alert(struct proxy *p)
2686{
2687 free(p->email_alert.mailers.name);
2688 p->email_alert.mailers.name = NULL;
2689 free(p->email_alert.from);
2690 p->email_alert.from = NULL;
2691 free(p->email_alert.to);
2692 p->email_alert.to = NULL;
2693 free(p->email_alert.myhostname);
2694 p->email_alert.myhostname = NULL;
2695}
2696
Willy Tarreau3842f002009-06-14 11:39:52 +02002697int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002698{
2699 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002700 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002701 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002702 int rc;
2703 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002704 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002705 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002706 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002707 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002708 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002709
Willy Tarreau977b8e42006-12-29 14:19:17 +01002710 if (!strcmp(args[0], "listen"))
2711 rc = PR_CAP_LISTEN;
2712 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002713 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002714 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002715 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002716 else
2717 rc = PR_CAP_NONE;
2718
2719 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002720 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002721 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2722 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2723 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002724 err_code |= ERR_ALERT | ERR_ABORT;
2725 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002726 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002727
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002728 err = invalid_char(args[1]);
2729 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002730 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2731 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002732 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002733 }
2734
Willy Tarreau8f50b682015-05-26 11:45:02 +02002735 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2736 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002737 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2738 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2739 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002740 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002741 }
2742
Vincent Bernat02779b62016-04-03 13:48:43 +02002743 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002744 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002745 err_code |= ERR_ALERT | ERR_ABORT;
2746 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002747 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002748
Willy Tarreau97cb7802010-01-03 20:23:58 +01002749 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002750 curproxy->next = proxies_list;
2751 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002752 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2753 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002754 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002755 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002756 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002757 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002758
William Lallemand6e62fb62015-04-28 16:55:23 +02002759 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2760 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002761 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002762 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002763 }
2764
2765 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002766 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002767 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002768
Willy Tarreaubaaee002006-06-26 02:48:02 +02002769 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002770 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002771 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002772 curproxy->no_options = defproxy.no_options;
2773 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002774 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002775 curproxy->except_net = defproxy.except_net;
2776 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002777 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002778 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002779
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002780 if (defproxy.fwdfor_hdr_len) {
2781 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2782 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2783 }
2784
Willy Tarreaub86db342009-11-30 11:50:16 +01002785 if (defproxy.orgto_hdr_len) {
2786 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2787 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2788 }
2789
Mark Lamourinec2247f02012-01-04 13:02:01 -05002790 if (defproxy.server_id_hdr_len) {
2791 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2792 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2793 }
2794
Willy Tarreau977b8e42006-12-29 14:19:17 +01002795 if (curproxy->cap & PR_CAP_FE) {
2796 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002797 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002798 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002799
2800 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002801 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2802 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002803
2804 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2805 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002806
Willy Tarreau977b8e42006-12-29 14:19:17 +01002807 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002808 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002809 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002810 curproxy->fullconn = defproxy.fullconn;
2811 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002812 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002813 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002814
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002815 if (defproxy.check_req) {
2816 curproxy->check_req = calloc(1, defproxy.check_len);
2817 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2818 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002819 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002820
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002821 if (defproxy.expect_str) {
2822 curproxy->expect_str = strdup(defproxy.expect_str);
2823 if (defproxy.expect_regex) {
2824 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002825 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2826 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002827 }
2828 }
2829
Willy Tarreau67402132012-05-31 20:40:20 +02002830 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002831 if (defproxy.cookie_name)
2832 curproxy->cookie_name = strdup(defproxy.cookie_name);
2833 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002834
2835 if (defproxy.dyncookie_key)
2836 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002837 if (defproxy.cookie_domain)
2838 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002839
Willy Tarreau31936852010-10-06 16:59:56 +02002840 if (defproxy.cookie_maxidle)
2841 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2842
2843 if (defproxy.cookie_maxlife)
2844 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2845
Emeric Brun647caf12009-06-30 17:57:00 +02002846 if (defproxy.rdp_cookie_name)
2847 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2848 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2849
Willy Tarreau01732802007-11-01 22:48:15 +01002850 if (defproxy.url_param_name)
2851 curproxy->url_param_name = strdup(defproxy.url_param_name);
2852 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002853
Benoitaffb4812009-03-25 13:02:10 +01002854 if (defproxy.hh_name)
2855 curproxy->hh_name = strdup(defproxy.hh_name);
2856 curproxy->hh_len = defproxy.hh_len;
2857 curproxy->hh_match_domain = defproxy.hh_match_domain;
2858
Willy Tarreauef9a3602012-12-08 22:29:20 +01002859 if (defproxy.conn_src.iface_name)
2860 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2861 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002862 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002863#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002864 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002865#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002866 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002867 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002868
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002869 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002870 if (defproxy.capture_name)
2871 curproxy->capture_name = strdup(defproxy.capture_name);
2872 curproxy->capture_namelen = defproxy.capture_namelen;
2873 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002874 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002875
Willy Tarreau977b8e42006-12-29 14:19:17 +01002876 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002877 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002878 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002879 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002880 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002881 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002882 curproxy->mon_net = defproxy.mon_net;
2883 curproxy->mon_mask = defproxy.mon_mask;
2884 if (defproxy.monitor_uri)
2885 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2886 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002887 if (defproxy.defbe.name)
2888 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002889
2890 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002891 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2892 if (curproxy->conf.logformat_string &&
2893 curproxy->conf.logformat_string != default_http_log_format &&
2894 curproxy->conf.logformat_string != default_tcp_log_format &&
2895 curproxy->conf.logformat_string != clf_http_log_format)
2896 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2897
2898 if (defproxy.conf.lfs_file) {
2899 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2900 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2901 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002902
2903 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2904 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2905 if (curproxy->conf.logformat_sd_string &&
2906 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2907 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2908
2909 if (defproxy.conf.lfsd_file) {
2910 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2911 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2912 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002913 }
2914
2915 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002916 curproxy->timeout.connect = defproxy.timeout.connect;
2917 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002918 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002919 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002920 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002921 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002922 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002923 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002924 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002925 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002926 }
2927
Willy Tarreaubaaee002006-06-26 02:48:02 +02002928 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002929 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002930
2931 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002932 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002933 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002934 memcpy(node, tmplogsrv, sizeof(struct logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02002935 LIST_INIT(&node->list);
2936 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2937 }
2938
Willy Tarreau62a61232013-04-12 18:13:46 +02002939 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2940 if (curproxy->conf.uniqueid_format_string)
2941 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2942
Dragan Dosen43885c72015-10-01 13:18:13 +02002943 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002944
Willy Tarreau62a61232013-04-12 18:13:46 +02002945 if (defproxy.conf.uif_file) {
2946 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2947 curproxy->conf.uif_line = defproxy.conf.uif_line;
2948 }
William Lallemanda73203e2012-03-12 12:48:57 +01002949
2950 /* copy default header unique id */
2951 if (defproxy.header_unique_id)
2952 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2953
William Lallemand82fe75c2012-10-23 10:25:10 +02002954 /* default compression options */
2955 if (defproxy.comp != NULL) {
2956 curproxy->comp = calloc(1, sizeof(struct comp));
2957 curproxy->comp->algos = defproxy.comp->algos;
2958 curproxy->comp->types = defproxy.comp->types;
2959 }
2960
Willy Tarreaubaaee002006-06-26 02:48:02 +02002961 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002962 curproxy->conf.used_listener_id = EB_ROOT;
2963 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002964
Simon Horman98637e52014-06-20 12:30:16 +09002965 if (defproxy.check_path)
2966 curproxy->check_path = strdup(defproxy.check_path);
2967 if (defproxy.check_command)
2968 curproxy->check_command = strdup(defproxy.check_command);
2969
Simon Horman9dc49962015-01-30 11:22:59 +09002970 if (defproxy.email_alert.mailers.name)
2971 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
2972 if (defproxy.email_alert.from)
2973 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
2974 if (defproxy.email_alert.to)
2975 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
2976 if (defproxy.email_alert.myhostname)
2977 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09002978 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01002979 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09002980
Willy Tarreau93893792009-07-23 13:19:11 +02002981 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002982 }
2983 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
2984 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002985 /* FIXME-20070101: we should do this too at the end of the
2986 * config parsing to free all default values.
2987 */
William Lallemand6e62fb62015-04-28 16:55:23 +02002988 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2989 err_code |= ERR_ABORT;
2990 goto out;
2991 }
2992
Willy Tarreaua534fea2008-08-03 12:19:50 +02002993 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09002994 free(defproxy.check_command);
2995 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02002996 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02002997 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01002998 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002999 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003000 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003001 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003002 free(defproxy.capture_name);
3003 free(defproxy.monitor_uri);
3004 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003005 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003006 free(defproxy.fwdfor_hdr_name);
3007 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003008 free(defproxy.orgto_hdr_name);
3009 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003010 free(defproxy.server_id_hdr_name);
3011 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003012 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003013 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003014 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003015 free(defproxy.expect_regex);
3016 defproxy.expect_regex = NULL;
3017 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003018
Willy Tarreau62a61232013-04-12 18:13:46 +02003019 if (defproxy.conf.logformat_string != default_http_log_format &&
3020 defproxy.conf.logformat_string != default_tcp_log_format &&
3021 defproxy.conf.logformat_string != clf_http_log_format)
3022 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003023
Willy Tarreau62a61232013-04-12 18:13:46 +02003024 free(defproxy.conf.uniqueid_format_string);
3025 free(defproxy.conf.lfs_file);
3026 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003027 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003028 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003029
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003030 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3031 free(defproxy.conf.logformat_sd_string);
3032 free(defproxy.conf.lfsd_file);
3033
Willy Tarreaua534fea2008-08-03 12:19:50 +02003034 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003035 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003036
Willy Tarreaubaaee002006-06-26 02:48:02 +02003037 /* we cannot free uri_auth because it might already be used */
3038 init_default_instance();
3039 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003040 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3041 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003042 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003043 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003044 }
3045 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003046 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003047 err_code |= ERR_ALERT | ERR_FATAL;
3048 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003049 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003050
3051 /* update the current file and line being parsed */
3052 curproxy->conf.args.file = curproxy->conf.file;
3053 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003054
3055 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003056 if (!strcmp(args[0], "server") ||
3057 !strcmp(args[0], "default-server") ||
3058 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003059 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3060 if (err_code & ERR_FATAL)
3061 goto out;
3062 }
3063 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003064 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003065 int cur_arg;
3066
Willy Tarreaubaaee002006-06-26 02:48:02 +02003067 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003068 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003069 err_code |= ERR_ALERT | ERR_FATAL;
3070 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003071 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003072 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003073 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003074
Willy Tarreau24709282013-03-10 21:32:12 +01003075 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003076 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3077 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003078 err_code |= ERR_ALERT | ERR_FATAL;
3079 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003080 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003081
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003082 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003083
3084 /* use default settings for unix sockets */
3085 bind_conf->ux.uid = global.unix_bind.ux.uid;
3086 bind_conf->ux.gid = global.unix_bind.ux.gid;
3087 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003088
3089 /* NOTE: the following line might create several listeners if there
3090 * are comma-separated IPs or port ranges. So all further processing
3091 * will have to be applied to all listeners created after last_listen.
3092 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003093 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3094 if (errmsg && *errmsg) {
3095 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003096 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003097 }
3098 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003099 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3100 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003101 err_code |= ERR_ALERT | ERR_FATAL;
3102 goto out;
3103 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003104
Willy Tarreau4348fad2012-09-20 16:48:07 +02003105 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3106 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003107 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003108 }
3109
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003110 cur_arg = 2;
3111 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003112 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003113 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003114 char *err;
3115
Willy Tarreau26982662012-09-12 23:17:10 +02003116 kw = bind_find_kw(args[cur_arg]);
3117 if (kw) {
3118 char *err = NULL;
3119 int code;
3120
3121 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003122 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3123 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003124 cur_arg += 1 + kw->skip ;
3125 err_code |= ERR_ALERT | ERR_FATAL;
3126 goto out;
3127 }
3128
Willy Tarreau4348fad2012-09-20 16:48:07 +02003129 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003130 err_code |= code;
3131
3132 if (code) {
3133 if (err && *err) {
3134 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003135 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003136 }
3137 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003138 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3139 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003140 if (code & ERR_FATAL) {
3141 free(err);
3142 cur_arg += 1 + kw->skip;
3143 goto out;
3144 }
3145 }
3146 free(err);
3147 cur_arg += 1 + kw->skip;
3148 continue;
3149 }
3150
Willy Tarreau8638f482012-09-18 18:01:17 +02003151 err = NULL;
3152 if (!bind_dumped) {
3153 bind_dump_kws(&err);
3154 indent_msg(&err, 4);
3155 bind_dumped = 1;
3156 }
3157
Christopher Faulet767a84b2017-11-24 16:50:31 +01003158 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3159 file, linenum, args[0], args[1], args[cur_arg],
3160 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003161 free(err);
3162
Willy Tarreau93893792009-07-23 13:19:11 +02003163 err_code |= ERR_ALERT | ERR_FATAL;
3164 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003165 }
Willy Tarreau93893792009-07-23 13:19:11 +02003166 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003167 }
3168 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003169 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003170 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3171 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003172 err_code |= ERR_ALERT | ERR_FATAL;
3173 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003174 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003175 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003176 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003177
Willy Tarreaubaaee002006-06-26 02:48:02 +02003178 /* flush useless bits */
3179 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003180 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003181 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003182 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003183 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003184 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003185
William Lallemanddf1425a2015-04-28 20:17:49 +02003186 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3187 goto out;
3188
Willy Tarreau1c47f852006-07-09 08:22:27 +02003189 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003190 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3191 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003192 err_code |= ERR_ALERT | ERR_FATAL;
3193 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003194 }
3195
Willy Tarreaua534fea2008-08-03 12:19:50 +02003196 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003197 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003198 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003199 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003200 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3201
Willy Tarreau93893792009-07-23 13:19:11 +02003202 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003203 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003204 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003205 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3206 goto out;
3207
Willy Tarreaubaaee002006-06-26 02:48:02 +02003208 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3209 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3210 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3211 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003212 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003213 err_code |= ERR_ALERT | ERR_FATAL;
3214 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003215 }
3216 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003217 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003218 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003219
3220 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003221 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003222 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003223 err_code |= ERR_ALERT | ERR_FATAL;
3224 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003225 }
3226
William Lallemanddf1425a2015-04-28 20:17:49 +02003227 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3228 goto out;
3229
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003230 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003231 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3232 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003233 err_code |= ERR_ALERT | ERR_FATAL;
3234 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003235 }
3236
3237 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003238 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003239 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003240
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003241 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003242 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3243 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003244 err_code |= ERR_ALERT | ERR_FATAL;
3245 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003246 }
3247
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003248 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3249 if (node) {
3250 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003251 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3252 file, linenum, proxy_type_str(curproxy), curproxy->id,
3253 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003254 err_code |= ERR_ALERT | ERR_FATAL;
3255 goto out;
3256 }
3257 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003258 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003259 else if (!strcmp(args[0], "description")) {
3260 int i, len=0;
3261 char *d;
3262
Cyril Bonté99ed3272010-01-24 23:29:44 +01003263 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003264 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003265 file, linenum, args[0]);
3266 err_code |= ERR_ALERT | ERR_FATAL;
3267 goto out;
3268 }
3269
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003270 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003271 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3272 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003273 return -1;
3274 }
3275
Willy Tarreau348acfe2014-04-14 15:00:39 +02003276 for (i = 1; *args[i]; i++)
3277 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003278
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003279 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003280 curproxy->desc = d;
3281
Willy Tarreau348acfe2014-04-14 15:00:39 +02003282 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3283 for (i = 2; *args[i]; i++)
3284 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003285
3286 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003287 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003288 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3289 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003290 curproxy->state = PR_STSTOPPED;
3291 }
3292 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003293 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3294 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003295 curproxy->state = PR_STNEW;
3296 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003297 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3298 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003299 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003300
3301 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003302 if (strcmp(args[cur_arg], "all") == 0) {
3303 set = 0;
3304 break;
3305 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003306 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003307 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003308 err_code |= ERR_ALERT | ERR_FATAL;
3309 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003310 }
3311 cur_arg++;
3312 }
3313 curproxy->bind_proc = set;
3314 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003315 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003316 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003317 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003318 err_code |= ERR_ALERT | ERR_FATAL;
3319 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003320 }
3321
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003322 err = invalid_char(args[1]);
3323 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003324 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3325 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003326 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003327 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003328 }
3329
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003330 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003331 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3332 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003333 err_code |= ERR_ALERT | ERR_FATAL;
3334 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003335 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003336 }
3337 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3338
3339 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3340 err_code |= ERR_WARN;
3341
3342 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003343 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3344 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003345 err_code |= ERR_ALERT | ERR_FATAL;
3346 goto out;
3347 }
3348 free(curproxy->dyncookie_key);
3349 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003350 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003351 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3352 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003353
Willy Tarreau977b8e42006-12-29 14:19:17 +01003354 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003355 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003356
Willy Tarreaubaaee002006-06-26 02:48:02 +02003357 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003358 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3359 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003360 err_code |= ERR_ALERT | ERR_FATAL;
3361 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003362 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003363
Willy Tarreau67402132012-05-31 20:40:20 +02003364 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003365 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003366 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003367 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003368 curproxy->cookie_name = strdup(args[1]);
3369 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003370
Willy Tarreaubaaee002006-06-26 02:48:02 +02003371 cur_arg = 2;
3372 while (*(args[cur_arg])) {
3373 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003374 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003375 }
3376 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003377 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003378 }
3379 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003380 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003381 }
3382 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003383 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003384 }
3385 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003386 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003387 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003388 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003389 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003390 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003391 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003392 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003393 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003394 else if (!strcmp(args[cur_arg], "httponly")) {
3395 curproxy->ck_opts |= PR_CK_HTTPONLY;
3396 }
3397 else if (!strcmp(args[cur_arg], "secure")) {
3398 curproxy->ck_opts |= PR_CK_SECURE;
3399 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003400 else if (!strcmp(args[cur_arg], "domain")) {
3401 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003402 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3403 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003404 err_code |= ERR_ALERT | ERR_FATAL;
3405 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003406 }
3407
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003408 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003409 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003410 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3411 " dots nor does not start with a dot."
3412 " RFC forbids it, this configuration may not work properly.\n",
3413 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003414 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003415 }
3416
3417 err = invalid_domainchar(args[cur_arg + 1]);
3418 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003419 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3420 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003421 err_code |= ERR_ALERT | ERR_FATAL;
3422 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003423 }
3424
Willy Tarreau68a897b2009-12-03 23:28:34 +01003425 if (!curproxy->cookie_domain) {
3426 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3427 } else {
3428 /* one domain was already specified, add another one by
3429 * building the string which will be returned along with
3430 * the cookie.
3431 */
3432 char *new_ptr;
3433 int new_len = strlen(curproxy->cookie_domain) +
3434 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3435 new_ptr = malloc(new_len);
3436 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3437 free(curproxy->cookie_domain);
3438 curproxy->cookie_domain = new_ptr;
3439 }
Willy Tarreau31936852010-10-06 16:59:56 +02003440 cur_arg++;
3441 }
3442 else if (!strcmp(args[cur_arg], "maxidle")) {
3443 unsigned int maxidle;
3444 const char *res;
3445
3446 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003447 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3448 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003449 err_code |= ERR_ALERT | ERR_FATAL;
3450 goto out;
3451 }
3452
3453 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3454 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003455 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3456 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003457 err_code |= ERR_ALERT | ERR_FATAL;
3458 goto out;
3459 }
3460 curproxy->cookie_maxidle = maxidle;
3461 cur_arg++;
3462 }
3463 else if (!strcmp(args[cur_arg], "maxlife")) {
3464 unsigned int maxlife;
3465 const char *res;
3466
3467 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003468 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3469 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003470 err_code |= ERR_ALERT | ERR_FATAL;
3471 goto out;
3472 }
3473
3474 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3475 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003476 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3477 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003478 err_code |= ERR_ALERT | ERR_FATAL;
3479 goto out;
3480 }
3481 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003482 cur_arg++;
3483 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003484 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003485
3486 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3487 err_code |= ERR_WARN;
3488 curproxy->ck_opts |= PR_CK_DYNAMIC;
3489 }
3490
Willy Tarreaubaaee002006-06-26 02:48:02 +02003491 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003492 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3493 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003494 err_code |= ERR_ALERT | ERR_FATAL;
3495 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003496 }
3497 cur_arg++;
3498 }
Willy Tarreau67402132012-05-31 20:40:20 +02003499 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003500 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3501 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003502 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003503 }
3504
Willy Tarreau67402132012-05-31 20:40:20 +02003505 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003506 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3507 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003508 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003509 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003510
Willy Tarreau67402132012-05-31 20:40:20 +02003511 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003512 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3513 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003514 err_code |= ERR_ALERT | ERR_FATAL;
3515 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003516 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003517 else if (!strcmp(args[0], "email-alert")) {
3518 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003519 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3520 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003521 err_code |= ERR_ALERT | ERR_FATAL;
3522 goto out;
3523 }
3524
3525 if (!strcmp(args[1], "from")) {
3526 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003527 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3528 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003529 err_code |= ERR_ALERT | ERR_FATAL;
3530 goto out;
3531 }
3532 free(curproxy->email_alert.from);
3533 curproxy->email_alert.from = strdup(args[2]);
3534 }
3535 else if (!strcmp(args[1], "mailers")) {
3536 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003537 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3538 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003539 err_code |= ERR_ALERT | ERR_FATAL;
3540 goto out;
3541 }
3542 free(curproxy->email_alert.mailers.name);
3543 curproxy->email_alert.mailers.name = strdup(args[2]);
3544 }
3545 else if (!strcmp(args[1], "myhostname")) {
3546 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003547 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3548 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003549 err_code |= ERR_ALERT | ERR_FATAL;
3550 goto out;
3551 }
3552 free(curproxy->email_alert.myhostname);
3553 curproxy->email_alert.myhostname = strdup(args[2]);
3554 }
Simon Horman64e34162015-02-06 11:11:57 +09003555 else if (!strcmp(args[1], "level")) {
3556 curproxy->email_alert.level = get_log_level(args[2]);
3557 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003558 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3559 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003560 err_code |= ERR_ALERT | ERR_FATAL;
3561 goto out;
3562 }
3563 }
Simon Horman9dc49962015-01-30 11:22:59 +09003564 else if (!strcmp(args[1], "to")) {
3565 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003566 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3567 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003568 err_code |= ERR_ALERT | ERR_FATAL;
3569 goto out;
3570 }
3571 free(curproxy->email_alert.to);
3572 curproxy->email_alert.to = strdup(args[2]);
3573 }
3574 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003575 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3576 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003577 err_code |= ERR_ALERT | ERR_FATAL;
3578 goto out;
3579 }
Simon Horman64e34162015-02-06 11:11:57 +09003580 /* Indicate that the email_alert is at least partially configured */
3581 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003582 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003583 else if (!strcmp(args[0], "external-check")) {
3584 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003585 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3586 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003587 err_code |= ERR_ALERT | ERR_FATAL;
3588 goto out;
3589 }
3590
3591 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003592 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003593 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003594 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003595 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3596 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003597 err_code |= ERR_ALERT | ERR_FATAL;
3598 goto out;
3599 }
3600 free(curproxy->check_command);
3601 curproxy->check_command = strdup(args[2]);
3602 }
3603 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003604 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003605 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003606 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003607 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3608 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003609 err_code |= ERR_ALERT | ERR_FATAL;
3610 goto out;
3611 }
3612 free(curproxy->check_path);
3613 curproxy->check_path = strdup(args[2]);
3614 }
3615 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003616 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3617 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003618 err_code |= ERR_ALERT | ERR_FATAL;
3619 goto out;
3620 }
3621 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003622 else if (!strcmp(args[0], "persist")) { /* persist */
3623 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003624 ha_alert("parsing [%s:%d] : missing persist method.\n",
3625 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003626 err_code |= ERR_ALERT | ERR_FATAL;
3627 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003628 }
3629
3630 if (!strncmp(args[1], "rdp-cookie", 10)) {
3631 curproxy->options2 |= PR_O2_RDPC_PRST;
3632
Emeric Brunb982a3d2010-01-04 15:45:53 +01003633 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003634 const char *beg, *end;
3635
3636 beg = args[1] + 11;
3637 end = strchr(beg, ')');
3638
William Lallemanddf1425a2015-04-28 20:17:49 +02003639 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3640 goto out;
3641
Emeric Brun647caf12009-06-30 17:57:00 +02003642 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003643 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3644 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003645 err_code |= ERR_ALERT | ERR_FATAL;
3646 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003647 }
3648
3649 free(curproxy->rdp_cookie_name);
3650 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3651 curproxy->rdp_cookie_len = end-beg;
3652 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003653 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003654 free(curproxy->rdp_cookie_name);
3655 curproxy->rdp_cookie_name = strdup("msts");
3656 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3657 }
3658 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003659 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3660 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003661 err_code |= ERR_ALERT | ERR_FATAL;
3662 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003663 }
3664 }
3665 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003666 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3667 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003668 err_code |= ERR_ALERT | ERR_FATAL;
3669 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003670 }
3671 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003672 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003673 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 +02003674 err_code |= ERR_ALERT | ERR_FATAL;
3675 goto out;
3676 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003677 else if (!strcmp(args[0], "load-server-state-from-file")) {
3678 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3679 err_code |= ERR_WARN;
3680 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3681 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3682 }
3683 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3684 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3685 }
3686 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3687 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3688 }
3689 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003690 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3691 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003692 err_code |= ERR_ALERT | ERR_FATAL;
3693 goto out;
3694 }
3695 }
3696 else if (!strcmp(args[0], "server-state-file-name")) {
3697 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3698 err_code |= ERR_WARN;
3699 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003700 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3701 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003702 err_code |= ERR_ALERT | ERR_FATAL;
3703 goto out;
3704 }
3705 else if (!strcmp(args[1], "use-backend-name"))
3706 curproxy->server_state_file_name = strdup(curproxy->id);
3707 else
3708 curproxy->server_state_file_name = strdup(args[1]);
3709 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003710 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003711 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003712 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003713
Willy Tarreaubaaee002006-06-26 02:48:02 +02003714 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003715 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003716 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 +01003717 err_code |= ERR_ALERT | ERR_FATAL;
3718 goto out;
3719 }
3720
William Lallemand1a748ae2015-05-19 16:37:23 +02003721 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3722 goto out;
3723
Willy Tarreaubaaee002006-06-26 02:48:02 +02003724 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003725 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3726 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003727 err_code |= ERR_ALERT | ERR_FATAL;
3728 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003729 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003730 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003731 curproxy->capture_name = strdup(args[2]);
3732 curproxy->capture_namelen = strlen(curproxy->capture_name);
3733 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003734 curproxy->to_log |= LW_COOKIE;
3735 }
3736 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3737 struct cap_hdr *hdr;
3738
3739 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003740 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 +02003741 err_code |= ERR_ALERT | ERR_FATAL;
3742 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003743 }
3744
William Lallemand1a748ae2015-05-19 16:37:23 +02003745 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3746 goto out;
3747
Willy Tarreaubaaee002006-06-26 02:48:02 +02003748 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003749 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3750 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003751 err_code |= ERR_ALERT | ERR_FATAL;
3752 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003753 }
3754
Vincent Bernat02779b62016-04-03 13:48:43 +02003755 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003756 hdr->next = curproxy->req_cap;
3757 hdr->name = strdup(args[3]);
3758 hdr->namelen = strlen(args[3]);
3759 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003760 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003761 hdr->index = curproxy->nb_req_cap++;
3762 curproxy->req_cap = hdr;
3763 curproxy->to_log |= LW_REQHDR;
3764 }
3765 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3766 struct cap_hdr *hdr;
3767
3768 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003769 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 +02003770 err_code |= ERR_ALERT | ERR_FATAL;
3771 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003772 }
3773
William Lallemand1a748ae2015-05-19 16:37:23 +02003774 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3775 goto out;
3776
Willy Tarreaubaaee002006-06-26 02:48:02 +02003777 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003778 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3779 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003780 err_code |= ERR_ALERT | ERR_FATAL;
3781 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003782 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003783 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003784 hdr->next = curproxy->rsp_cap;
3785 hdr->name = strdup(args[3]);
3786 hdr->namelen = strlen(args[3]);
3787 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003788 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003789 hdr->index = curproxy->nb_rsp_cap++;
3790 curproxy->rsp_cap = hdr;
3791 curproxy->to_log |= LW_RSPHDR;
3792 }
3793 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003794 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3795 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003796 err_code |= ERR_ALERT | ERR_FATAL;
3797 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003798 }
3799 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003800 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003801 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003802 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003803
William Lallemanddf1425a2015-04-28 20:17:49 +02003804 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3805 goto out;
3806
Willy Tarreaubaaee002006-06-26 02:48:02 +02003807 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003808 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3809 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003810 err_code |= ERR_ALERT | ERR_FATAL;
3811 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003812 }
3813 curproxy->conn_retries = atol(args[1]);
3814 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003815 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003816 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003817
3818 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003819 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003820 err_code |= ERR_ALERT | ERR_FATAL;
3821 goto out;
3822 }
3823
Willy Tarreau20b0de52012-12-24 15:45:22 +01003824 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003825 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003826 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3827 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3828 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3829 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003830 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3831 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003832 err_code |= ERR_WARN;
3833 }
3834
Willy Tarreauff011f22011-01-06 17:51:27 +01003835 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003836
Willy Tarreauff011f22011-01-06 17:51:27 +01003837 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003838 err_code |= ERR_ALERT | ERR_ABORT;
3839 goto out;
3840 }
3841
Willy Tarreau5002f572014-04-23 01:32:02 +02003842 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003843 err_code |= warnif_cond_conflicts(rule->cond,
3844 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3845 file, linenum);
3846
Willy Tarreauff011f22011-01-06 17:51:27 +01003847 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003848 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003849 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003850 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003851
3852 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003853 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003854 err_code |= ERR_ALERT | ERR_FATAL;
3855 goto out;
3856 }
3857
3858 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003859 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003860 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3861 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003862 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3863 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003864 err_code |= ERR_WARN;
3865 }
3866
3867 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3868
3869 if (!rule) {
3870 err_code |= ERR_ALERT | ERR_ABORT;
3871 goto out;
3872 }
3873
3874 err_code |= warnif_cond_conflicts(rule->cond,
3875 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3876 file, linenum);
3877
3878 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3879 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003880 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3881 /* set the header name and length into the proxy structure */
3882 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3883 err_code |= ERR_WARN;
3884
3885 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003886 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3887 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003888 err_code |= ERR_ALERT | ERR_FATAL;
3889 goto out;
3890 }
3891
3892 /* set the desired header name */
3893 free(curproxy->server_id_hdr_name);
3894 curproxy->server_id_hdr_name = strdup(args[1]);
3895 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3896 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003897 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003898 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003899
Willy Tarreaub099aca2008-10-12 17:26:37 +02003900 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003901 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003902 err_code |= ERR_ALERT | ERR_FATAL;
3903 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003904 }
3905
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003906 /* emulate "block" using "http-request block". Since these rules are supposed to
3907 * be processed before all http-request rules, we put them into their own list
3908 * and will insert them at the end.
3909 */
3910 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3911 if (!rule) {
3912 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003913 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003914 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003915 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3916 err_code |= warnif_cond_conflicts(rule->cond,
3917 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3918 file, linenum);
3919 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003920
3921 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003922 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 +02003923
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003924 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003925 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003926 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003927
Cyril Bonté99ed3272010-01-24 23:29:44 +01003928 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003929 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003930 err_code |= ERR_ALERT | ERR_FATAL;
3931 goto out;
3932 }
3933
Willy Tarreaube4653b2015-05-28 15:26:58 +02003934 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003935 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3936 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003937 err_code |= ERR_ALERT | ERR_FATAL;
3938 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003939 }
3940
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003941 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003942 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003943 err_code |= warnif_cond_conflicts(rule->cond,
3944 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3945 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003946 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003947 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003948 struct switching_rule *rule;
3949
Willy Tarreaub099aca2008-10-12 17:26:37 +02003950 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003951 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003952 err_code |= ERR_ALERT | ERR_FATAL;
3953 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003954 }
3955
Willy Tarreau55ea7572007-06-17 19:56:27 +02003956 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003957 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003958
3959 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003960 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003961 err_code |= ERR_ALERT | ERR_FATAL;
3962 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003963 }
3964
Willy Tarreauf51658d2014-04-23 01:21:56 +02003965 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003966 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003967 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3968 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02003969 err_code |= ERR_ALERT | ERR_FATAL;
3970 goto out;
3971 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003972
Willy Tarreauf51658d2014-04-23 01:21:56 +02003973 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02003974 }
Willy Tarreau4f862642017-02-28 09:34:39 +01003975 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003976 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
3977 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01003978 err_code |= ERR_ALERT | ERR_FATAL;
3979 goto out;
3980 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003981
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003982 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01003983 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003984 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01003985 goto out;
3986 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003987 rule->cond = cond;
3988 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01003989 rule->line = linenum;
3990 rule->file = strdup(file);
3991 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003992 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01003993 goto out;
3994 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003995 LIST_INIT(&rule->list);
3996 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
3997 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02003998 else if (strcmp(args[0], "use-server") == 0) {
3999 struct server_rule *rule;
4000
4001 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004002 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004003 err_code |= ERR_ALERT | ERR_FATAL;
4004 goto out;
4005 }
4006
4007 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4008 err_code |= ERR_WARN;
4009
4010 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004011 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004012 err_code |= ERR_ALERT | ERR_FATAL;
4013 goto out;
4014 }
4015
4016 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004017 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4018 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004019 err_code |= ERR_ALERT | ERR_FATAL;
4020 goto out;
4021 }
4022
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004023 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004024 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4025 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004026 err_code |= ERR_ALERT | ERR_FATAL;
4027 goto out;
4028 }
4029
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004030 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004031
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004032 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004033 rule->cond = cond;
4034 rule->srv.name = strdup(args[1]);
4035 LIST_INIT(&rule->list);
4036 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4037 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4038 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004039 else if ((!strcmp(args[0], "force-persist")) ||
4040 (!strcmp(args[0], "ignore-persist"))) {
4041 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004042
4043 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004044 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004045 err_code |= ERR_ALERT | ERR_FATAL;
4046 goto out;
4047 }
4048
4049 if (warnifnotcap(curproxy, PR_CAP_FE|PR_CAP_BE, file, linenum, args[0], NULL))
4050 err_code |= ERR_WARN;
4051
Willy Tarreauef6494c2010-01-28 17:12:36 +01004052 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004053 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4054 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004055 err_code |= ERR_ALERT | ERR_FATAL;
4056 goto out;
4057 }
4058
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004059 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004060 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4061 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004062 err_code |= ERR_ALERT | ERR_FATAL;
4063 goto out;
4064 }
4065
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004066 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4067 * where force-persist is applied.
4068 */
4069 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004070
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004071 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004072 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004073 if (!strcmp(args[0], "force-persist")) {
4074 rule->type = PERSIST_TYPE_FORCE;
4075 } else {
4076 rule->type = PERSIST_TYPE_IGNORE;
4077 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004078 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004079 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004080 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004081 else if (!strcmp(args[0], "stick-table")) {
4082 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004083 struct proxy *other;
4084
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004085 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004086 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004087 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4088 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004089 err_code |= ERR_ALERT | ERR_FATAL;
4090 goto out;
4091 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004092
Emeric Brun32da3c42010-09-23 18:39:19 +02004093 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004094 curproxy->table.type = (unsigned int)-1;
4095 while (*args[myidx]) {
4096 const char *err;
4097
4098 if (strcmp(args[myidx], "size") == 0) {
4099 myidx++;
4100 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004101 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4102 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004103 err_code |= ERR_ALERT | ERR_FATAL;
4104 goto out;
4105 }
4106 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004107 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4108 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004109 err_code |= ERR_ALERT | ERR_FATAL;
4110 goto out;
4111 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004112 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004113 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004114 else if (strcmp(args[myidx], "peers") == 0) {
4115 myidx++;
Godbach50523162013-12-11 19:48:57 +08004116 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004117 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4118 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004119 err_code |= ERR_ALERT | ERR_FATAL;
4120 goto out;
Godbach50523162013-12-11 19:48:57 +08004121 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004122 curproxy->table.peers.name = strdup(args[myidx++]);
4123 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004124 else if (strcmp(args[myidx], "expire") == 0) {
4125 myidx++;
4126 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004127 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4128 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004129 err_code |= ERR_ALERT | ERR_FATAL;
4130 goto out;
4131 }
4132 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4133 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004134 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4135 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004136 err_code |= ERR_ALERT | ERR_FATAL;
4137 goto out;
4138 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004139 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004140 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4141 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004142 err_code |= ERR_ALERT | ERR_FATAL;
4143 goto out;
4144 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004145 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004146 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004147 }
4148 else if (strcmp(args[myidx], "nopurge") == 0) {
4149 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004150 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004151 }
4152 else if (strcmp(args[myidx], "type") == 0) {
4153 myidx++;
4154 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004155 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4156 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004157 err_code |= ERR_ALERT | ERR_FATAL;
4158 goto out;
4159 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004160 /* myidx already points to next arg */
4161 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004162 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004163 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004164 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004165
4166 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004167 nw = args[myidx];
4168 while (*nw) {
4169 /* the "store" keyword supports a comma-separated list */
4170 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004171 sa = NULL; /* store arg */
4172 while (*nw && *nw != ',') {
4173 if (*nw == '(') {
4174 *nw = 0;
4175 sa = ++nw;
4176 while (*nw != ')') {
4177 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004178 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4179 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004180 err_code |= ERR_ALERT | ERR_FATAL;
4181 goto out;
4182 }
4183 nw++;
4184 }
4185 *nw = '\0';
4186 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004187 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004188 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004189 if (*nw)
4190 *nw++ = '\0';
4191 type = stktable_get_data_type(cw);
4192 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004193 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4194 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004195 err_code |= ERR_ALERT | ERR_FATAL;
4196 goto out;
4197 }
Willy Tarreauac782882010-06-20 10:41:54 +02004198
4199 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4200 switch (err) {
4201 case PE_NONE: break;
4202 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004203 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4204 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004205 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004206 break;
4207
4208 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004209 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4210 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004211 err_code |= ERR_ALERT | ERR_FATAL;
4212 goto out;
4213
4214 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004215 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4216 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004217 err_code |= ERR_ALERT | ERR_FATAL;
4218 goto out;
4219
4220 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004221 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4222 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004223 err_code |= ERR_ALERT | ERR_FATAL;
4224 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004225 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004226 }
4227 myidx++;
4228 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004229 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004230 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4231 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004232 err_code |= ERR_ALERT | ERR_FATAL;
4233 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004234 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004235 }
4236
4237 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004238 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4239 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004240 err_code |= ERR_ALERT | ERR_FATAL;
4241 goto out;
4242 }
4243
4244 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004245 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4246 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004247 err_code |= ERR_ALERT | ERR_FATAL;
4248 goto out;
4249 }
4250 }
4251 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004252 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004253 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004254 int myidx = 0;
4255 const char *name = NULL;
4256 int flags;
4257
4258 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004259 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004260 err_code |= ERR_ALERT | ERR_FATAL;
4261 goto out;
4262 }
4263
4264 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4265 err_code |= ERR_WARN;
4266 goto out;
4267 }
4268
4269 myidx++;
4270 if ((strcmp(args[myidx], "store") == 0) ||
4271 (strcmp(args[myidx], "store-request") == 0)) {
4272 myidx++;
4273 flags = STK_IS_STORE;
4274 }
4275 else if (strcmp(args[myidx], "store-response") == 0) {
4276 myidx++;
4277 flags = STK_IS_STORE | STK_ON_RSP;
4278 }
4279 else if (strcmp(args[myidx], "match") == 0) {
4280 myidx++;
4281 flags = STK_IS_MATCH;
4282 }
4283 else if (strcmp(args[myidx], "on") == 0) {
4284 myidx++;
4285 flags = STK_IS_MATCH | STK_IS_STORE;
4286 }
4287 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004288 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004289 err_code |= ERR_ALERT | ERR_FATAL;
4290 goto out;
4291 }
4292
4293 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004294 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004295 err_code |= ERR_ALERT | ERR_FATAL;
4296 goto out;
4297 }
4298
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004299 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004300 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004301 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004302 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004303 err_code |= ERR_ALERT | ERR_FATAL;
4304 goto out;
4305 }
4306
4307 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004308 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004309 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4310 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004311 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004312 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004313 goto out;
4314 }
4315 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004316 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004317 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4318 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004319 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004320 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004321 goto out;
4322 }
4323 }
4324
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004325 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004326 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004327
Emeric Brunb982a3d2010-01-04 15:45:53 +01004328 if (strcmp(args[myidx], "table") == 0) {
4329 myidx++;
4330 name = args[myidx++];
4331 }
4332
Willy Tarreauef6494c2010-01-28 17:12:36 +01004333 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004334 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004335 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4336 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004337 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004338 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004339 goto out;
4340 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004341 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004342 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004343 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4344 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004345 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004346 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004347 goto out;
4348 }
Emeric Brun97679e72010-09-23 17:56:44 +02004349 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004350 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004351 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004352 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004353
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004354 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004355 rule->cond = cond;
4356 rule->expr = expr;
4357 rule->flags = flags;
4358 rule->table.name = name ? strdup(name) : NULL;
4359 LIST_INIT(&rule->list);
4360 if (flags & STK_ON_RSP)
4361 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4362 else
4363 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4364 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004365 else if (!strcmp(args[0], "stats")) {
4366 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4367 curproxy->uri_auth = NULL; /* we must detach from the default config */
4368
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004369 if (!*args[1]) {
4370 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004371 } else if (!strcmp(args[1], "admin")) {
4372 struct stats_admin_rule *rule;
4373
4374 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004375 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 +02004376 err_code |= ERR_ALERT | ERR_FATAL;
4377 goto out;
4378 }
4379
4380 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004381 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004382 err_code |= ERR_ALERT | ERR_ABORT;
4383 goto out;
4384 }
4385
4386 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004387 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4388 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004389 err_code |= ERR_ALERT | ERR_FATAL;
4390 goto out;
4391 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004392 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004393 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4394 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004395 err_code |= ERR_ALERT | ERR_FATAL;
4396 goto out;
4397 }
4398
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004399 err_code |= warnif_cond_conflicts(cond,
4400 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4401 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004402
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004403 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004404 rule->cond = cond;
4405 LIST_INIT(&rule->list);
4406 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004407 } else if (!strcmp(args[1], "uri")) {
4408 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004409 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004410 err_code |= ERR_ALERT | ERR_FATAL;
4411 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004412 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004413 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004414 err_code |= ERR_ALERT | ERR_ABORT;
4415 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004416 }
4417 } else if (!strcmp(args[1], "realm")) {
4418 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004419 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004420 err_code |= ERR_ALERT | ERR_FATAL;
4421 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004422 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004423 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004424 err_code |= ERR_ALERT | ERR_ABORT;
4425 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004426 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004427 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004428 unsigned interval;
4429
4430 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4431 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004432 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4433 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004434 err_code |= ERR_ALERT | ERR_FATAL;
4435 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004436 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004437 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004438 err_code |= ERR_ALERT | ERR_ABORT;
4439 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004440 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004441 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004442 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004443
4444 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004445 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004446 err_code |= ERR_ALERT | ERR_FATAL;
4447 goto out;
4448 }
4449
4450 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004451 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004452 err_code |= ERR_ALERT | ERR_ABORT;
4453 goto out;
4454 }
4455
Willy Tarreauff011f22011-01-06 17:51:27 +01004456 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004457 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004458 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4459 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004460 err_code |= ERR_WARN;
4461 }
4462
Willy Tarreauff011f22011-01-06 17:51:27 +01004463 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004464
Willy Tarreauff011f22011-01-06 17:51:27 +01004465 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004466 err_code |= ERR_ALERT | ERR_ABORT;
4467 goto out;
4468 }
4469
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004470 err_code |= warnif_cond_conflicts(rule->cond,
4471 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4472 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004473 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004474
Willy Tarreaubaaee002006-06-26 02:48:02 +02004475 } else if (!strcmp(args[1], "auth")) {
4476 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004477 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
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 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004481 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004482 err_code |= ERR_ALERT | ERR_ABORT;
4483 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004484 }
4485 } else if (!strcmp(args[1], "scope")) {
4486 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004487 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
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 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004491 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004492 err_code |= ERR_ALERT | ERR_ABORT;
4493 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004494 }
4495 } else if (!strcmp(args[1], "enable")) {
4496 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004497 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004498 err_code |= ERR_ALERT | ERR_ABORT;
4499 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004500 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004501 } else if (!strcmp(args[1], "hide-version")) {
4502 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004503 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004504 err_code |= ERR_ALERT | ERR_ABORT;
4505 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004506 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004507 } else if (!strcmp(args[1], "show-legends")) {
4508 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004509 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004510 err_code |= ERR_ALERT | ERR_ABORT;
4511 goto out;
4512 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004513 } else if (!strcmp(args[1], "show-node")) {
4514
4515 if (*args[2]) {
4516 int i;
4517 char c;
4518
4519 for (i=0; args[2][i]; i++) {
4520 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004521 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4522 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004523 break;
4524 }
4525
4526 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004527 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4528 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4529 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004530 err_code |= ERR_ALERT | ERR_FATAL;
4531 goto out;
4532 }
4533 }
4534
4535 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004536 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004537 err_code |= ERR_ALERT | ERR_ABORT;
4538 goto out;
4539 }
4540 } else if (!strcmp(args[1], "show-desc")) {
4541 char *desc = NULL;
4542
4543 if (*args[2]) {
4544 int i, len=0;
4545 char *d;
4546
Willy Tarreau348acfe2014-04-14 15:00:39 +02004547 for (i = 2; *args[i]; i++)
4548 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004549
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004550 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004551
Willy Tarreau348acfe2014-04-14 15:00:39 +02004552 d += snprintf(d, desc + len - d, "%s", args[2]);
4553 for (i = 3; *args[i]; i++)
4554 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004555 }
4556
4557 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004558 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4559 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004560 else {
4561 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4562 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004563 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004564 err_code |= ERR_ALERT | ERR_ABORT;
4565 goto out;
4566 }
4567 free(desc);
4568 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004569 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004570stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004571 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4572 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004573 err_code |= ERR_ALERT | ERR_FATAL;
4574 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004575 }
4576 }
4577 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004578 int optnum;
4579
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004580 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004581 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4582 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004583 err_code |= ERR_ALERT | ERR_FATAL;
4584 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004585 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004586
4587 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4588 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004589 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004590 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4591 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004592 err_code |= ERR_ALERT | ERR_FATAL;
4593 goto out;
4594 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004595 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4596 goto out;
4597
Willy Tarreau93893792009-07-23 13:19:11 +02004598 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4599 err_code |= ERR_WARN;
4600 goto out;
4601 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004602
Willy Tarreau3842f002009-06-14 11:39:52 +02004603 curproxy->no_options &= ~cfg_opts[optnum].val;
4604 curproxy->options &= ~cfg_opts[optnum].val;
4605
4606 switch (kwm) {
4607 case KWM_STD:
4608 curproxy->options |= cfg_opts[optnum].val;
4609 break;
4610 case KWM_NO:
4611 curproxy->no_options |= cfg_opts[optnum].val;
4612 break;
4613 case KWM_DEF: /* already cleared */
4614 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004615 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004616
Willy Tarreau93893792009-07-23 13:19:11 +02004617 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004618 }
4619 }
4620
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004621 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4622 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004623 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004624 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4625 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004626 err_code |= ERR_ALERT | ERR_FATAL;
4627 goto out;
4628 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004629 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4630 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004631 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4632 err_code |= ERR_WARN;
4633 goto out;
4634 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004635
Willy Tarreau3842f002009-06-14 11:39:52 +02004636 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4637 curproxy->options2 &= ~cfg_opts2[optnum].val;
4638
4639 switch (kwm) {
4640 case KWM_STD:
4641 curproxy->options2 |= cfg_opts2[optnum].val;
4642 break;
4643 case KWM_NO:
4644 curproxy->no_options2 |= cfg_opts2[optnum].val;
4645 break;
4646 case KWM_DEF: /* already cleared */
4647 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004648 }
Willy Tarreau93893792009-07-23 13:19:11 +02004649 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004650 }
4651 }
4652
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004653 /* HTTP options override each other. They can be cancelled using
4654 * "no option xxx" which only switches to default mode if the mode
4655 * was this one (useful for cancelling options set in defaults
4656 * sections).
4657 */
4658 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004659 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4660 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004661 if (kwm == KWM_STD) {
4662 curproxy->options &= ~PR_O_HTTP_MODE;
4663 curproxy->options |= PR_O_HTTP_PCL;
4664 goto out;
4665 }
4666 else if (kwm == KWM_NO) {
4667 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4668 curproxy->options &= ~PR_O_HTTP_MODE;
4669 goto out;
4670 }
4671 }
4672 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004673 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4674 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004675 if (kwm == KWM_STD) {
4676 curproxy->options &= ~PR_O_HTTP_MODE;
4677 curproxy->options |= PR_O_HTTP_FCL;
4678 goto out;
4679 }
4680 else if (kwm == KWM_NO) {
4681 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4682 curproxy->options &= ~PR_O_HTTP_MODE;
4683 goto out;
4684 }
4685 }
4686 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004687 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4688 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004689 if (kwm == KWM_STD) {
4690 curproxy->options &= ~PR_O_HTTP_MODE;
4691 curproxy->options |= PR_O_HTTP_SCL;
4692 goto out;
4693 }
4694 else if (kwm == KWM_NO) {
4695 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4696 curproxy->options &= ~PR_O_HTTP_MODE;
4697 goto out;
4698 }
4699 }
4700 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004701 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4702 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004703 if (kwm == KWM_STD) {
4704 curproxy->options &= ~PR_O_HTTP_MODE;
4705 curproxy->options |= PR_O_HTTP_KAL;
4706 goto out;
4707 }
4708 else if (kwm == KWM_NO) {
4709 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4710 curproxy->options &= ~PR_O_HTTP_MODE;
4711 goto out;
4712 }
4713 }
4714 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004715 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4716 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004717 if (kwm == KWM_STD) {
4718 curproxy->options &= ~PR_O_HTTP_MODE;
4719 curproxy->options |= PR_O_HTTP_TUN;
4720 goto out;
4721 }
4722 else if (kwm == KWM_NO) {
4723 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4724 curproxy->options &= ~PR_O_HTTP_MODE;
4725 goto out;
4726 }
4727 }
4728
Joseph Lynch726ab712015-05-11 23:25:34 -07004729 /* Redispatch can take an integer argument that control when the
4730 * resispatch occurs. All values are relative to the retries option.
4731 * This can be cancelled using "no option xxx".
4732 */
4733 if (strcmp(args[1], "redispatch") == 0) {
4734 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4735 err_code |= ERR_WARN;
4736 goto out;
4737 }
4738
4739 curproxy->no_options &= ~PR_O_REDISP;
4740 curproxy->options &= ~PR_O_REDISP;
4741
4742 switch (kwm) {
4743 case KWM_STD:
4744 curproxy->options |= PR_O_REDISP;
4745 curproxy->redispatch_after = -1;
4746 if(*args[2]) {
4747 curproxy->redispatch_after = atol(args[2]);
4748 }
4749 break;
4750 case KWM_NO:
4751 curproxy->no_options |= PR_O_REDISP;
4752 curproxy->redispatch_after = 0;
4753 break;
4754 case KWM_DEF: /* already cleared */
4755 break;
4756 }
4757 goto out;
4758 }
4759
Willy Tarreau3842f002009-06-14 11:39:52 +02004760 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004761 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4762 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004763 err_code |= ERR_ALERT | ERR_FATAL;
4764 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004765 }
4766
Emeric Brun3a058f32009-06-30 18:26:00 +02004767 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004768 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004769 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004770 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004771 if (*(args[2]) != '\0') {
4772 if (!strcmp(args[2], "clf")) {
4773 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004774 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004775 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004776 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004777 err_code |= ERR_ALERT | ERR_FATAL;
4778 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004779 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004780 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4781 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004782 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004783 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4784 char *oldlogformat = "log-format";
4785 char *clflogformat = "";
4786
4787 if (curproxy->conf.logformat_string == default_http_log_format)
4788 oldlogformat = "option httplog";
4789 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4790 oldlogformat = "option tcplog";
4791 else if (curproxy->conf.logformat_string == clf_http_log_format)
4792 oldlogformat = "option httplog clf";
4793 if (logformat == clf_http_log_format)
4794 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004795 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4796 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004797 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004798 if (curproxy->conf.logformat_string != default_http_log_format &&
4799 curproxy->conf.logformat_string != default_tcp_log_format &&
4800 curproxy->conf.logformat_string != clf_http_log_format)
4801 free(curproxy->conf.logformat_string);
4802 curproxy->conf.logformat_string = logformat;
4803
4804 free(curproxy->conf.lfs_file);
4805 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4806 curproxy->conf.lfs_line = curproxy->conf.args.line;
Emeric Brun3a058f32009-06-30 18:26:00 +02004807 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004808 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004809 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4810 char *oldlogformat = "log-format";
4811
4812 if (curproxy->conf.logformat_string == default_http_log_format)
4813 oldlogformat = "option httplog";
4814 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4815 oldlogformat = "option tcplog";
4816 else if (curproxy->conf.logformat_string == clf_http_log_format)
4817 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004818 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4819 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004820 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004821 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004822 if (curproxy->conf.logformat_string != default_http_log_format &&
4823 curproxy->conf.logformat_string != default_tcp_log_format &&
4824 curproxy->conf.logformat_string != clf_http_log_format)
4825 free(curproxy->conf.logformat_string);
4826 curproxy->conf.logformat_string = default_tcp_log_format;
4827
4828 free(curproxy->conf.lfs_file);
4829 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4830 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004831
4832 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4833 goto out;
William Lallemandbddd4fd2012-02-27 11:23:10 +01004834 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004835 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004836 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004837 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004838 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004839
William Lallemanddf1425a2015-04-28 20:17:49 +02004840 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4841 goto out;
4842
Willy Tarreau13943ab2006-12-31 00:24:10 +01004843 if (curproxy->cap & PR_CAP_FE)
4844 curproxy->options |= PR_O_TCP_CLI_KA;
4845 if (curproxy->cap & PR_CAP_BE)
4846 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004847 }
4848 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004849 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004850 err_code |= ERR_WARN;
4851
Willy Tarreaubaaee002006-06-26 02:48:02 +02004852 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004853 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004854 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004855 curproxy->options2 &= ~PR_O2_CHK_ANY;
4856 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004857 if (!*args[2]) { /* no argument */
4858 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4859 curproxy->check_len = strlen(DEF_CHECK_REQ);
4860 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004861 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004862 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004863 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004864 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004865 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004866 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004867 if (*args[4])
4868 reqlen += strlen(args[4]);
4869 else
4870 reqlen += strlen("HTTP/1.0");
4871
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004872 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004873 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004874 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004875 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004876 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4877 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004878 }
4879 else if (!strcmp(args[1], "ssl-hello-chk")) {
4880 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004881 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004882 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004883
Willy Tarreaua534fea2008-08-03 12:19:50 +02004884 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004885 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004886 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004887 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004888
4889 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4890 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004891 }
Willy Tarreau23677902007-05-08 23:50:35 +02004892 else if (!strcmp(args[1], "smtpchk")) {
4893 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004894 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004895 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004896 curproxy->options2 &= ~PR_O2_CHK_ANY;
4897 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004898
4899 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4900 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4901 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4902 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4903 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4904 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004905 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004906 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4907 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4908 } else {
4909 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4910 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4911 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4912 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4913 }
4914 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004915 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4916 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004917 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004918 else if (!strcmp(args[1], "pgsql-check")) {
4919 /* use PostgreSQL request to check servers' health */
4920 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4921 err_code |= ERR_WARN;
4922
4923 free(curproxy->check_req);
4924 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004925 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004926 curproxy->options2 |= PR_O2_PGSQL_CHK;
4927
4928 if (*(args[2])) {
4929 int cur_arg = 2;
4930
4931 while (*(args[cur_arg])) {
4932 if (strcmp(args[cur_arg], "user") == 0) {
4933 char * packet;
4934 uint32_t packet_len;
4935 uint32_t pv;
4936
4937 /* suboption header - needs additional argument for it */
4938 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004939 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4940 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004941 err_code |= ERR_ALERT | ERR_FATAL;
4942 goto out;
4943 }
4944
4945 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4946 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4947 pv = htonl(0x30000); /* protocol version 3.0 */
4948
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004949 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004950
4951 memcpy(packet + 4, &pv, 4);
4952
4953 /* copy "user" */
4954 memcpy(packet + 8, "user", 4);
4955
4956 /* copy username */
4957 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
4958
4959 free(curproxy->check_req);
4960 curproxy->check_req = packet;
4961 curproxy->check_len = packet_len;
4962
4963 packet_len = htonl(packet_len);
4964 memcpy(packet, &packet_len, 4);
4965 cur_arg += 2;
4966 } else {
4967 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004968 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
4969 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004970 err_code |= ERR_ALERT | ERR_FATAL;
4971 goto out;
4972 }
4973 } /* end while loop */
4974 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004975 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4976 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004977 }
4978
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004979 else if (!strcmp(args[1], "redis-check")) {
4980 /* use REDIS PING request to check servers' health */
4981 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4982 err_code |= ERR_WARN;
4983
4984 free(curproxy->check_req);
4985 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004986 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004987 curproxy->options2 |= PR_O2_REDIS_CHK;
4988
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004989 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004990 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
4991 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02004992
4993 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4994 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02004995 }
4996
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004997 else if (!strcmp(args[1], "mysql-check")) {
4998 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004999 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5000 err_code |= ERR_WARN;
5001
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005002 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005003 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005004 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005005 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005006
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005007 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005008 * const char mysql40_client_auth_pkt[] = {
5009 * "\x0e\x00\x00" // packet length
5010 * "\x01" // packet number
5011 * "\x00\x00" // client capabilities
5012 * "\x00\x00\x01" // max packet
5013 * "haproxy\x00" // username (null terminated string)
5014 * "\x00" // filler (always 0x00)
5015 * "\x01\x00\x00" // packet length
5016 * "\x00" // packet number
5017 * "\x01" // COM_QUIT command
5018 * };
5019 */
5020
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005021 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5022 * const char mysql41_client_auth_pkt[] = {
5023 * "\x0e\x00\x00\" // packet length
5024 * "\x01" // packet number
5025 * "\x00\x00\x00\x00" // client capabilities
5026 * "\x00\x00\x00\x01" // max packet
5027 * "\x21" // character set (UTF-8)
5028 * char[23] // All zeroes
5029 * "haproxy\x00" // username (null terminated string)
5030 * "\x00" // filler (always 0x00)
5031 * "\x01\x00\x00" // packet length
5032 * "\x00" // packet number
5033 * "\x01" // COM_QUIT command
5034 * };
5035 */
5036
5037
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005038 if (*(args[2])) {
5039 int cur_arg = 2;
5040
5041 while (*(args[cur_arg])) {
5042 if (strcmp(args[cur_arg], "user") == 0) {
5043 char *mysqluser;
5044 int packetlen, reqlen, userlen;
5045
5046 /* suboption header - needs additional argument for it */
5047 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005048 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5049 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005050 err_code |= ERR_ALERT | ERR_FATAL;
5051 goto out;
5052 }
5053 mysqluser = args[cur_arg + 1];
5054 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005055
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005056 if (*(args[cur_arg+2])) {
5057 if (!strcmp(args[cur_arg+2], "post-41")) {
5058 packetlen = userlen + 7 + 27;
5059 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005060
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005061 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005062 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005063 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005064
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005065 snprintf(curproxy->check_req, 4, "%c%c%c",
5066 ((unsigned char) packetlen & 0xff),
5067 ((unsigned char) (packetlen >> 8) & 0xff),
5068 ((unsigned char) (packetlen >> 16) & 0xff));
5069
5070 curproxy->check_req[3] = 1;
5071 curproxy->check_req[5] = 130;
5072 curproxy->check_req[11] = 1;
5073 curproxy->check_req[12] = 33;
5074 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5075 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5076 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5077 cur_arg += 3;
5078 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005079 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 +02005080 err_code |= ERR_ALERT | ERR_FATAL;
5081 goto out;
5082 }
5083 } else {
5084 packetlen = userlen + 7;
5085 reqlen = packetlen + 9;
5086
5087 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005088 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005089 curproxy->check_len = reqlen;
5090
5091 snprintf(curproxy->check_req, 4, "%c%c%c",
5092 ((unsigned char) packetlen & 0xff),
5093 ((unsigned char) (packetlen >> 8) & 0xff),
5094 ((unsigned char) (packetlen >> 16) & 0xff));
5095
5096 curproxy->check_req[3] = 1;
5097 curproxy->check_req[5] = 128;
5098 curproxy->check_req[8] = 1;
5099 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5100 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5101 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5102 cur_arg += 2;
5103 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005104 } else {
5105 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005106 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5107 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005108 err_code |= ERR_ALERT | ERR_FATAL;
5109 goto out;
5110 }
5111 } /* end while loop */
5112 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005113 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005114 else if (!strcmp(args[1], "ldap-check")) {
5115 /* use LDAP request to check servers' health */
5116 free(curproxy->check_req);
5117 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005118 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005119 curproxy->options2 |= PR_O2_LDAP_CHK;
5120
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005121 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005122 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5123 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005124 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5125 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005126 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005127 else if (!strcmp(args[1], "spop-check")) {
5128 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005129 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5130 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005131 err_code |= ERR_ALERT | ERR_FATAL;
5132 goto out;
5133 }
5134 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005135 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5136 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005137 err_code |= ERR_ALERT | ERR_FATAL;
5138 goto out;
5139 }
5140
5141 /* use SPOE request to check servers' health */
5142 free(curproxy->check_req);
5143 curproxy->check_req = NULL;
5144 curproxy->options2 &= ~PR_O2_CHK_ANY;
5145 curproxy->options2 |= PR_O2_SPOP_CHK;
5146
Christopher Faulet8ef75252017-02-20 22:56:03 +01005147 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005148 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005149 err_code |= ERR_ALERT | ERR_FATAL;
5150 goto out;
5151 }
5152 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5153 goto out;
5154 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005155 else if (!strcmp(args[1], "tcp-check")) {
5156 /* use raw TCPCHK send/expect to check servers' health */
5157 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5158 err_code |= ERR_WARN;
5159
5160 free(curproxy->check_req);
5161 curproxy->check_req = NULL;
5162 curproxy->options2 &= ~PR_O2_CHK_ANY;
5163 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005164 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5165 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005166 }
Simon Horman98637e52014-06-20 12:30:16 +09005167 else if (!strcmp(args[1], "external-check")) {
5168 /* excute an external command to check servers' health */
5169 free(curproxy->check_req);
5170 curproxy->check_req = NULL;
5171 curproxy->options2 &= ~PR_O2_CHK_ANY;
5172 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005173 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5174 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005175 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005176 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005177 int cur_arg;
5178
5179 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5180 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005181 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005182
Willy Tarreau87cf5142011-08-19 22:57:24 +02005183 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005184
5185 free(curproxy->fwdfor_hdr_name);
5186 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5187 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5188
5189 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5190 cur_arg = 2;
5191 while (*(args[cur_arg])) {
5192 if (!strcmp(args[cur_arg], "except")) {
5193 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005194 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005195 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5196 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005197 err_code |= ERR_ALERT | ERR_FATAL;
5198 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005199 }
5200 /* flush useless bits */
5201 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005202 cur_arg += 2;
5203 } else if (!strcmp(args[cur_arg], "header")) {
5204 /* suboption header - needs additional argument for it */
5205 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005206 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5207 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005208 err_code |= ERR_ALERT | ERR_FATAL;
5209 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005210 }
5211 free(curproxy->fwdfor_hdr_name);
5212 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5213 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5214 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005215 } else if (!strcmp(args[cur_arg], "if-none")) {
5216 curproxy->options &= ~PR_O_FF_ALWAYS;
5217 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005218 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005219 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005220 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5221 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005222 err_code |= ERR_ALERT | ERR_FATAL;
5223 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005224 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005225 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005226 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005227 else if (!strcmp(args[1], "originalto")) {
5228 int cur_arg;
5229
5230 /* insert x-original-to field, but not for the IP address listed as an except.
5231 * set default options (ie: bitfield, header name, etc)
5232 */
5233
5234 curproxy->options |= PR_O_ORGTO;
5235
5236 free(curproxy->orgto_hdr_name);
5237 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5238 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5239
Willy Tarreau87cf5142011-08-19 22:57:24 +02005240 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005241 cur_arg = 2;
5242 while (*(args[cur_arg])) {
5243 if (!strcmp(args[cur_arg], "except")) {
5244 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005245 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 +01005246 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5247 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005248 err_code |= ERR_ALERT | ERR_FATAL;
5249 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005250 }
5251 /* flush useless bits */
5252 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5253 cur_arg += 2;
5254 } else if (!strcmp(args[cur_arg], "header")) {
5255 /* suboption header - needs additional argument for it */
5256 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005257 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5258 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005259 err_code |= ERR_ALERT | ERR_FATAL;
5260 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005261 }
5262 free(curproxy->orgto_hdr_name);
5263 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5264 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5265 cur_arg += 2;
5266 } else {
5267 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005268 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5269 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005270 err_code |= ERR_ALERT | ERR_FATAL;
5271 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005272 }
5273 } /* end while loop */
5274 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005275 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005276 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005277 err_code |= ERR_ALERT | ERR_FATAL;
5278 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005279 }
Willy Tarreau93893792009-07-23 13:19:11 +02005280 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005281 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005282 else if (!strcmp(args[0], "default_backend")) {
5283 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005284 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005285
5286 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005287 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005288 err_code |= ERR_ALERT | ERR_FATAL;
5289 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005290 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005291 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005292 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005293
5294 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5295 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005296 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005297 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005298 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005299 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005300
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005301 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005302 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5303 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005304 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005305 /* enable reconnections to dispatch */
5306 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005307
5308 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5309 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005310 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005311 else if (!strcmp(args[0], "http-reuse")) {
5312 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5313 err_code |= ERR_WARN;
5314
5315 if (strcmp(args[1], "never") == 0) {
5316 /* enable a graceful server shutdown on an HTTP 404 response */
5317 curproxy->options &= ~PR_O_REUSE_MASK;
5318 curproxy->options |= PR_O_REUSE_NEVR;
5319 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5320 goto out;
5321 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005322 else if (strcmp(args[1], "safe") == 0) {
5323 /* enable a graceful server shutdown on an HTTP 404 response */
5324 curproxy->options &= ~PR_O_REUSE_MASK;
5325 curproxy->options |= PR_O_REUSE_SAFE;
5326 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5327 goto out;
5328 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005329 else if (strcmp(args[1], "aggressive") == 0) {
5330 curproxy->options &= ~PR_O_REUSE_MASK;
5331 curproxy->options |= PR_O_REUSE_AGGR;
5332 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5333 goto out;
5334 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005335 else if (strcmp(args[1], "always") == 0) {
5336 /* enable a graceful server shutdown on an HTTP 404 response */
5337 curproxy->options &= ~PR_O_REUSE_MASK;
5338 curproxy->options |= PR_O_REUSE_ALWS;
5339 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5340 goto out;
5341 }
5342 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005343 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005344 err_code |= ERR_ALERT | ERR_FATAL;
5345 goto out;
5346 }
5347 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005348 else if (!strcmp(args[0], "http-check")) {
5349 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005350 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005351
5352 if (strcmp(args[1], "disable-on-404") == 0) {
5353 /* enable a graceful server shutdown on an HTTP 404 response */
5354 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005355 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5356 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005357 }
Willy Tarreauef781042010-01-27 11:53:01 +01005358 else if (strcmp(args[1], "send-state") == 0) {
5359 /* enable emission of the apparent state of a server in HTTP checks */
5360 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005361 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5362 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005363 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005364 else if (strcmp(args[1], "expect") == 0) {
5365 const char *ptr_arg;
5366 int cur_arg;
5367
5368 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005369 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005370 err_code |= ERR_ALERT | ERR_FATAL;
5371 goto out;
5372 }
5373
5374 cur_arg = 2;
5375 /* consider exclamation marks, sole or at the beginning of a word */
5376 while (*(ptr_arg = args[cur_arg])) {
5377 while (*ptr_arg == '!') {
5378 curproxy->options2 ^= PR_O2_EXP_INV;
5379 ptr_arg++;
5380 }
5381 if (*ptr_arg)
5382 break;
5383 cur_arg++;
5384 }
5385 /* now ptr_arg points to the beginning of a word past any possible
5386 * exclamation mark, and cur_arg is the argument which holds this word.
5387 */
5388 if (strcmp(ptr_arg, "status") == 0) {
5389 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005390 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5391 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005392 err_code |= ERR_ALERT | ERR_FATAL;
5393 goto out;
5394 }
5395 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005396 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005397 curproxy->expect_str = strdup(args[cur_arg + 1]);
5398 }
5399 else if (strcmp(ptr_arg, "string") == 0) {
5400 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005401 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5402 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005403 err_code |= ERR_ALERT | ERR_FATAL;
5404 goto out;
5405 }
5406 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005407 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005408 curproxy->expect_str = strdup(args[cur_arg + 1]);
5409 }
5410 else if (strcmp(ptr_arg, "rstatus") == 0) {
5411 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005412 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5413 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005414 err_code |= ERR_ALERT | ERR_FATAL;
5415 goto out;
5416 }
5417 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005418 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005419 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005420 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005421 free(curproxy->expect_regex);
5422 curproxy->expect_regex = NULL;
5423 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005424 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005425 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5426 error = NULL;
5427 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005428 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5429 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005430 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005431 err_code |= ERR_ALERT | ERR_FATAL;
5432 goto out;
5433 }
5434 }
5435 else if (strcmp(ptr_arg, "rstring") == 0) {
5436 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005437 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5438 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005439 err_code |= ERR_ALERT | ERR_FATAL;
5440 goto out;
5441 }
5442 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005443 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005444 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005445 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005446 free(curproxy->expect_regex);
5447 curproxy->expect_regex = NULL;
5448 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005449 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005450 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5451 error = NULL;
5452 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005453 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5454 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005455 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005456 err_code |= ERR_ALERT | ERR_FATAL;
5457 goto out;
5458 }
5459 }
5460 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005461 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5462 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005463 err_code |= ERR_ALERT | ERR_FATAL;
5464 goto out;
5465 }
5466 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005467 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005468 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 +02005469 err_code |= ERR_ALERT | ERR_FATAL;
5470 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005471 }
5472 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005473 else if (!strcmp(args[0], "tcp-check")) {
5474 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5475 err_code |= ERR_WARN;
5476
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005477 if (strcmp(args[1], "comment") == 0) {
5478 int cur_arg;
5479 struct tcpcheck_rule *tcpcheck;
5480
5481 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005482 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005483 tcpcheck->action = TCPCHK_ACT_COMMENT;
5484
5485 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005486 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5487 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005488 err_code |= ERR_ALERT | ERR_FATAL;
5489 goto out;
5490 }
5491
5492 tcpcheck->comment = strdup(args[cur_arg + 1]);
5493
5494 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005495 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5496 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005497 }
5498 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005499 const char *ptr_arg;
5500 int cur_arg;
5501 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005502
5503 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005504 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5505 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5506 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5507 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5508 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005509
Willy Tarreau5581c272015-05-13 12:24:53 +02005510 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5511 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005512 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5513 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005514 err_code |= ERR_ALERT | ERR_FATAL;
5515 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005516 }
5517
5518 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005519 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005520 tcpcheck->action = TCPCHK_ACT_CONNECT;
5521
5522 /* parsing each parameters to fill up the rule */
5523 while (*(ptr_arg = args[cur_arg])) {
5524 /* tcp port */
5525 if (strcmp(args[cur_arg], "port") == 0) {
5526 if ( (atol(args[cur_arg + 1]) > 65535) ||
5527 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005528 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5529 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005530 err_code |= ERR_ALERT | ERR_FATAL;
5531 goto out;
5532 }
5533 tcpcheck->port = atol(args[cur_arg + 1]);
5534 cur_arg += 2;
5535 }
5536 /* send proxy protocol */
5537 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5538 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5539 cur_arg++;
5540 }
5541#ifdef USE_OPENSSL
5542 else if (strcmp(args[cur_arg], "ssl") == 0) {
5543 curproxy->options |= PR_O_TCPCHK_SSL;
5544 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5545 cur_arg++;
5546 }
5547#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005548 /* comment for this tcpcheck line */
5549 else if (strcmp(args[cur_arg], "comment") == 0) {
5550 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005551 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5552 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005553 err_code |= ERR_ALERT | ERR_FATAL;
5554 goto out;
5555 }
5556 tcpcheck->comment = strdup(args[cur_arg + 1]);
5557 cur_arg += 2;
5558 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005559 else {
5560#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005561 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 +01005562#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005563 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 +01005564#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005565 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005566 err_code |= ERR_ALERT | ERR_FATAL;
5567 goto out;
5568 }
5569
5570 }
5571
5572 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5573 }
5574 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005575 if (! *(args[2]) ) {
5576 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005577 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5578 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005579 err_code |= ERR_ALERT | ERR_FATAL;
5580 goto out;
5581 } else {
5582 struct tcpcheck_rule *tcpcheck;
5583
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005584 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005585
5586 tcpcheck->action = TCPCHK_ACT_SEND;
5587 tcpcheck->string_len = strlen(args[2]);
5588 tcpcheck->string = strdup(args[2]);
5589 tcpcheck->expect_regex = NULL;
5590
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005591 /* comment for this tcpcheck line */
5592 if (strcmp(args[3], "comment") == 0) {
5593 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005594 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5595 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005596 err_code |= ERR_ALERT | ERR_FATAL;
5597 goto out;
5598 }
5599 tcpcheck->comment = strdup(args[4]);
5600 }
5601
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005602 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5603 }
5604 }
5605 else if (strcmp(args[1], "send-binary") == 0) {
5606 if (! *(args[2]) ) {
5607 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005608 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5609 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005610 err_code |= ERR_ALERT | ERR_FATAL;
5611 goto out;
5612 } else {
5613 struct tcpcheck_rule *tcpcheck;
5614 char *err = NULL;
5615
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005616 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005617
5618 tcpcheck->action = TCPCHK_ACT_SEND;
5619 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005620 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5621 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005622 err_code |= ERR_ALERT | ERR_FATAL;
5623 goto out;
5624 }
5625 tcpcheck->expect_regex = NULL;
5626
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005627 /* comment for this tcpcheck line */
5628 if (strcmp(args[3], "comment") == 0) {
5629 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005630 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5631 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005632 err_code |= ERR_ALERT | ERR_FATAL;
5633 goto out;
5634 }
5635 tcpcheck->comment = strdup(args[4]);
5636 }
5637
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005638 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5639 }
5640 }
5641 else if (strcmp(args[1], "expect") == 0) {
5642 const char *ptr_arg;
5643 int cur_arg;
5644 int inverse = 0;
5645
5646 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005647 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005648 err_code |= ERR_ALERT | ERR_FATAL;
5649 goto out;
5650 }
5651
5652 cur_arg = 2;
5653 /* consider exclamation marks, sole or at the beginning of a word */
5654 while (*(ptr_arg = args[cur_arg])) {
5655 while (*ptr_arg == '!') {
5656 inverse = !inverse;
5657 ptr_arg++;
5658 }
5659 if (*ptr_arg)
5660 break;
5661 cur_arg++;
5662 }
5663 /* now ptr_arg points to the beginning of a word past any possible
5664 * exclamation mark, and cur_arg is the argument which holds this word.
5665 */
5666 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005667 struct tcpcheck_rule *tcpcheck;
5668 char *err = NULL;
5669
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005670 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005671 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5672 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005673 err_code |= ERR_ALERT | ERR_FATAL;
5674 goto out;
5675 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005676
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005677 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005678
5679 tcpcheck->action = TCPCHK_ACT_EXPECT;
5680 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005681 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5682 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005683 err_code |= ERR_ALERT | ERR_FATAL;
5684 goto out;
5685 }
5686 tcpcheck->expect_regex = NULL;
5687 tcpcheck->inverse = inverse;
5688
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005689 /* tcpcheck comment */
5690 cur_arg += 2;
5691 if (strcmp(args[cur_arg], "comment") == 0) {
5692 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005693 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5694 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005695 err_code |= ERR_ALERT | ERR_FATAL;
5696 goto out;
5697 }
5698 tcpcheck->comment = strdup(args[cur_arg + 1]);
5699 }
5700
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005701 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5702 }
5703 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005704 struct tcpcheck_rule *tcpcheck;
5705
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005706 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005707 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5708 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005709 err_code |= ERR_ALERT | ERR_FATAL;
5710 goto out;
5711 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005712
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005713 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005714
5715 tcpcheck->action = TCPCHK_ACT_EXPECT;
5716 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5717 tcpcheck->string = strdup(args[cur_arg + 1]);
5718 tcpcheck->expect_regex = NULL;
5719 tcpcheck->inverse = inverse;
5720
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005721 /* tcpcheck comment */
5722 cur_arg += 2;
5723 if (strcmp(args[cur_arg], "comment") == 0) {
5724 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005725 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5726 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005727 err_code |= ERR_ALERT | ERR_FATAL;
5728 goto out;
5729 }
5730 tcpcheck->comment = strdup(args[cur_arg + 1]);
5731 }
5732
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005733 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5734 }
5735 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005736 struct tcpcheck_rule *tcpcheck;
5737
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005738 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005739 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5740 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005741 err_code |= ERR_ALERT | ERR_FATAL;
5742 goto out;
5743 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005744
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005745 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005746
5747 tcpcheck->action = TCPCHK_ACT_EXPECT;
5748 tcpcheck->string_len = 0;
5749 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005750 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5751 error = NULL;
5752 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005753 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5754 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005755 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005756 err_code |= ERR_ALERT | ERR_FATAL;
5757 goto out;
5758 }
5759 tcpcheck->inverse = inverse;
5760
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005761 /* tcpcheck comment */
5762 cur_arg += 2;
5763 if (strcmp(args[cur_arg], "comment") == 0) {
5764 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005765 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5766 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005767 err_code |= ERR_ALERT | ERR_FATAL;
5768 goto out;
5769 }
5770 tcpcheck->comment = strdup(args[cur_arg + 1]);
5771 }
5772
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005773 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5774 }
5775 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005776 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5777 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005778 err_code |= ERR_ALERT | ERR_FATAL;
5779 goto out;
5780 }
5781 }
5782 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005783 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 +02005784 err_code |= ERR_ALERT | ERR_FATAL;
5785 goto out;
5786 }
5787 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005788 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005789 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005790 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005791 err_code |= ERR_ALERT | ERR_FATAL;
5792 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005793 }
5794
Willy Tarreaub80c2302007-11-30 20:51:32 +01005795 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005796 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005797
5798 if (strcmp(args[1], "fail") == 0) {
5799 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005800 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005801 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5802 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005803 err_code |= ERR_ALERT | ERR_FATAL;
5804 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005805 }
5806
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005807 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005808 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5809 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005810 err_code |= ERR_ALERT | ERR_FATAL;
5811 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005812 }
5813 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5814 }
5815 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005816 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005817 err_code |= ERR_ALERT | ERR_FATAL;
5818 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005819 }
5820 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005821#ifdef TPROXY
5822 else if (!strcmp(args[0], "transparent")) {
5823 /* enable transparent proxy connections */
5824 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005825 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5826 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005827 }
5828#endif
5829 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005830 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005831 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005832
Willy Tarreaubaaee002006-06-26 02:48:02 +02005833 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005834 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005835 err_code |= ERR_ALERT | ERR_FATAL;
5836 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005837 }
5838 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005839 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5840 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005841 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005842 else if (!strcmp(args[0], "backlog")) { /* backlog */
5843 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005844 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005845
5846 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005847 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005848 err_code |= ERR_ALERT | ERR_FATAL;
5849 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005850 }
5851 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005852 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5853 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005854 }
Willy Tarreau86034312006-12-29 00:10:33 +01005855 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005856 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005857 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005858
Willy Tarreau86034312006-12-29 00:10:33 +01005859 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005860 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005861 err_code |= ERR_ALERT | ERR_FATAL;
5862 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005863 }
5864 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005865 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5866 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005867 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005868 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5869 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005870 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005871 err_code |= ERR_ALERT | ERR_FATAL;
5872 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005873 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005874 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5875 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005876 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5877 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005878 err_code |= ERR_ALERT | ERR_FATAL;
5879 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005880 }
5881 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005882 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5883 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005884 }
5885 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005886 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005887 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005888 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005889
Willy Tarreaubaaee002006-06-26 02:48:02 +02005890 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005891 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005892 err_code |= ERR_ALERT | ERR_FATAL;
5893 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005894 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005895 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005896 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005897
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005898 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005899 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005900 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005901 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005902 goto out;
5903 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005904
5905 proto = protocol_by_family(sk->ss_family);
5906 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005907 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5908 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005909 err_code |= ERR_ALERT | ERR_FATAL;
5910 goto out;
5911 }
5912
5913 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005914 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5915 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005916 err_code |= ERR_ALERT | ERR_FATAL;
5917 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005918 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005919
5920 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005921 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5922 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005923 err_code |= ERR_ALERT | ERR_FATAL;
5924 goto out;
5925 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005926
William Lallemanddf1425a2015-04-28 20:17:49 +02005927 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5928 goto out;
5929
Willy Tarreaud5191e72010-02-09 20:50:45 +01005930 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005931 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005932 }
5933 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005934 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005935 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005936
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005937 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005938 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005939 err_code |= ERR_ALERT | ERR_FATAL;
5940 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005941 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005942 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005943 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005944 /**
5945 * The syntax for hash-type config element is
5946 * hash-type {map-based|consistent} [[<algo>] avalanche]
5947 *
5948 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5949 */
5950 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005951
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005952 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5953 err_code |= ERR_WARN;
5954
5955 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005956 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
5957 }
5958 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005959 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
5960 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005961 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005962 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 -05005963 err_code |= ERR_ALERT | ERR_FATAL;
5964 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01005965 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005966 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005967 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005968 err_code |= ERR_ALERT | ERR_FATAL;
5969 goto out;
5970 }
Bhaskar98634f02013-10-29 23:30:51 -04005971
5972 /* set the hash function to use */
5973 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005974 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04005975 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005976
5977 /* if consistent with no argument, then avalanche modifier is also applied */
5978 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
5979 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04005980 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005981 /* set the hash function */
5982 if (!strcmp(args[2], "sdbm")) {
5983 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
5984 }
5985 else if (!strcmp(args[2], "djb2")) {
5986 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01005987 }
5988 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01005989 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005990 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01005991 else if (!strcmp(args[2], "crc32")) {
5992 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
5993 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005994 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005995 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 -05005996 err_code |= ERR_ALERT | ERR_FATAL;
5997 goto out;
5998 }
5999
6000 /* set the hash modifier */
6001 if (!strcmp(args[3], "avalanche")) {
6002 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6003 }
6004 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006005 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 -05006006 err_code |= ERR_ALERT | ERR_FATAL;
6007 goto out;
6008 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006009 }
William Lallemanda73203e2012-03-12 12:48:57 +01006010 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006011 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6012 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006013 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006014 err_code |= ERR_ALERT | ERR_FATAL;
6015 goto out;
6016 }
6017 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6018 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006019 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 -04006020 err_code |= ERR_ALERT | ERR_FATAL;
6021 goto out;
6022 }
6023 }
William Lallemanda73203e2012-03-12 12:48:57 +01006024 else if (strcmp(args[0], "unique-id-format") == 0) {
6025 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006026 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006027 err_code |= ERR_ALERT | ERR_FATAL;
6028 goto out;
6029 }
William Lallemand3203ff42012-11-11 17:30:56 +01006030 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006031 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 +01006032 err_code |= ERR_ALERT | ERR_FATAL;
6033 goto out;
6034 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006035 free(curproxy->conf.uniqueid_format_string);
6036 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006037
Willy Tarreau62a61232013-04-12 18:13:46 +02006038 free(curproxy->conf.uif_file);
6039 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6040 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006041 }
William Lallemanda73203e2012-03-12 12:48:57 +01006042
6043 else if (strcmp(args[0], "unique-id-header") == 0) {
6044 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006045 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006046 err_code |= ERR_ALERT | ERR_FATAL;
6047 goto out;
6048 }
6049 free(curproxy->header_unique_id);
6050 curproxy->header_unique_id = strdup(args[1]);
6051 }
6052
William Lallemand723b73a2012-02-08 16:37:49 +01006053 else if (strcmp(args[0], "log-format") == 0) {
6054 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006055 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006056 err_code |= ERR_ALERT | ERR_FATAL;
6057 goto out;
6058 }
William Lallemand3203ff42012-11-11 17:30:56 +01006059 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006060 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 +01006061 err_code |= ERR_ALERT | ERR_FATAL;
6062 goto out;
6063 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006064 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6065 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006066
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006067 if (curproxy->conf.logformat_string == default_http_log_format)
6068 oldlogformat = "option httplog";
6069 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6070 oldlogformat = "option tcplog";
6071 else if (curproxy->conf.logformat_string == clf_http_log_format)
6072 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006073 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6074 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006075 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006076 if (curproxy->conf.logformat_string != default_http_log_format &&
6077 curproxy->conf.logformat_string != default_tcp_log_format &&
6078 curproxy->conf.logformat_string != clf_http_log_format)
6079 free(curproxy->conf.logformat_string);
6080 curproxy->conf.logformat_string = strdup(args[1]);
6081
6082 free(curproxy->conf.lfs_file);
6083 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6084 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006085
6086 /* get a chance to improve log-format error reporting by
6087 * reporting the correct line-number when possible.
6088 */
6089 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006090 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6091 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006092 err_code |= ERR_WARN;
6093 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006094 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006095 else if (!strcmp(args[0], "log-format-sd")) {
6096 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006097 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006098 err_code |= ERR_ALERT | ERR_FATAL;
6099 goto out;
6100 }
6101 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006102 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 +02006103 err_code |= ERR_ALERT | ERR_FATAL;
6104 goto out;
6105 }
6106
6107 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6108 free(curproxy->conf.logformat_sd_string);
6109 curproxy->conf.logformat_sd_string = strdup(args[1]);
6110
6111 free(curproxy->conf.lfsd_file);
6112 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6113 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6114
6115 /* get a chance to improve log-format-sd error reporting by
6116 * reporting the correct line-number when possible.
6117 */
6118 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006119 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6120 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006121 err_code |= ERR_WARN;
6122 }
6123 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006124 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6125 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006126 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 +01006127 err_code |= ERR_ALERT | ERR_FATAL;
6128 goto out;
6129 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006130 chunk_destroy(&curproxy->log_tag);
6131 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006132 }
William Lallemand0f99e342011-10-12 17:50:54 +02006133 else if (!strcmp(args[0], "log") && kwm == KWM_NO) {
6134 /* delete previous herited or defined syslog servers */
6135 struct logsrv *back;
6136
6137 if (*(args[1]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006138 ha_alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
William Lallemand0f99e342011-10-12 17:50:54 +02006139 err_code |= ERR_ALERT | ERR_FATAL;
6140 goto out;
6141 }
6142
William Lallemand723b73a2012-02-08 16:37:49 +01006143 list_for_each_entry_safe(tmplogsrv, back, &curproxy->logsrvs, list) {
6144 LIST_DEL(&tmplogsrv->list);
6145 free(tmplogsrv);
William Lallemand0f99e342011-10-12 17:50:54 +02006146 }
6147 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006148 else if (!strcmp(args[0], "log")) { /* syslog server address */
William Lallemand0f99e342011-10-12 17:50:54 +02006149 struct logsrv *logsrv;
6150
Willy Tarreaubaaee002006-06-26 02:48:02 +02006151 if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
William Lallemand0f99e342011-10-12 17:50:54 +02006152 /* copy global.logrsvs linked list to the end of curproxy->logsrvs */
William Lallemand723b73a2012-02-08 16:37:49 +01006153 list_for_each_entry(tmplogsrv, &global.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02006154 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01006155 memcpy(node, tmplogsrv, sizeof(struct logsrv));
William Lallemand0f99e342011-10-12 17:50:54 +02006156 LIST_INIT(&node->list);
6157 LIST_ADDQ(&curproxy->logsrvs, &node->list);
6158 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006159 }
6160 else if (*(args[1]) && *(args[2])) {
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006161 struct sockaddr_storage *sk;
6162 int port1, port2;
Willy Tarreau18324f52014-06-27 18:10:07 +02006163 int arg = 0;
6164 int len = 0;
William Lallemand0f99e342011-10-12 17:50:54 +02006165
Vincent Bernat02779b62016-04-03 13:48:43 +02006166 logsrv = calloc(1, sizeof(*logsrv));
Willy Tarreaubaaee002006-06-26 02:48:02 +02006167
Willy Tarreau18324f52014-06-27 18:10:07 +02006168 /* just after the address, a length may be specified */
6169 if (strcmp(args[arg+2], "len") == 0) {
6170 len = atoi(args[arg+3]);
6171 if (len < 80 || len > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006172 ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
6173 file, linenum, args[arg+3]);
Willy Tarreau18324f52014-06-27 18:10:07 +02006174 err_code |= ERR_ALERT | ERR_FATAL;
6175 goto out;
6176 }
6177 logsrv->maxlen = len;
6178
6179 /* skip these two args */
6180 arg += 2;
6181 }
6182 else
6183 logsrv->maxlen = MAX_SYSLOG_LEN;
6184
Christopher Faulet084aa962017-08-29 16:54:41 +02006185 if (logsrv->maxlen > global.max_syslog_len)
Willy Tarreau18324f52014-06-27 18:10:07 +02006186 global.max_syslog_len = logsrv->maxlen;
Willy Tarreau18324f52014-06-27 18:10:07 +02006187
Dragan Dosen1322d092015-09-22 16:05:32 +02006188 /* after the length, a format may be specified */
6189 if (strcmp(args[arg+2], "format") == 0) {
6190 logsrv->format = get_log_format(args[arg+3]);
6191 if (logsrv->format < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006192 ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
Dragan Dosen1322d092015-09-22 16:05:32 +02006193 err_code |= ERR_ALERT | ERR_FATAL;
6194 goto out;
6195 }
6196
6197 /* skip these two args */
6198 arg += 2;
6199 }
6200
William Lallemanddf1425a2015-04-28 20:17:49 +02006201 if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code))
6202 goto out;
6203
Willy Tarreau18324f52014-06-27 18:10:07 +02006204 logsrv->facility = get_log_facility(args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02006205 if (logsrv->facility < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006206 ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
William Lallemand0f99e342011-10-12 17:50:54 +02006207 err_code |= ERR_ALERT | ERR_FATAL;
6208 goto out;
6209
Willy Tarreaubaaee002006-06-26 02:48:02 +02006210 }
6211
William Lallemand0f99e342011-10-12 17:50:54 +02006212 logsrv->level = 7; /* max syslog level = debug */
Willy Tarreau18324f52014-06-27 18:10:07 +02006213 if (*(args[arg+3])) {
6214 logsrv->level = get_log_level(args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02006215 if (logsrv->level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006216 ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
William Lallemand0f99e342011-10-12 17:50:54 +02006217 err_code |= ERR_ALERT | ERR_FATAL;
6218 goto out;
6219
Willy Tarreaubaaee002006-06-26 02:48:02 +02006220 }
6221 }
6222
William Lallemand0f99e342011-10-12 17:50:54 +02006223 logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
Willy Tarreau18324f52014-06-27 18:10:07 +02006224 if (*(args[arg+4])) {
6225 logsrv->minlvl = get_log_level(args[arg+4]);
Willy Tarreauf7f057b2013-01-24 00:31:24 +01006226 if (logsrv->minlvl < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006227 ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
William Lallemand0f99e342011-10-12 17:50:54 +02006228 err_code |= ERR_ALERT | ERR_FATAL;
6229 goto out;
6230
Willy Tarreauf7edefa2009-05-10 17:20:05 +02006231 }
6232 }
6233
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006234 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006235 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006236 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006237 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006238 goto out;
6239 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006240
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006241 logsrv->addr = *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006242
Willy Tarreau9b435bc2013-03-06 15:02:49 +01006243 if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006244 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006245 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6246 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006247 err_code |= ERR_ALERT | ERR_FATAL;
6248 goto out;
6249 }
6250
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006251 if (!port1)
William Lallemand0f99e342011-10-12 17:50:54 +02006252 set_host_port(&logsrv->addr, SYSLOG_PORT);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006253 }
William Lallemand0f99e342011-10-12 17:50:54 +02006254
6255 LIST_ADDQ(&curproxy->logsrvs, &logsrv->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006256 }
6257 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006258 ha_alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
6259 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02006260 err_code |= ERR_ALERT | ERR_FATAL;
6261 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006262 }
6263 }
6264 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006265 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006266 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006267 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006268 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006269
Willy Tarreau977b8e42006-12-29 14:19:17 +01006270 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006271 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006272
Willy Tarreaubaaee002006-06-26 02:48:02 +02006273 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006274 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6275 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006276 err_code |= ERR_ALERT | ERR_FATAL;
6277 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006278 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006279
6280 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006281 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6282 free(curproxy->conn_src.iface_name);
6283 curproxy->conn_src.iface_name = NULL;
6284 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006285
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006286 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006287 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006288 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6289 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006290 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006291 goto out;
6292 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006293
6294 proto = protocol_by_family(sk->ss_family);
6295 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006296 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6297 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006298 err_code |= ERR_ALERT | ERR_FATAL;
6299 goto out;
6300 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006301
6302 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006303 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6304 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006305 err_code |= ERR_ALERT | ERR_FATAL;
6306 goto out;
6307 }
6308
Willy Tarreauef9a3602012-12-08 22:29:20 +01006309 curproxy->conn_src.source_addr = *sk;
6310 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006311
6312 cur_arg = 2;
6313 while (*(args[cur_arg])) {
6314 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006315#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006316 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006317 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6318 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006319 err_code |= ERR_ALERT | ERR_FATAL;
6320 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006321 }
6322
6323 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006324 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6325 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006326 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006327 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6328 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006329 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6330 char *name, *end;
6331
6332 name = args[cur_arg+1] + 7;
6333 while (isspace(*name))
6334 name++;
6335
6336 end = name;
6337 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6338 end++;
6339
Willy Tarreauef9a3602012-12-08 22:29:20 +01006340 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6341 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6342 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6343 curproxy->conn_src.bind_hdr_len = end - name;
6344 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6345 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6346 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006347
6348 /* now look for an occurrence number */
6349 while (isspace(*end))
6350 end++;
6351 if (*end == ',') {
6352 end++;
6353 name = end;
6354 if (*end == '-')
6355 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006356 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006357 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006358 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006359 }
6360
Willy Tarreauef9a3602012-12-08 22:29:20 +01006361 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006362 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6363 " occurrences values smaller than %d.\n",
6364 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006365 err_code |= ERR_ALERT | ERR_FATAL;
6366 goto out;
6367 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006368 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006369 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006370
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006371 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006372 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006373 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6374 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006375 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006376 goto out;
6377 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006378
6379 proto = protocol_by_family(sk->ss_family);
6380 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006381 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6382 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006383 err_code |= ERR_ALERT | ERR_FATAL;
6384 goto out;
6385 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006386
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006387 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006388 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6389 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006390 err_code |= ERR_ALERT | ERR_FATAL;
6391 goto out;
6392 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006393 curproxy->conn_src.tproxy_addr = *sk;
6394 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006395 }
6396 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006397#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006398 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6399 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006400 err_code |= ERR_ALERT | ERR_FATAL;
6401 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006402#endif
6403 cur_arg += 2;
6404 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006405 }
6406
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006407 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6408#ifdef SO_BINDTODEVICE
6409 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006410 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6411 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006412 err_code |= ERR_ALERT | ERR_FATAL;
6413 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006414 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006415 free(curproxy->conn_src.iface_name);
6416 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6417 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006418 global.last_checks |= LSTCHK_NETADM;
6419#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006420 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6421 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006422 err_code |= ERR_ALERT | ERR_FATAL;
6423 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006424#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006425 cur_arg += 2;
6426 continue;
6427 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006428 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6429 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006430 err_code |= ERR_ALERT | ERR_FATAL;
6431 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006432 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006433 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006434 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006435 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6436 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006437 err_code |= ERR_ALERT | ERR_FATAL;
6438 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006439 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006440 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006441 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006442 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6443 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006444 err_code |= ERR_ALERT | ERR_FATAL;
6445 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006446 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006447
6448 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006449 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006450 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006451 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006452 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006453 }
6454 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006455 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006456 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006457 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006458 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006459 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006460 }
6461 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006462 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006463 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006464 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006465 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006466 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006467 }
6468 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006469 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006470 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006471 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006472 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006473 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006474 }
6475 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006476 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006477 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006478 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006479 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006480 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006481 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006482 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006483 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006484 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006485 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006486 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006487 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006488 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006489 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006490 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006491 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6492 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006493 err_code |= ERR_ALERT | ERR_FATAL;
6494 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006495 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006496
6497 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006498 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006499 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006500 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006501 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006502 }
6503 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006504 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006505 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006506 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006507 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006508 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006509 }
6510 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006511 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006512 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006513 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006514 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006515 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006516 }
6517 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006518 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006519 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006520 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006521 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006522 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006523 }
6524 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006525 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006526 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006527 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006528 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006529 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006530 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006531 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006532 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006533 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006534 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006535 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006536 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006537 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006538 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006539 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006540
Willy Tarreaubaaee002006-06-26 02:48:02 +02006541 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006542 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006543 err_code |= ERR_ALERT | ERR_FATAL;
6544 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006545 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006546 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006547 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006548
Willy Tarreaubaaee002006-06-26 02:48:02 +02006549 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006550 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006551 err_code |= ERR_ALERT | ERR_FATAL;
6552 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006553 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006554
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006555 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006556 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006557 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6558 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006559 err_code |= ERR_ALERT | ERR_FATAL;
6560 goto out;
6561 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006562 err_code |= warnif_cond_conflicts(cond,
6563 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6564 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006565 }
6566 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006567 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6568 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006569 err_code |= ERR_ALERT | ERR_FATAL;
6570 goto out;
6571 }
6572
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006573 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006574 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006575 wl->s = strdup(args[1]);
6576 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006577 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006578 }
6579 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006580 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006581 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6582 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006583 err_code |= ERR_ALERT | ERR_FATAL;
6584 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006585 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006586
Willy Tarreauade5ec42010-01-28 19:33:49 +01006587 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006588 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006589 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006590 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006591 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006592 }
6593 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006594 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006595 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006596 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006597 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006598 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006599 }
6600 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006601 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006602 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006603 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006604 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006605 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006606 }
6607 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006608 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006609 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6610 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006611 err_code |= ERR_ALERT | ERR_FATAL;
6612 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006613 }
6614
Willy Tarreauade5ec42010-01-28 19:33:49 +01006615 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006616 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006617 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006618 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006619 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006620 }
6621 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006622 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006623 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006624 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006625 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006626 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006627 }
6628 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006629 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006630 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006631 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006632 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006633 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006634 }
6635 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006636 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006637
Willy Tarreaubaaee002006-06-26 02:48:02 +02006638 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006639 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006640 err_code |= ERR_ALERT | ERR_FATAL;
6641 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006642 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006643 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006644 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006645
Willy Tarreaubaaee002006-06-26 02:48:02 +02006646 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006647 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006648 err_code |= ERR_ALERT | ERR_FATAL;
6649 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006650 }
6651
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006652 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006653 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006654 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6655 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006656 err_code |= ERR_ALERT | ERR_FATAL;
6657 goto out;
6658 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006659 err_code |= warnif_cond_conflicts(cond,
6660 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6661 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006662 }
6663 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006664 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6665 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006666 err_code |= ERR_ALERT | ERR_FATAL;
6667 goto out;
6668 }
6669
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006670 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006671 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006672 wl->s = strdup(args[1]);
6673 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006674 }
6675 else if (!strcmp(args[0], "errorloc") ||
6676 !strcmp(args[0], "errorloc302") ||
6677 !strcmp(args[0], "errorloc303")) { /* error location */
6678 int errnum, errlen;
6679 char *err;
6680
Willy Tarreau977b8e42006-12-29 14:19:17 +01006681 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006682 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006683
Willy Tarreaubaaee002006-06-26 02:48:02 +02006684 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006685 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 +02006686 err_code |= ERR_ALERT | ERR_FATAL;
6687 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006688 }
6689
6690 errnum = atol(args[1]);
6691 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006692 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6693 err = malloc(errlen);
6694 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006695 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006696 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6697 err = malloc(errlen);
6698 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006699 }
6700
Willy Tarreau0f772532006-12-23 20:51:41 +01006701 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6702 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006703 chunk_destroy(&curproxy->errmsg[rc]);
6704 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006705 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006706 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006707 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006708
6709 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006710 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6711 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006712 free(err);
6713 }
6714 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006715 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6716 int errnum, errlen, fd;
6717 char *err;
6718 struct stat stat;
6719
6720 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006721 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006722
6723 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006724 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 +02006725 err_code |= ERR_ALERT | ERR_FATAL;
6726 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006727 }
6728
6729 fd = open(args[2], O_RDONLY);
6730 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006731 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6732 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006733 if (fd >= 0)
6734 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006735 err_code |= ERR_ALERT | ERR_FATAL;
6736 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006737 }
6738
Willy Tarreau27a674e2009-08-17 07:23:33 +02006739 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006740 errlen = stat.st_size;
6741 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006742 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6743 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006744 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006745 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006746 }
6747
6748 err = malloc(errlen); /* malloc() must succeed during parsing */
6749 errnum = read(fd, err, errlen);
6750 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006751 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6752 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006753 close(fd);
6754 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006755 err_code |= ERR_ALERT | ERR_FATAL;
6756 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006757 }
6758 close(fd);
6759
6760 errnum = atol(args[1]);
6761 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6762 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006763 chunk_destroy(&curproxy->errmsg[rc]);
6764 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006765 break;
6766 }
6767 }
6768
6769 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006770 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6771 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006772 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006773 free(err);
6774 }
6775 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006776 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006777 struct cfg_kw_list *kwl;
6778 int index;
6779
6780 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6781 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6782 if (kwl->kw[index].section != CFG_LISTEN)
6783 continue;
6784 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6785 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006786 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006787 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006788 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006789 err_code |= ERR_ALERT | ERR_FATAL;
6790 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006791 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006792 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006793 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006794 err_code |= ERR_WARN;
6795 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006796 }
Willy Tarreau93893792009-07-23 13:19:11 +02006797 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006798 }
6799 }
6800 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006801
Christopher Faulet767a84b2017-11-24 16:50:31 +01006802 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006803 err_code |= ERR_ALERT | ERR_FATAL;
6804 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006805 }
Willy Tarreau93893792009-07-23 13:19:11 +02006806 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006807 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006808 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006809}
6810
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006811int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006812cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6813{
6814#ifdef CONFIG_HAP_NS
6815 const char *err;
6816 const char *item = args[0];
6817
6818 if (!strcmp(item, "namespace_list")) {
6819 return 0;
6820 }
6821 else if (!strcmp(item, "namespace")) {
6822 size_t idx = 1;
6823 const char *current;
6824 while (*(current = args[idx++])) {
6825 err = invalid_char(current);
6826 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006827 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6828 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006829 return ERR_ALERT | ERR_FATAL;
6830 }
6831
6832 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006833 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6834 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006835 return ERR_ALERT | ERR_FATAL;
6836 }
6837 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006838 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6839 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006840 return ERR_ALERT | ERR_FATAL;
6841 }
6842 }
6843 }
6844
6845 return 0;
6846#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006847 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6848 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006849 return ERR_ALERT | ERR_FATAL;
6850#endif
6851}
6852
6853int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006854cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6855{
6856
6857 int err_code = 0;
6858 const char *err;
6859
6860 if (!strcmp(args[0], "userlist")) { /* new userlist */
6861 struct userlist *newul;
6862
6863 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006864 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6865 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006866 err_code |= ERR_ALERT | ERR_FATAL;
6867 goto out;
6868 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006869 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6870 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006871
6872 err = invalid_char(args[1]);
6873 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006874 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6875 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006876 err_code |= ERR_ALERT | ERR_FATAL;
6877 goto out;
6878 }
6879
6880 for (newul = userlist; newul; newul = newul->next)
6881 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006882 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6883 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006884 err_code |= ERR_WARN;
6885 goto out;
6886 }
6887
Vincent Bernat02779b62016-04-03 13:48:43 +02006888 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006889 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006890 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006891 err_code |= ERR_ALERT | ERR_ABORT;
6892 goto out;
6893 }
6894
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006895 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006896 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006897 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006898 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006899 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006900 goto out;
6901 }
6902
6903 newul->next = userlist;
6904 userlist = newul;
6905
6906 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006907 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006908 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006909 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006910
6911 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006912 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6913 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006914 err_code |= ERR_ALERT | ERR_FATAL;
6915 goto out;
6916 }
6917
6918 err = invalid_char(args[1]);
6919 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006920 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6921 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006922 err_code |= ERR_ALERT | ERR_FATAL;
6923 goto out;
6924 }
6925
William Lallemand4ac9f542015-05-28 18:03:51 +02006926 if (!userlist)
6927 goto out;
6928
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006929 for (ag = userlist->groups; ag; ag = ag->next)
6930 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006931 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6932 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006933 err_code |= ERR_ALERT;
6934 goto out;
6935 }
6936
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006937 ag = calloc(1, sizeof(*ag));
6938 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006939 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006940 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006941 goto out;
6942 }
6943
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006944 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006945 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006946 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006947 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006948 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006949 goto out;
6950 }
6951
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006952 cur_arg = 2;
6953
6954 while (*args[cur_arg]) {
6955 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006956 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006957 cur_arg += 2;
6958 continue;
6959 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006960 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6961 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006962 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006963 free(ag->groupusers);
6964 free(ag->name);
6965 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006966 goto out;
6967 }
6968 }
6969
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006970 ag->next = userlist->groups;
6971 userlist->groups = ag;
6972
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006973 } else if (!strcmp(args[0], "user")) { /* new user */
6974 struct auth_users *newuser;
6975 int cur_arg;
6976
6977 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006978 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6979 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006980 err_code |= ERR_ALERT | ERR_FATAL;
6981 goto out;
6982 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006983 if (!userlist)
6984 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006985
6986 for (newuser = userlist->users; newuser; newuser = newuser->next)
6987 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006988 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6989 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006990 err_code |= ERR_ALERT;
6991 goto out;
6992 }
6993
Vincent Bernat02779b62016-04-03 13:48:43 +02006994 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006995 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006996 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006997 err_code |= ERR_ALERT | ERR_ABORT;
6998 goto out;
6999 }
7000
7001 newuser->user = strdup(args[1]);
7002
7003 newuser->next = userlist->users;
7004 userlist->users = newuser;
7005
7006 cur_arg = 2;
7007
7008 while (*args[cur_arg]) {
7009 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02007010#ifdef CONFIG_HAP_CRYPT
7011 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007012 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
7013 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02007014 err_code |= ERR_ALERT | ERR_FATAL;
7015 goto out;
7016 }
7017#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01007018 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
7019 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007020 err_code |= ERR_ALERT;
7021#endif
7022 newuser->pass = strdup(args[cur_arg + 1]);
7023 cur_arg += 2;
7024 continue;
7025 } else if (!strcmp(args[cur_arg], "insecure-password")) {
7026 newuser->pass = strdup(args[cur_arg + 1]);
7027 newuser->flags |= AU_O_INSECURE;
7028 cur_arg += 2;
7029 continue;
7030 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007031 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007032 cur_arg += 2;
7033 continue;
7034 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007035 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
7036 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007037 err_code |= ERR_ALERT | ERR_FATAL;
7038 goto out;
7039 }
7040 }
7041 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007042 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 +01007043 err_code |= ERR_ALERT | ERR_FATAL;
7044 }
7045
7046out:
7047 return err_code;
7048}
Willy Tarreaubaaee002006-06-26 02:48:02 +02007049
Christopher Faulet79bdef32016-11-04 22:36:15 +01007050int
7051cfg_parse_scope(const char *file, int linenum, char *line)
7052{
7053 char *beg, *end, *scope = NULL;
7054 int err_code = 0;
7055 const char *err;
7056
7057 beg = line + 1;
7058 end = strchr(beg, ']');
7059
7060 /* Detect end of scope declaration */
7061 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007062 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
7063 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007064 err_code |= ERR_ALERT | ERR_FATAL;
7065 goto out;
7066 }
7067
7068 /* Get scope name and check its validity */
7069 scope = my_strndup(beg, end-beg);
7070 err = invalid_char(scope);
7071 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007072 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
7073 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007074 err_code |= ERR_ALERT | ERR_ABORT;
7075 goto out;
7076 }
7077
7078 /* Be sure to have a scope declaration alone on its line */
7079 line = end+1;
7080 while (isspace((unsigned char)*line))
7081 line++;
7082 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007083 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7084 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007085 err_code |= ERR_ALERT | ERR_ABORT;
7086 goto out;
7087 }
7088
7089 /* We have a valid scope declaration, save it */
7090 free(cfg_scope);
7091 cfg_scope = scope;
7092 scope = NULL;
7093
7094 out:
7095 free(scope);
7096 return err_code;
7097}
7098
Willy Tarreaubaaee002006-06-26 02:48:02 +02007099/*
7100 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007101 * Returns the error code, 0 if OK, or any combination of :
7102 * - ERR_ABORT: must abort ASAP
7103 * - ERR_FATAL: we can continue parsing but not start the service
7104 * - ERR_WARN: a warning has been emitted
7105 * - ERR_ALERT: an alert has been emitted
7106 * Only the two first ones can stop processing, the two others are just
7107 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007108 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007109int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007110{
William Lallemand64e84512015-05-12 14:25:37 +02007111 char *thisline;
7112 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007113 FILE *f;
7114 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007115 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007116 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007117 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007118 int readbytes = 0;
7119
7120 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007121 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007122 return -1;
7123 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007124
David Carlier97880bb2016-04-08 10:35:26 +01007125 if ((f=fopen(file,"r")) == NULL) {
7126 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007127 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007128 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007129
William Lallemandb2f07452015-05-12 14:27:13 +02007130next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007131 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007132 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007133 char *end;
7134 char *args[MAX_LINE_ARGS + 1];
7135 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007136 int dquote = 0; /* double quote */
7137 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007138
Willy Tarreaubaaee002006-06-26 02:48:02 +02007139 linenum++;
7140
7141 end = line + strlen(line);
7142
William Lallemand64e84512015-05-12 14:25:37 +02007143 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007144 /* Check if we reached the limit and the last char is not \n.
7145 * Watch out for the last line without the terminating '\n'!
7146 */
William Lallemand64e84512015-05-12 14:25:37 +02007147 char *newline;
7148 int newlinesize = linesize * 2;
7149
7150 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7151 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007152 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7153 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007154 err_code |= ERR_ALERT | ERR_FATAL;
7155 continue;
7156 }
7157
7158 readbytes = linesize - 1;
7159 linesize = newlinesize;
7160 thisline = newline;
7161 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007162 }
7163
William Lallemand64e84512015-05-12 14:25:37 +02007164 readbytes = 0;
7165
Willy Tarreaubaaee002006-06-26 02:48:02 +02007166 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007167 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007168 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007169
Christopher Faulet79bdef32016-11-04 22:36:15 +01007170
7171 if (*line == '[') {/* This is the begining if a scope */
7172 err_code |= cfg_parse_scope(file, linenum, line);
7173 goto next_line;
7174 }
7175
Willy Tarreaubaaee002006-06-26 02:48:02 +02007176 arg = 0;
7177 args[arg] = line;
7178
7179 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007180 if (*line == '"' && !squote) { /* double quote outside single quotes */
7181 if (dquote)
7182 dquote = 0;
7183 else
7184 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007185 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007186 end--;
7187 }
7188 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7189 if (squote)
7190 squote = 0;
7191 else
7192 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007193 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007194 end--;
7195 }
7196 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007197 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7198 * C equivalent value. Other combinations left unchanged (eg: \1).
7199 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007200 int skip = 0;
7201 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7202 *line = line[1];
7203 skip = 1;
7204 }
7205 else if (line[1] == 'r') {
7206 *line = '\r';
7207 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007208 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007209 else if (line[1] == 'n') {
7210 *line = '\n';
7211 skip = 1;
7212 }
7213 else if (line[1] == 't') {
7214 *line = '\t';
7215 skip = 1;
7216 }
7217 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007218 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007219 unsigned char hex1, hex2;
7220 hex1 = toupper(line[2]) - '0';
7221 hex2 = toupper(line[3]) - '0';
7222 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7223 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7224 *line = (hex1<<4) + hex2;
7225 skip = 3;
7226 }
7227 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007228 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007229 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007230 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007231 } else if (line[1] == '"') {
7232 *line = '"';
7233 skip = 1;
7234 } else if (line[1] == '\'') {
7235 *line = '\'';
7236 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007237 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7238 *line = '$';
7239 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007240 }
7241 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007242 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007243 end -= skip;
7244 }
7245 line++;
7246 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007247 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007248 /* end of string, end of loop */
7249 *line = 0;
7250 break;
7251 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007252 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007253 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007254 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007255 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007256 line++;
7257 args[++arg] = line;
7258 }
William Lallemandb2f07452015-05-12 14:27:13 +02007259 else if (dquote && *line == '$') {
7260 /* environment variables are evaluated inside double quotes */
7261 char *var_beg;
7262 char *var_end;
7263 char save_char;
7264 char *value;
7265 int val_len;
7266 int newlinesize;
7267 int braces = 0;
7268
7269 var_beg = line + 1;
7270 var_end = var_beg;
7271
7272 if (*var_beg == '{') {
7273 var_beg++;
7274 var_end++;
7275 braces = 1;
7276 }
7277
7278 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007279 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 +02007280 err_code |= ERR_ALERT | ERR_FATAL;
7281 goto next_line; /* skip current line */
7282 }
7283
7284 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7285 var_end++;
7286
7287 save_char = *var_end;
7288 *var_end = '\0';
7289 value = getenv(var_beg);
7290 *var_end = save_char;
7291 val_len = value ? strlen(value) : 0;
7292
7293 if (braces) {
7294 if (*var_end == '}') {
7295 var_end++;
7296 braces = 0;
7297 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007298 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007299 err_code |= ERR_ALERT | ERR_FATAL;
7300 goto next_line; /* skip current line */
7301 }
7302 }
7303
7304 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7305
7306 /* if not enough space in thisline */
7307 if (newlinesize > linesize) {
7308 char *newline;
7309
7310 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7311 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007312 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007313 err_code |= ERR_ALERT | ERR_FATAL;
7314 goto next_line; /* slip current line */
7315 }
7316 /* recompute pointers if realloc returns a new pointer */
7317 if (newline != thisline) {
7318 int i;
7319 int diff;
7320
7321 for (i = 0; i <= arg; i++) {
7322 diff = args[i] - thisline;
7323 args[i] = newline + diff;
7324 }
7325
7326 diff = var_end - thisline;
7327 var_end = newline + diff;
7328 diff = end - thisline;
7329 end = newline + diff;
7330 diff = line - thisline;
7331 line = newline + diff;
7332 thisline = newline;
7333 }
7334 linesize = newlinesize;
7335 }
7336
7337 /* insert value inside the line */
7338 memmove(line + val_len, var_end, end - var_end + 1);
7339 memcpy(line, value, val_len);
7340 end += val_len - (var_end - line);
7341 line += val_len;
7342 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007343 else {
7344 line++;
7345 }
7346 }
William Lallemandb2f07452015-05-12 14:27:13 +02007347
William Lallemandf9873ba2015-05-05 17:37:14 +02007348 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007349 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007350 err_code |= ERR_ALERT | ERR_FATAL;
7351 }
7352
7353 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007354 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007355 err_code |= ERR_ALERT | ERR_FATAL;
7356 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007357
7358 /* empty line */
7359 if (!**args)
7360 continue;
7361
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007362 if (*line) {
7363 /* we had to stop due to too many args.
7364 * Let's terminate the string, print the offending part then cut the
7365 * last arg.
7366 */
7367 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7368 line++;
7369 *line = '\0';
7370
Christopher Faulet767a84b2017-11-24 16:50:31 +01007371 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7372 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007373 err_code |= ERR_ALERT | ERR_FATAL;
7374 args[arg] = line;
7375 }
7376
Willy Tarreau540abe42007-05-02 20:50:16 +02007377 /* zero out remaining args and ensure that at least one entry
7378 * is zeroed out.
7379 */
7380 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007381 args[arg] = line;
7382 }
7383
Willy Tarreau3842f002009-06-14 11:39:52 +02007384 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007385 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007386 char *tmp;
7387
Willy Tarreau3842f002009-06-14 11:39:52 +02007388 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007389 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007390 for (arg=0; *args[arg+1]; arg++)
7391 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007392 *tmp = '\0'; // fix the next arg to \0
7393 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007394 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007395 else if (!strcmp(args[0], "default")) {
7396 kwm = KWM_DEF;
7397 for (arg=0; *args[arg+1]; arg++)
7398 args[arg] = args[arg+1]; // shift args after inversion
7399 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007400
William Lallemand0f99e342011-10-12 17:50:54 +02007401 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7402 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007403 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007404 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007405 }
7406
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007407 /* detect section start */
7408 list_for_each_entry(ics, &sections, list) {
7409 if (strcmp(args[0], ics->section_name) == 0) {
7410 cursection = ics->section_name;
7411 cs = ics;
7412 break;
7413 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007414 }
7415
William Lallemandd2ff56d2017-10-16 11:06:50 +02007416 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007417 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007418 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007419 } else {
7420 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007421
William Lallemandd2ff56d2017-10-16 11:06:50 +02007422 if (pcs != cs && pcs && pcs->post_section_parser) {
7423 err_code |= pcs->post_section_parser();
7424 if (err_code & ERR_ABORT)
7425 goto err;
7426 }
7427
7428 err_code |= cs->section_parser(file, linenum, args, kwm);
7429 if (err_code & ERR_ABORT)
7430 goto err;
7431 }
7432 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007433 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007434
7435 if (pcs == cs && pcs && pcs->post_section_parser)
7436 err_code |= pcs->post_section_parser();
7437
7438err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007439 free(cfg_scope);
7440 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007441 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007442 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007443 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007444 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007445}
7446
Willy Tarreau64ab6072014-09-16 12:17:36 +02007447/* This function propagates processes from frontend <from> to backend <to> so
7448 * that it is always guaranteed that a backend pointed to by a frontend is
7449 * bound to all of its processes. After that, if the target is a "listen"
7450 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007451 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007452 * checked first to ensure that <to> is already bound to all processes of
7453 * <from>, there is no risk of looping and we ensure to follow the shortest
7454 * path to the destination.
7455 *
7456 * It is possible to set <to> to NULL for the first call so that the function
7457 * takes care of visiting the initial frontend in <from>.
7458 *
7459 * It is important to note that the function relies on the fact that all names
7460 * have already been resolved.
7461 */
7462void propagate_processes(struct proxy *from, struct proxy *to)
7463{
7464 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007465
7466 if (to) {
7467 /* check whether we need to go down */
7468 if (from->bind_proc &&
7469 (from->bind_proc & to->bind_proc) == from->bind_proc)
7470 return;
7471
7472 if (!from->bind_proc && !to->bind_proc)
7473 return;
7474
7475 to->bind_proc = from->bind_proc ?
7476 (to->bind_proc | from->bind_proc) : 0;
7477
7478 /* now propagate down */
7479 from = to;
7480 }
7481
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007482 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007483 return;
7484
Willy Tarreauf6b70012014-12-18 14:00:43 +01007485 if (from->state == PR_STSTOPPED)
7486 return;
7487
Willy Tarreau64ab6072014-09-16 12:17:36 +02007488 /* default_backend */
7489 if (from->defbe.be)
7490 propagate_processes(from, from->defbe.be);
7491
7492 /* use_backend */
7493 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007494 if (rule->dynamic)
7495 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007496 to = rule->be.backend;
7497 propagate_processes(from, to);
7498 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007499}
7500
Willy Tarreaubb925012009-07-23 13:36:36 +02007501/*
7502 * Returns the error code, 0 if OK, or any combination of :
7503 * - ERR_ABORT: must abort ASAP
7504 * - ERR_FATAL: we can continue parsing but not start the service
7505 * - ERR_WARN: a warning has been emitted
7506 * - ERR_ALERT: an alert has been emitted
7507 * Only the two first ones can stop processing, the two others are just
7508 * indicators.
7509 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007510int check_config_validity()
7511{
7512 int cfgerr = 0;
7513 struct proxy *curproxy = NULL;
7514 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007515 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007516 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007517 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007518 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007519 struct cfg_postparser *postparser;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007520
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007521 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007522 /*
7523 * Now, check for the integrity of all that we have collected.
7524 */
7525
7526 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007527 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007528
Willy Tarreau193b8c62012-11-22 00:17:38 +01007529 if (!global.tune.max_http_hdr)
7530 global.tune.max_http_hdr = MAX_HTTP_HDR;
7531
7532 if (!global.tune.cookie_len)
7533 global.tune.cookie_len = CAPTURE_LEN;
7534
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007535 if (!global.tune.requri_len)
7536 global.tune.requri_len = REQURI_LEN;
7537
Willy Tarreaubafbe012017-11-24 17:34:44 +01007538 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007539
Willy Tarreaubafbe012017-11-24 17:34:44 +01007540 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007541
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007542 /* Post initialisation of the users and groups lists. */
7543 err_code = userlist_postinit();
7544 if (err_code != ERR_NONE)
7545 goto out;
7546
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007547 /* first, we will invert the proxy list order */
7548 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007549 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007550 struct proxy *next;
7551
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007552 next = proxies_list->next;
7553 proxies_list->next = curproxy;
7554 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007555 if (!next)
7556 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007557 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007558 }
7559
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007560 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007561 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007562 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007563 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007564 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007565 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007566 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007567 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007568
Willy Tarreau050536d2012-10-04 08:47:34 +02007569 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007570 /* proxy ID not set, use automatic numbering with first
7571 * spare entry starting with next_pxid.
7572 */
7573 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7574 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7575 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007576 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007577 next_pxid++;
7578
Willy Tarreau55ea7572007-06-17 19:56:27 +02007579
Willy Tarreaubaaee002006-06-26 02:48:02 +02007580 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007581 /* ensure we don't keep listeners uselessly bound */
7582 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007583 free((void *)curproxy->table.peers.name);
7584 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007585 continue;
7586 }
7587
Willy Tarreau102df612014-05-07 23:56:38 +02007588 /* Check multi-process mode compatibility for the current proxy */
7589
7590 if (curproxy->bind_proc) {
7591 /* an explicit bind-process was specified, let's check how many
7592 * processes remain.
7593 */
David Carliere6c39412015-07-02 07:00:17 +00007594 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007595
7596 curproxy->bind_proc &= nbits(global.nbproc);
7597 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007598 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 +02007599 curproxy->bind_proc = 1;
7600 }
7601 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007602 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 +02007603 curproxy->bind_proc = 0;
7604 }
7605 }
7606
Willy Tarreau3d209582014-05-09 17:06:11 +02007607 /* check and reduce the bind-proc of each listener */
7608 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7609 unsigned long mask;
7610
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007611 /* HTTP frontends with "h2" as ALPN/NPN will work in
7612 * HTTP/2 and absolutely require buffers 16kB or larger.
7613 */
7614#ifdef USE_OPENSSL
7615 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7616#ifdef OPENSSL_NPN_NEGOTIATED
7617 /* check NPN */
7618 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007619 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",
7620 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007621 cfgerr++;
7622 }
7623#endif
7624#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7625 /* check ALPN */
7626 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007627 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",
7628 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007629 cfgerr++;
7630 }
7631#endif
7632 } /* HTTP && bufsize < 16384 */
7633#endif
7634
Willy Tarreau3d209582014-05-09 17:06:11 +02007635 if (!bind_conf->bind_proc)
7636 continue;
7637
7638 mask = nbits(global.nbproc);
7639 if (curproxy->bind_proc)
7640 mask &= curproxy->bind_proc;
7641 /* mask cannot be null here thanks to the previous checks */
7642
David Carliere6c39412015-07-02 07:00:17 +00007643 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007644 bind_conf->bind_proc &= mask;
7645
7646 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007647 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",
7648 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007649 bind_conf->bind_proc = mask & ~(mask - 1);
7650 }
7651 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007652 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",
7653 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007654 bind_conf->bind_proc = 0;
7655 }
7656 }
7657
Willy Tarreauff01a212009-03-15 13:46:16 +01007658 switch (curproxy->mode) {
7659 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007660 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007661 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007662 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7663 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007664 cfgerr++;
7665 }
7666
7667 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007668 ha_warning("config : servers will be ignored for %s '%s'.\n",
7669 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007670 break;
7671
7672 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007673 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007674 break;
7675
7676 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007677 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007678 break;
7679 }
7680
Willy Tarreauf3934b82015-08-11 11:36:45 +02007681 if ((curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007682 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7683 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007684 err_code |= ERR_WARN;
7685 }
7686
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007687 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007688 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007689 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007690 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7691 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007692 cfgerr++;
7693 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007694#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007695 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007696 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7697 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007698 cfgerr++;
7699 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007700#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007701 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007702 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7703 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007704 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007705 }
7706 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007707 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007708 /* If no LB algo is set in a backend, and we're not in
7709 * transparent mode, dispatch mode nor proxy mode, we
7710 * want to use balance roundrobin by default.
7711 */
7712 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7713 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007714 }
7715 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007716
Willy Tarreau1620ec32011-08-06 17:05:02 +02007717 if (curproxy->options & PR_O_DISPATCH)
7718 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7719 else if (curproxy->options & PR_O_HTTP_PROXY)
7720 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7721 else if (curproxy->options & PR_O_TRANSP)
7722 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007723
Willy Tarreau1620ec32011-08-06 17:05:02 +02007724 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7725 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007726 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7727 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007728 err_code |= ERR_WARN;
7729 curproxy->options &= ~PR_O_DISABLE404;
7730 }
7731 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007732 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7733 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007734 err_code |= ERR_WARN;
7735 curproxy->options &= ~PR_O2_CHK_SNDST;
7736 }
Willy Tarreauef781042010-01-27 11:53:01 +01007737 }
7738
Simon Horman98637e52014-06-20 12:30:16 +09007739 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7740 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007741 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7742 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007743 cfgerr++;
7744 }
7745 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007746 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7747 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007748 cfgerr++;
7749 }
7750 }
7751
Simon Horman64e34162015-02-06 11:11:57 +09007752 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007753 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007754 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7755 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7756 "'email-alert myhostname', or 'email-alert to' "
7757 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7758 "to be present).\n",
7759 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007760 err_code |= ERR_WARN;
7761 free_email_alert(curproxy);
7762 }
7763 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007764 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007765 }
7766
Simon Horman98637e52014-06-20 12:30:16 +09007767 if (curproxy->check_command) {
7768 int clear = 0;
7769 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007770 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7771 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007772 err_code |= ERR_WARN;
7773 clear = 1;
7774 }
7775 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007776 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7777 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007778 cfgerr++;
7779 }
7780 if (clear) {
7781 free(curproxy->check_command);
7782 curproxy->check_command = NULL;
7783 }
7784 }
7785
7786 if (curproxy->check_path) {
7787 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007788 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7789 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007790 err_code |= ERR_WARN;
7791 free(curproxy->check_path);
7792 curproxy->check_path = NULL;
7793 }
7794 }
7795
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007796 /* if a default backend was specified, let's find it */
7797 if (curproxy->defbe.name) {
7798 struct proxy *target;
7799
Willy Tarreauafb39922015-05-26 12:04:09 +02007800 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007801 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007802 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7803 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007804 cfgerr++;
7805 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007806 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7807 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007808 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007809 } else if (target->mode != curproxy->mode &&
7810 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7811
Christopher Faulet767a84b2017-11-24 16:50:31 +01007812 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7813 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7814 curproxy->conf.file, curproxy->conf.line,
7815 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7816 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007817 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007818 } else {
7819 free(curproxy->defbe.name);
7820 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007821 /* Update tot_fe_maxconn for a further fullconn's computation */
7822 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007823 /* Emit a warning if this proxy also has some servers */
7824 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007825 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7826 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007827 err_code |= ERR_WARN;
7828 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007829 }
7830 }
7831
Emeric Brun3f783572017-01-12 11:21:28 +01007832 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7833 /* Case of listen without default backend
7834 * The curproxy will be its own default backend
7835 * so we update tot_fe_maxconn for a further
7836 * fullconn's computation */
7837 curproxy->tot_fe_maxconn += curproxy->maxconn;
7838 }
7839
Willy Tarreau55ea7572007-06-17 19:56:27 +02007840 /* find the target proxy for 'use_backend' rules */
7841 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007842 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007843 struct logformat_node *node;
7844 char *pxname;
7845
7846 /* Try to parse the string as a log format expression. If the result
7847 * of the parsing is only one entry containing a simple string, then
7848 * it's a standard string corresponding to a static rule, thus the
7849 * parsing is cancelled and be.name is restored to be resolved.
7850 */
7851 pxname = rule->be.name;
7852 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007853 curproxy->conf.args.ctx = ARGC_UBK;
7854 curproxy->conf.args.file = rule->file;
7855 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007856 err = NULL;
7857 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007858 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7859 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007860 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007861 cfgerr++;
7862 continue;
7863 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007864 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7865
7866 if (!LIST_ISEMPTY(&rule->be.expr)) {
7867 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7868 rule->dynamic = 1;
7869 free(pxname);
7870 continue;
7871 }
7872 /* simple string: free the expression and fall back to static rule */
7873 free(node->arg);
7874 free(node);
7875 }
7876
7877 rule->dynamic = 0;
7878 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007879
Willy Tarreauafb39922015-05-26 12:04:09 +02007880 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007881 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007882 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7883 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007884 cfgerr++;
7885 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007886 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7887 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007888 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007889 } else if (target->mode != curproxy->mode &&
7890 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7891
Christopher Faulet767a84b2017-11-24 16:50:31 +01007892 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7893 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7894 curproxy->conf.file, curproxy->conf.line,
7895 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7896 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007897 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007898 } else {
7899 free((void *)rule->be.name);
7900 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007901 /* For each target of switching rules, we update
7902 * their tot_fe_maxconn, except if a previous rule point
7903 * on the same backend or on the default backend */
7904 if (rule->be.backend != curproxy->defbe.be) {
7905 struct switching_rule *swrule;
7906
7907 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7908 if (rule == swrule) {
7909 target->tot_fe_maxconn += curproxy->maxconn;
7910 break;
7911 }
7912 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7913 /* there is multiple ref of this backend */
7914 break;
7915 }
7916 }
7917 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007918 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007919 }
7920
Willy Tarreau64ab6072014-09-16 12:17:36 +02007921 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007922 list_for_each_entry(srule, &curproxy->server_rules, list) {
7923 struct server *target = findserver(curproxy, srule->srv.name);
7924
7925 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007926 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7927 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007928 cfgerr++;
7929 continue;
7930 }
7931 free((void *)srule->srv.name);
7932 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007933 }
7934
Emeric Brunb982a3d2010-01-04 15:45:53 +01007935 /* find the target table for 'stick' rules */
7936 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7937 struct proxy *target;
7938
Emeric Brun1d33b292010-01-04 15:47:17 +01007939 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7940 if (mrule->flags & STK_IS_STORE)
7941 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7942
Emeric Brunb982a3d2010-01-04 15:45:53 +01007943 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007944 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007945 else
7946 target = curproxy;
7947
7948 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007949 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7950 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007951 cfgerr++;
7952 }
7953 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007954 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7955 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007956 cfgerr++;
7957 }
Willy Tarreau12785782012-04-27 21:37:17 +02007958 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007959 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7960 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007961 cfgerr++;
7962 }
7963 else {
7964 free((void *)mrule->table.name);
7965 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007966 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007967 }
7968 }
7969
7970 /* find the target table for 'store response' rules */
7971 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7972 struct proxy *target;
7973
Emeric Brun1d33b292010-01-04 15:47:17 +01007974 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7975
Emeric Brunb982a3d2010-01-04 15:45:53 +01007976 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007977 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007978 else
7979 target = curproxy;
7980
7981 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007982 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7983 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007984 cfgerr++;
7985 }
7986 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007987 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7988 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007989 cfgerr++;
7990 }
Willy Tarreau12785782012-04-27 21:37:17 +02007991 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007992 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7993 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007994 cfgerr++;
7995 }
7996 else {
7997 free((void *)mrule->table.name);
7998 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007999 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01008000 }
8001 }
8002
Christopher Faulete4e830d2017-09-18 14:51:41 +02008003 /* check validity for 'tcp-request' layer 4 rules */
8004 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
8005 err = NULL;
8006 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008007 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008008 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01008009 cfgerr++;
8010 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02008011 }
8012
Christopher Faulete4e830d2017-09-18 14:51:41 +02008013 /* check validity for 'tcp-request' layer 5 rules */
8014 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
8015 err = NULL;
8016 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008017 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008018 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008019 cfgerr++;
8020 }
8021 }
8022
Christopher Faulete4e830d2017-09-18 14:51:41 +02008023 /* check validity for 'tcp-request' layer 6 rules */
8024 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8025 err = NULL;
8026 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008027 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008028 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008029 cfgerr++;
8030 }
8031 }
8032
Christopher Faulete4e830d2017-09-18 14:51:41 +02008033 /* check validity for 'http-request' layer 7 rules */
8034 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
8035 err = NULL;
8036 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008037 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008038 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008039 cfgerr++;
8040 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008041 }
8042
Christopher Faulete4e830d2017-09-18 14:51:41 +02008043 /* check validity for 'http-response' layer 7 rules */
8044 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
8045 err = NULL;
8046 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008047 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008048 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02008049 cfgerr++;
8050 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008051 }
8052
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008053 /* move any "block" rules at the beginning of the http-request rules */
8054 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8055 /* insert block_rules into http_req_rules at the beginning */
8056 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8057 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8058 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8059 curproxy->http_req_rules.n = curproxy->block_rules.n;
8060 LIST_INIT(&curproxy->block_rules);
8061 }
8062
Emeric Brun32da3c42010-09-23 18:39:19 +02008063 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008064 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008065
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008066 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008067 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8068 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008069 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008070 break;
8071 }
8072 }
8073
8074 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008075 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8076 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008077 free((void *)curproxy->table.peers.name);
8078 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008079 cfgerr++;
8080 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008081 else if (curpeers->state == PR_STSTOPPED) {
8082 /* silently disable this peers section */
8083 curproxy->table.peers.p = NULL;
8084 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008085 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008086 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8087 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008088 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008089 cfgerr++;
8090 }
8091 }
8092
Simon Horman9dc49962015-01-30 11:22:59 +09008093
8094 if (curproxy->email_alert.mailers.name) {
8095 struct mailers *curmailers = mailers;
8096
8097 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008098 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008099 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008100 }
Simon Horman9dc49962015-01-30 11:22:59 +09008101 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008102 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8103 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008104 free_email_alert(curproxy);
8105 cfgerr++;
8106 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008107 else {
8108 err = NULL;
8109 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008110 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008111 free(err);
8112 cfgerr++;
8113 }
8114 }
Simon Horman9dc49962015-01-30 11:22:59 +09008115 }
8116
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008117 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008118 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008119 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008120 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8121 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008122 cfgerr++;
8123 goto out_uri_auth_compat;
8124 }
8125
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008126 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008127 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008128 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008129 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008130
Willy Tarreau95fa4692010-02-01 13:05:50 +01008131 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8132 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008133
8134 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008135 uri_auth_compat_req[i++] = "realm";
8136 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8137 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008138
Willy Tarreau95fa4692010-02-01 13:05:50 +01008139 uri_auth_compat_req[i++] = "unless";
8140 uri_auth_compat_req[i++] = "{";
8141 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8142 uri_auth_compat_req[i++] = "}";
8143 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008144
Willy Tarreauff011f22011-01-06 17:51:27 +01008145 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8146 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008147 cfgerr++;
8148 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008149 }
8150
Willy Tarreauff011f22011-01-06 17:51:27 +01008151 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008152
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008153 if (curproxy->uri_auth->auth_realm) {
8154 free(curproxy->uri_auth->auth_realm);
8155 curproxy->uri_auth->auth_realm = NULL;
8156 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008157
8158 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008159 }
8160out_uri_auth_compat:
8161
Dragan Dosen43885c72015-10-01 13:18:13 +02008162 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008163 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008164 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8165 if (!curproxy->conf.logformat_sd_string) {
8166 /* set the default logformat_sd_string */
8167 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8168 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008169 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008170 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008171 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008172
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008173 /* compile the log format */
8174 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008175 if (curproxy->conf.logformat_string != default_http_log_format &&
8176 curproxy->conf.logformat_string != default_tcp_log_format &&
8177 curproxy->conf.logformat_string != clf_http_log_format)
8178 free(curproxy->conf.logformat_string);
8179 curproxy->conf.logformat_string = NULL;
8180 free(curproxy->conf.lfs_file);
8181 curproxy->conf.lfs_file = NULL;
8182 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008183
8184 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8185 free(curproxy->conf.logformat_sd_string);
8186 curproxy->conf.logformat_sd_string = NULL;
8187 free(curproxy->conf.lfsd_file);
8188 curproxy->conf.lfsd_file = NULL;
8189 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008190 }
8191
Willy Tarreau62a61232013-04-12 18:13:46 +02008192 if (curproxy->conf.logformat_string) {
8193 curproxy->conf.args.ctx = ARGC_LOG;
8194 curproxy->conf.args.file = curproxy->conf.lfs_file;
8195 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008196 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008197 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008198 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008199 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8200 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008201 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008202 cfgerr++;
8203 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008204 curproxy->conf.args.file = NULL;
8205 curproxy->conf.args.line = 0;
8206 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008207
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008208 if (curproxy->conf.logformat_sd_string) {
8209 curproxy->conf.args.ctx = ARGC_LOGSD;
8210 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8211 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008212 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008213 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 +01008214 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008215 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8216 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008217 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008218 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008219 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008220 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8221 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008222 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008223 cfgerr++;
8224 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008225 curproxy->conf.args.file = NULL;
8226 curproxy->conf.args.line = 0;
8227 }
8228
Willy Tarreau62a61232013-04-12 18:13:46 +02008229 if (curproxy->conf.uniqueid_format_string) {
8230 curproxy->conf.args.ctx = ARGC_UIF;
8231 curproxy->conf.args.file = curproxy->conf.uif_file;
8232 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008233 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008234 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 +01008235 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008236 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8237 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008238 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008239 cfgerr++;
8240 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008241 curproxy->conf.args.file = NULL;
8242 curproxy->conf.args.line = 0;
8243 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008244
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008245 /* only now we can check if some args remain unresolved.
8246 * This must be done after the users and groups resolution.
8247 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008248 cfgerr += smp_resolve_args(curproxy);
8249 if (!cfgerr)
8250 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008251
Willy Tarreau2738a142006-07-08 17:28:09 +02008252 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008253 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008254 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008255 (!curproxy->timeout.connect ||
8256 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008257 ha_warning("config : missing timeouts for %s '%s'.\n"
8258 " | While not properly invalid, you will certainly encounter various problems\n"
8259 " | with such a configuration. To fix this, please ensure that all following\n"
8260 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8261 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008262 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008263 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008264
Willy Tarreau1fa31262007-12-03 00:36:16 +01008265 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8266 * We must still support older configurations, so let's find out whether those
8267 * parameters have been set or must be copied from contimeouts.
8268 */
8269 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008270 if (!curproxy->timeout.tarpit ||
8271 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008272 /* tarpit timeout not set. We search in the following order:
8273 * default.tarpit, curr.connect, default.connect.
8274 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008275 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008276 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008277 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008278 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008279 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008280 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008281 }
8282 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008283 (!curproxy->timeout.queue ||
8284 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008285 /* queue timeout not set. We search in the following order:
8286 * default.queue, curr.connect, default.connect.
8287 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008288 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008289 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008290 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008291 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008292 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008293 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008294 }
8295 }
8296
Willy Tarreau1620ec32011-08-06 17:05:02 +02008297 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008298 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008299 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008300 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008301 }
8302
Willy Tarreau215663d2014-06-13 18:30:23 +02008303 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8304 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008305 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8306 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008307 err_code |= ERR_WARN;
8308 }
8309
Willy Tarreau193b8c62012-11-22 00:17:38 +01008310 /* ensure that cookie capture length is not too large */
8311 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008312 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8313 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008314 err_code |= ERR_WARN;
8315 curproxy->capture_len = global.tune.cookie_len - 1;
8316 }
8317
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008318 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008319 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008320 curproxy->req_cap_pool = create_pool("ptrcap",
8321 curproxy->nb_req_cap * sizeof(char *),
8322 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008323 }
8324
8325 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008326 curproxy->rsp_cap_pool = create_pool("ptrcap",
8327 curproxy->nb_rsp_cap * sizeof(char *),
8328 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008329 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008330
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008331 switch (curproxy->load_server_state_from_file) {
8332 case PR_SRV_STATE_FILE_UNSPEC:
8333 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8334 break;
8335 case PR_SRV_STATE_FILE_GLOBAL:
8336 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008337 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",
8338 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008339 err_code |= ERR_WARN;
8340 }
8341 break;
8342 }
8343
Willy Tarreaubaaee002006-06-26 02:48:02 +02008344 /* first, we will invert the servers list order */
8345 newsrv = NULL;
8346 while (curproxy->srv) {
8347 struct server *next;
8348
8349 next = curproxy->srv->next;
8350 curproxy->srv->next = newsrv;
8351 newsrv = curproxy->srv;
8352 if (!next)
8353 break;
8354 curproxy->srv = next;
8355 }
8356
Willy Tarreau17edc812014-01-03 12:14:34 +01008357 /* Check that no server name conflicts. This causes trouble in the stats.
8358 * We only emit a warning for the first conflict affecting each server,
8359 * in order to avoid combinatory explosion if all servers have the same
8360 * name. We do that only for servers which do not have an explicit ID,
8361 * because these IDs were made also for distinguishing them and we don't
8362 * want to annoy people who correctly manage them.
8363 */
8364 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8365 struct server *other_srv;
8366
8367 if (newsrv->puid)
8368 continue;
8369
8370 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8371 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008372 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",
8373 newsrv->conf.file, newsrv->conf.line,
8374 proxy_type_str(curproxy), curproxy->id,
8375 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008376 break;
8377 }
8378 }
8379 }
8380
Willy Tarreaudd701652010-05-25 23:03:02 +02008381 /* assign automatic UIDs to servers which don't have one yet */
8382 next_id = 1;
8383 newsrv = curproxy->srv;
8384 while (newsrv != NULL) {
8385 if (!newsrv->puid) {
8386 /* server ID not set, use automatic numbering with first
8387 * spare entry starting with next_svid.
8388 */
8389 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8390 newsrv->conf.id.key = newsrv->puid = next_id;
8391 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8392 }
8393 next_id++;
8394 newsrv = newsrv->next;
8395 }
8396
Willy Tarreau20697042007-11-15 23:26:18 +01008397 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008398 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008399
Willy Tarreau62c3be22012-01-20 13:12:32 +01008400 /*
8401 * If this server supports a maxconn parameter, it needs a dedicated
8402 * tasks to fill the emptied slots when a connection leaves.
8403 * Also, resolve deferred tracking dependency if needed.
8404 */
8405 newsrv = curproxy->srv;
8406 while (newsrv != NULL) {
8407 if (newsrv->minconn > newsrv->maxconn) {
8408 /* Only 'minconn' was specified, or it was higher than or equal
8409 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8410 * this will avoid further useless expensive computations.
8411 */
8412 newsrv->maxconn = newsrv->minconn;
8413 } else if (newsrv->maxconn && !newsrv->minconn) {
8414 /* minconn was not specified, so we set it to maxconn */
8415 newsrv->minconn = newsrv->maxconn;
8416 }
8417
Willy Tarreau17d45382016-12-22 21:16:08 +01008418 /* this will also properly set the transport layer for prod and checks */
8419 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8420 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8421 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8422 }
Emeric Brun94324a42012-10-11 14:00:19 +02008423
Willy Tarreau2f075e92013-12-03 11:11:34 +01008424 /* set the check type on the server */
8425 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8426
Willy Tarreau62c3be22012-01-20 13:12:32 +01008427 if (newsrv->trackit) {
8428 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008429 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008430 char *pname, *sname;
8431
8432 pname = newsrv->trackit;
8433 sname = strrchr(pname, '/');
8434
8435 if (sname)
8436 *sname++ = '\0';
8437 else {
8438 sname = pname;
8439 pname = NULL;
8440 }
8441
8442 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008443 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008444 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008445 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8446 proxy_type_str(curproxy), curproxy->id,
8447 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008448 cfgerr++;
8449 goto next_srv;
8450 }
8451 } else
8452 px = curproxy;
8453
8454 srv = findserver(px, sname);
8455 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008456 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8457 proxy_type_str(curproxy), curproxy->id,
8458 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008459 cfgerr++;
8460 goto next_srv;
8461 }
8462
Willy Tarreau32091232014-05-16 13:52:00 +02008463 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8464 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8465 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008466 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8467 "tracking as it does not have any check nor agent enabled.\n",
8468 proxy_type_str(curproxy), curproxy->id,
8469 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008470 cfgerr++;
8471 goto next_srv;
8472 }
8473
8474 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8475
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008476 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008477 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8478 "belongs to a tracking chain looping back to %s/%s.\n",
8479 proxy_type_str(curproxy), curproxy->id,
8480 newsrv->id, px->id, srv->id, px->id,
8481 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008482 cfgerr++;
8483 goto next_srv;
8484 }
8485
8486 if (curproxy != px &&
8487 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008488 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8489 "tracking: disable-on-404 option inconsistency.\n",
8490 proxy_type_str(curproxy), curproxy->id,
8491 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008492 cfgerr++;
8493 goto next_srv;
8494 }
8495
Willy Tarreau62c3be22012-01-20 13:12:32 +01008496 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008497 newsrv->tracknext = srv->trackers;
8498 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008499
8500 free(newsrv->trackit);
8501 newsrv->trackit = NULL;
8502 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008503
Willy Tarreau62c3be22012-01-20 13:12:32 +01008504 next_srv:
8505 newsrv = newsrv->next;
8506 }
8507
Olivier Houchard4e694042017-03-14 20:01:29 +01008508 /*
8509 * Try to generate dynamic cookies for servers now.
8510 * It couldn't be done earlier, since at the time we parsed
8511 * the server line, we may not have known yet that we
8512 * should use dynamic cookies, or the secret key may not
8513 * have been provided yet.
8514 */
8515 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8516 newsrv = curproxy->srv;
8517 while (newsrv != NULL) {
8518 srv_set_dyncookie(newsrv);
8519 newsrv = newsrv->next;
8520 }
8521
8522 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008523 /* We have to initialize the server lookup mechanism depending
8524 * on what LB algorithm was choosen.
8525 */
8526
8527 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8528 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8529 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008530 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8531 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8532 init_server_map(curproxy);
8533 } else {
8534 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8535 fwrr_init_server_groups(curproxy);
8536 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008537 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008538
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008539 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008540 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8541 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8542 fwlc_init_server_tree(curproxy);
8543 } else {
8544 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8545 fas_init_server_tree(curproxy);
8546 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008547 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008548
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008549 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008550 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8551 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8552 chash_init_server_tree(curproxy);
8553 } else {
8554 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8555 init_server_map(curproxy);
8556 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008557 break;
8558 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008559 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008560
8561 if (curproxy->options & PR_O_LOGASAP)
8562 curproxy->to_log &= ~LW_BYTES;
8563
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008564 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008565 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8566 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008567 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8568 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008569 err_code |= ERR_WARN;
8570 }
8571
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008572 if (curproxy->mode != PR_MODE_HTTP) {
8573 int optnum;
8574
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008575 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008576 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8577 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008578 err_code |= ERR_WARN;
8579 curproxy->uri_auth = NULL;
8580 }
8581
Willy Tarreaude7dc882017-03-10 11:49:21 +01008582 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008583 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8584 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008585 err_code |= ERR_WARN;
8586 }
8587
8588 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008589 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8590 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008591 err_code |= ERR_WARN;
8592 }
8593
8594 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008595 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8596 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008597 err_code |= ERR_WARN;
8598 }
8599
8600 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008601 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8602 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008603 err_code |= ERR_WARN;
8604 }
8605
8606 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008607 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8608 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008609 err_code |= ERR_WARN;
8610 }
8611
Willy Tarreau87cf5142011-08-19 22:57:24 +02008612 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008613 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8614 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008615 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008616 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008617 }
8618
8619 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008620 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8621 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008622 err_code |= ERR_WARN;
8623 curproxy->options &= ~PR_O_ORGTO;
8624 }
8625
8626 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8627 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8628 (curproxy->cap & cfg_opts[optnum].cap) &&
8629 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008630 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8631 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008632 err_code |= ERR_WARN;
8633 curproxy->options &= ~cfg_opts[optnum].val;
8634 }
8635 }
8636
8637 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8638 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8639 (curproxy->cap & cfg_opts2[optnum].cap) &&
8640 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008641 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8642 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008643 err_code |= ERR_WARN;
8644 curproxy->options2 &= ~cfg_opts2[optnum].val;
8645 }
8646 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008647
Willy Tarreau29fbe512015-08-20 19:35:14 +02008648#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008649 if (curproxy->conn_src.bind_hdr_occ) {
8650 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008651 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8652 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008653 err_code |= ERR_WARN;
8654 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008655#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008656 }
8657
Willy Tarreaubaaee002006-06-26 02:48:02 +02008658 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008659 * ensure that we're not cross-dressing a TCP server into HTTP.
8660 */
8661 newsrv = curproxy->srv;
8662 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008663 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008664 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8665 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008666 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008667 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008668
Willy Tarreau0cec3312011-10-31 13:49:26 +01008669 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008670 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8671 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008672 err_code |= ERR_WARN;
8673 }
8674
Willy Tarreauc93cd162014-05-13 15:54:22 +02008675 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008676 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8677 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008678 err_code |= ERR_WARN;
8679 }
8680
Willy Tarreau29fbe512015-08-20 19:35:14 +02008681#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008682 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8683 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008684 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8685 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008686 err_code |= ERR_WARN;
8687 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008688#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008689
8690 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8691 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8692 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8693 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8694 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008695 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",
8696 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008697 err_code |= ERR_WARN;
8698 }
8699
8700
8701 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008702 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",
8703 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008704 err_code |= ERR_WARN;
8705 }
8706 }
8707
Willy Tarreau21d2af32008-02-14 20:25:24 +01008708 newsrv = newsrv->next;
8709 }
8710
Willy Tarreaue42bd962014-09-16 16:21:19 +02008711 /* check if we have a frontend with "tcp-request content" looking at L7
8712 * with no inspect-delay
8713 */
8714 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008715 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8716 if (arule->action == ACT_TCP_CAPTURE &&
8717 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008718 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008719 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8720 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008721 break;
8722 }
8723
Christopher Faulete4e830d2017-09-18 14:51:41 +02008724 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008725 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8726 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8727 " This means that these rules will randomly find their contents. This can be fixed by"
8728 " setting the tcp-request inspect-delay.\n",
8729 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008730 err_code |= ERR_WARN;
8731 }
8732 }
8733
Christopher Fauletd7c91962015-04-30 11:48:27 +02008734 /* Check filter configuration, if any */
8735 cfgerr += flt_check(curproxy);
8736
Willy Tarreauc1a21672009-08-16 22:37:44 +02008737 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008738 if (!curproxy->accept)
8739 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008740
Willy Tarreauc1a21672009-08-16 22:37:44 +02008741 if (curproxy->tcp_req.inspect_delay ||
8742 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008743 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008744
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008745 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008746 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008747 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008748 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008749
8750 /* both TCP and HTTP must check switching rules */
8751 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008752
8753 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008754 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008755 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8756 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 +01008757 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008758 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8759 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008760 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008761 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008762 }
8763
8764 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008765 if (curproxy->tcp_req.inspect_delay ||
8766 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8767 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8768
Emeric Brun97679e72010-09-23 17:56:44 +02008769 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8770 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8771
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008772 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008773 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008774 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008775 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008776
8777 /* If the backend does requires RDP cookie persistence, we have to
8778 * enable the corresponding analyser.
8779 */
8780 if (curproxy->options2 & PR_O2_RDPC_PRST)
8781 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008782
8783 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008784 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008785 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8786 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 +01008787 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008788 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8789 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008790 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008791 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008792 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008793 }
8794
8795 /***********************************************************/
8796 /* At this point, target names have already been resolved. */
8797 /***********************************************************/
8798
8799 /* Check multi-process mode compatibility */
8800
8801 if (global.nbproc > 1 && global.stats_fe) {
8802 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8803 unsigned long mask;
8804
8805 mask = nbits(global.nbproc);
8806 if (global.stats_fe->bind_proc)
8807 mask &= global.stats_fe->bind_proc;
8808
8809 if (bind_conf->bind_proc)
8810 mask &= bind_conf->bind_proc;
8811
8812 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008813 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008814 break;
8815 }
8816 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008817 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 +02008818 }
8819 }
8820
8821 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008822 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008823 if (curproxy->bind_proc)
8824 continue;
8825
8826 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8827 unsigned long mask;
8828
Willy Tarreaue428b082015-05-04 21:57:58 +02008829 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008830 curproxy->bind_proc |= mask;
8831 }
8832
8833 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008834 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008835 }
8836
8837 if (global.stats_fe) {
8838 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8839 unsigned long mask;
8840
Cyril Bonté06181952016-02-24 00:14:54 +01008841 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008842 global.stats_fe->bind_proc |= mask;
8843 }
8844 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008845 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008846 }
8847
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008848 /* propagate bindings from frontends to backends. Don't do it if there
8849 * are any fatal errors as we must not call it with unresolved proxies.
8850 */
8851 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008852 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008853 if (curproxy->cap & PR_CAP_FE)
8854 propagate_processes(curproxy, NULL);
8855 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008856 }
8857
8858 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008859 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008860 if (curproxy->bind_proc)
8861 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008862 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008863 }
8864
8865 /*******************************************************/
8866 /* At this step, all proxies have a non-null bind_proc */
8867 /*******************************************************/
8868
8869 /* perform the final checks before creating tasks */
8870
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008871 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008872 struct listener *listener;
8873 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008874
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008875 /* Configure SSL for each bind line.
8876 * Note: if configuration fails at some point, the ->ctx member
8877 * remains NULL so that listeners can later detach.
8878 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008879 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008880 if (bind_conf->xprt->prepare_bind_conf &&
8881 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008882 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008883 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008884
Willy Tarreaue6b98942007-10-29 01:09:36 +01008885 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008886 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008887 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008888 int nbproc;
8889
8890 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008891 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008892 nbits(global.nbproc));
8893
8894 if (!nbproc) /* no intersection between listener and frontend */
8895 nbproc = 1;
8896
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008897 if (!listener->luid) {
8898 /* listener ID not set, use automatic numbering with first
8899 * spare entry starting with next_luid.
8900 */
8901 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8902 listener->conf.id.key = listener->luid = next_id;
8903 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008904 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008905 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008906
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008907 /* enable separate counters */
8908 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008909 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008910 if (!listener->name)
8911 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008912 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008913
Willy Tarreaue6b98942007-10-29 01:09:36 +01008914 if (curproxy->options & PR_O_TCP_NOLING)
8915 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008916 if (!listener->maxconn)
8917 listener->maxconn = curproxy->maxconn;
8918 if (!listener->backlog)
8919 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008920 if (!listener->maxaccept)
8921 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8922
8923 /* we want to have an optimal behaviour on single process mode to
8924 * maximize the work at once, but in multi-process we want to keep
8925 * some fairness between processes, so we target half of the max
8926 * number of events to be balanced over all the processes the proxy
8927 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8928 * used to disable the limit.
8929 */
8930 if (listener->maxaccept > 0) {
8931 if (nbproc > 1)
8932 listener->maxaccept = (listener->maxaccept + 1) / 2;
8933 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8934 }
8935
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008936 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008937 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008938 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008939
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008940 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008941 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008942
Willy Tarreau620408f2016-10-21 16:37:51 +02008943 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8944 listener->options |= LI_O_TCP_L5_RULES;
8945
Willy Tarreaude3041d2010-05-31 10:56:17 +02008946 if (curproxy->mon_mask.s_addr)
8947 listener->options |= LI_O_CHK_MONNET;
8948
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008949 /* smart accept mode is automatic in HTTP mode */
8950 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008951 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008952 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8953 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008954 }
8955
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008956 /* Release unused SSL configs */
8957 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008958 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8959 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008960 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008961
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008962 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008963 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008964 int count, maxproc = 0;
8965
8966 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008967 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008968 if (count > maxproc)
8969 maxproc = count;
8970 }
8971 /* backends have 0, frontends have 1 or more */
8972 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008973 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8974 " limited to process assigned to the current request.\n",
8975 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008976
Willy Tarreau102df612014-05-07 23:56:38 +02008977 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008978 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
8979 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008980 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008981 }
Willy Tarreau102df612014-05-07 23:56:38 +02008982 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008983 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
8984 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008985 }
8986 }
Willy Tarreau918ff602011-07-25 16:33:49 +02008987
8988 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02008989 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02008990 if (curproxy->task) {
8991 curproxy->task->context = curproxy;
8992 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02008993 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008994 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
8995 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02008996 cfgerr++;
8997 }
Willy Tarreaub369a042014-09-16 13:21:03 +02008998 }
8999
Willy Tarreaufbb78422011-06-05 15:38:35 +02009000 /* automatically compute fullconn if not set. We must not do it in the
9001 * loop above because cross-references are not yet fully resolved.
9002 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009003 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009004 /* If <fullconn> is not set, let's set it to 10% of the sum of
9005 * the possible incoming frontend's maxconns.
9006 */
9007 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009008 /* we have the sum of the maxconns in <total>. We only
9009 * keep 10% of that sum to set the default fullconn, with
9010 * a hard minimum of 1 (to avoid a divide by zero).
9011 */
Emeric Brun3f783572017-01-12 11:21:28 +01009012 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02009013 if (!curproxy->fullconn)
9014 curproxy->fullconn = 1;
9015 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01009016 }
9017
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009018 /*
9019 * Recount currently required checks.
9020 */
9021
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009022 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009023 int optnum;
9024
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009025 for (optnum = 0; cfg_opts[optnum].name; optnum++)
9026 if (curproxy->options & cfg_opts[optnum].val)
9027 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009028
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009029 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
9030 if (curproxy->options2 & cfg_opts2[optnum].val)
9031 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009032 }
9033
Willy Tarreau0fca4832015-05-01 19:12:05 +02009034 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009035 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02009036 if (curproxy->table.peers.p)
9037 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
9038
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009039 if (cfg_peers) {
9040 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02009041 struct peer *p, *pb;
9042
Willy Tarreau1e273012015-05-01 19:15:17 +02009043 /* Remove all peers sections which don't have a valid listener,
9044 * which are not used by any table, or which are bound to more
9045 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009046 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009047 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009048 while (*last) {
9049 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009050
9051 if (curpeers->state == PR_STSTOPPED) {
9052 /* the "disabled" keyword was present */
9053 if (curpeers->peers_fe)
9054 stop_proxy(curpeers->peers_fe);
9055 curpeers->peers_fe = NULL;
9056 }
9057 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009058 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9059 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009060 }
David Carliere6c39412015-07-02 07:00:17 +00009061 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009062 /* either it's totally stopped or too much used */
9063 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009064 ha_alert("Peers section '%s': peers referenced by sections "
9065 "running in different processes (%d different ones). "
9066 "Check global.nbproc and all tables' bind-process "
9067 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009068 cfgerr++;
9069 }
9070 stop_proxy(curpeers->peers_fe);
9071 curpeers->peers_fe = NULL;
9072 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009073 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009074 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009075 last = &curpeers->next;
9076 continue;
9077 }
9078
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009079 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009080 p = curpeers->remote;
9081 while (p) {
9082 pb = p->next;
9083 free(p->id);
9084 free(p);
9085 p = pb;
9086 }
9087
9088 /* Destroy and unlink this curpeers section.
9089 * Note: curpeers is backed up into *last.
9090 */
9091 free(curpeers->id);
9092 curpeers = curpeers->next;
9093 free(*last);
9094 *last = curpeers;
9095 }
9096 }
9097
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009098 /* initialize stick-tables on backend capable proxies. This must not
9099 * be done earlier because the data size may be discovered while parsing
9100 * other proxies.
9101 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009102 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009103 if (curproxy->state == PR_STSTOPPED)
9104 continue;
9105
9106 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009107 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009108 cfgerr++;
9109 }
9110 }
9111
Simon Horman0d16a402015-01-30 11:22:58 +09009112 if (mailers) {
9113 struct mailers *curmailers = mailers, **last;
9114 struct mailer *m, *mb;
9115
9116 /* Remove all mailers sections which don't have a valid listener.
9117 * This can happen when a mailers section is never referenced.
9118 */
9119 last = &mailers;
9120 while (*last) {
9121 curmailers = *last;
9122 if (curmailers->users) {
9123 last = &curmailers->next;
9124 continue;
9125 }
9126
Christopher Faulet767a84b2017-11-24 16:50:31 +01009127 ha_warning("Removing incomplete section 'mailers %s'.\n",
9128 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009129
9130 m = curmailers->mailer_list;
9131 while (m) {
9132 mb = m->next;
9133 free(m->id);
9134 free(m);
9135 m = mb;
9136 }
9137
9138 /* Destroy and unlink this curmailers section.
9139 * Note: curmailers is backed up into *last.
9140 */
9141 free(curmailers->id);
9142 curmailers = curmailers->next;
9143 free(*last);
9144 *last = curmailers;
9145 }
9146 }
9147
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009148 /* Update server_state_file_name to backend name if backend is supposed to use
9149 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009150 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009151 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9152 curproxy->server_state_file_name == NULL)
9153 curproxy->server_state_file_name = strdup(curproxy->id);
9154 }
9155
Willy Tarreaubafbe012017-11-24 17:34:44 +01009156 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009157 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009158 MEM_F_SHARED);
9159
William Lallemand48b4bb42017-10-23 14:36:34 +02009160 list_for_each_entry(postparser, &postparsers, list) {
9161 if (postparser->func)
9162 cfgerr += postparser->func();
9163 }
9164
Willy Tarreaubb925012009-07-23 13:36:36 +02009165 if (cfgerr > 0)
9166 err_code |= ERR_ALERT | ERR_FATAL;
9167 out:
9168 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009169}
9170
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009171/*
9172 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9173 * parsing sessions.
9174 */
9175void cfg_register_keywords(struct cfg_kw_list *kwl)
9176{
9177 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9178}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009179
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009180/*
9181 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9182 */
9183void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9184{
9185 LIST_DEL(&kwl->list);
9186 LIST_INIT(&kwl->list);
9187}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009188
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009189/* this function register new section in the haproxy configuration file.
9190 * <section_name> is the name of this new section and <section_parser>
9191 * is the called parser. If two section declaration have the same name,
9192 * only the first declared is used.
9193 */
9194int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009195 int (*section_parser)(const char *, int, char **, int),
9196 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009197{
9198 struct cfg_section *cs;
9199
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009200 list_for_each_entry(cs, &sections, list) {
9201 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009202 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009203 return 0;
9204 }
9205 }
9206
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009207 cs = calloc(1, sizeof(*cs));
9208 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009209 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009210 return 0;
9211 }
9212
9213 cs->section_name = section_name;
9214 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009215 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009216
9217 LIST_ADDQ(&sections, &cs->list);
9218
9219 return 1;
9220}
9221
William Lallemand48b4bb42017-10-23 14:36:34 +02009222/* this function register a new function which will be called once the haproxy
9223 * configuration file has been parsed. It's useful to check dependencies
9224 * between sections or to resolve items once everything is parsed.
9225 */
9226int cfg_register_postparser(char *name, int (*func)())
9227{
9228 struct cfg_postparser *cp;
9229
9230 cp = calloc(1, sizeof(*cp));
9231 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009232 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009233 return 0;
9234 }
9235 cp->name = name;
9236 cp->func = func;
9237
9238 LIST_ADDQ(&postparsers, &cp->list);
9239
9240 return 1;
9241}
9242
Willy Tarreaubaaee002006-06-26 02:48:02 +02009243/*
David Carlier845efb52015-09-25 11:49:18 +01009244 * free all config section entries
9245 */
9246void cfg_unregister_sections(void)
9247{
9248 struct cfg_section *cs, *ics;
9249
9250 list_for_each_entry_safe(cs, ics, &sections, list) {
9251 LIST_DEL(&cs->list);
9252 free(cs);
9253 }
9254}
9255
Christopher Faulet7110b402016-10-26 11:09:44 +02009256void cfg_backup_sections(struct list *backup_sections)
9257{
9258 struct cfg_section *cs, *ics;
9259
9260 list_for_each_entry_safe(cs, ics, &sections, list) {
9261 LIST_DEL(&cs->list);
9262 LIST_ADDQ(backup_sections, &cs->list);
9263 }
9264}
9265
9266void cfg_restore_sections(struct list *backup_sections)
9267{
9268 struct cfg_section *cs, *ics;
9269
9270 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9271 LIST_DEL(&cs->list);
9272 LIST_ADDQ(&sections, &cs->list);
9273 }
9274}
9275
Willy Tarreau659fbf02016-05-26 17:55:28 +02009276__attribute__((constructor))
9277static void cfgparse_init(void)
9278{
9279 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009280 cfg_register_section("listen", cfg_parse_listen, NULL);
9281 cfg_register_section("frontend", cfg_parse_listen, NULL);
9282 cfg_register_section("backend", cfg_parse_listen, NULL);
9283 cfg_register_section("defaults", cfg_parse_listen, NULL);
9284 cfg_register_section("global", cfg_parse_global, NULL);
9285 cfg_register_section("userlist", cfg_parse_users, NULL);
9286 cfg_register_section("peers", cfg_parse_peers, NULL);
9287 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9288 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9289 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009290}
9291
David Carlier845efb52015-09-25 11:49:18 +01009292/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009293 * Local variables:
9294 * c-indent-level: 8
9295 * c-basic-offset: 8
9296 * End:
9297 */