blob: 2ac7b965977c1f650e8c63f4c51f202359002aab [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Configuration parser
3 *
Willy Tarreauff011f22011-01-06 17:51:27 +01004 * Copyright 2000-2011 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Cyril Bonté1a0191d2014-08-29 20:20:02 +020013#ifdef CONFIG_HAP_CRYPT
14/* This is to have crypt() defined on Linux */
15#define _GNU_SOURCE
16
17#ifdef NEED_CRYPT_H
18/* some platforms such as Solaris need this */
19#include <crypt.h>
20#endif
21#endif /* CONFIG_HAP_CRYPT */
22
Willy Tarreaubaaee002006-06-26 02:48:02 +020023#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <netdb.h>
27#include <ctype.h>
Willy Tarreau95c20ac2007-03-25 15:39:23 +020028#include <pwd.h>
29#include <grp.h>
Willy Tarreau0b4ed902007-03-26 00:18:40 +020030#include <errno.h>
Willy Tarreau3f49b302007-06-11 00:29:26 +020031#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <unistd.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035
Willy Tarreau2dd0d472006-06-29 17:53:05 +020036#include <common/cfgparse.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020037#include <common/chunk.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020038#include <common/config.h>
Willy Tarreau058e9072009-07-20 09:30:05 +020039#include <common/errors.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020040#include <common/memory.h>
41#include <common/standard.h>
42#include <common/time.h>
43#include <common/uri_auth.h>
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +010044#include <common/namespace.h>
Emeric Brunc60def82017-09-27 14:59:38 +020045#include <common/hathreads.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020046
47#include <types/capture.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020048#include <types/compression.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020049#include <types/filters.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020050#include <types/global.h>
Willy Tarreau3fdb3662012-11-12 00:42:33 +010051#include <types/obj_type.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020052#include <types/peers.h>
Simon Horman0d16a402015-01-30 11:22:58 +090053#include <types/mailers.h>
Baptiste Assmann325137d2015-04-13 23:40:55 +020054#include <types/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010055#include <types/stats.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020056
Willy Tarreaueb0c6142007-05-07 00:53:22 +020057#include <proto/acl.h>
Christopher Faulet4fce0d82017-09-18 11:57:31 +020058#include <proto/action.h>
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +010059#include <proto/auth.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020060#include <proto/backend.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020061#include <proto/channel.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020062#include <proto/checks.h>
William Lallemand82fe75c2012-10-23 10:25:10 +020063#include <proto/compression.h>
Baptiste Assmann201c07f2017-05-22 15:17:15 +020064#include <proto/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010065#include <proto/stats.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020066#include <proto/filters.h>
Willy Tarreaueb472682010-05-28 18:46:57 +020067#include <proto/frontend.h>
Willy Tarreau34eb6712011-10-24 18:15:04 +020068#include <proto/hdr_idx.h>
Willy Tarreau6b2e11b2009-10-01 07:52:15 +020069#include <proto/lb_chash.h>
Willy Tarreauf09c6602012-02-13 17:12:08 +010070#include <proto/lb_fas.h>
Willy Tarreauf89c1872009-10-01 11:19:37 +020071#include <proto/lb_fwlc.h>
72#include <proto/lb_fwrr.h>
73#include <proto/lb_map.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020074#include <proto/listener.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020075#include <proto/log.h>
Willy Tarreaud1d54542012-09-12 22:58:11 +020076#include <proto/protocol.h>
Willy Tarreaue6b98942007-10-29 01:09:36 +010077#include <proto/proto_http.h>
Willy Tarreau2b5652f2006-12-31 17:46:05 +010078#include <proto/proxy.h>
Emeric Brun32da3c42010-09-23 18:39:19 +020079#include <proto/peers.h>
Willy Tarreaucd3b0942012-04-27 21:52:18 +020080#include <proto/sample.h>
Willy Tarreau9903f0e2015-04-04 18:50:31 +020081#include <proto/session.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020082#include <proto/server.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020083#include <proto/stream.h>
Emeric Brunb982a3d2010-01-04 15:45:53 +010084#include <proto/stick_table.h>
Willy Tarreau39713102016-11-25 15:49:32 +010085#include <proto/task.h>
86#include <proto/tcp_rules.h>
Olivier Houchard673867c2018-05-25 16:58:52 +020087#include <proto/connection.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020088
89
Willy Tarreauf3c69202006-07-09 16:42:34 +020090/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
91 * ssl-hello-chk option to ensure that the remote server speaks SSL.
92 *
93 * Check RFC 2246 (TLSv1.0) sections A.3 and A.4 for details.
94 */
95const char sslv3_client_hello_pkt[] = {
96 "\x16" /* ContentType : 0x16 = Hanshake */
97 "\x03\x00" /* ProtocolVersion : 0x0300 = SSLv3 */
98 "\x00\x79" /* ContentLength : 0x79 bytes after this one */
99 "\x01" /* HanshakeType : 0x01 = CLIENT HELLO */
100 "\x00\x00\x75" /* HandshakeLength : 0x75 bytes after this one */
101 "\x03\x00" /* Hello Version : 0x0300 = v3 */
102 "\x00\x00\x00\x00" /* Unix GMT Time (s) : filled with <now> (@0x0B) */
103 "HAPROXYSSLCHK\nHAPROXYSSLCHK\n" /* Random : must be exactly 28 bytes */
104 "\x00" /* Session ID length : empty (no session ID) */
105 "\x00\x4E" /* Cipher Suite Length : 78 bytes after this one */
106 "\x00\x01" "\x00\x02" "\x00\x03" "\x00\x04" /* 39 most common ciphers : */
107 "\x00\x05" "\x00\x06" "\x00\x07" "\x00\x08" /* 0x01...0x1B, 0x2F...0x3A */
108 "\x00\x09" "\x00\x0A" "\x00\x0B" "\x00\x0C" /* This covers RSA/DH, */
109 "\x00\x0D" "\x00\x0E" "\x00\x0F" "\x00\x10" /* various bit lengths, */
110 "\x00\x11" "\x00\x12" "\x00\x13" "\x00\x14" /* SHA1/MD5, DES/3DES/AES... */
111 "\x00\x15" "\x00\x16" "\x00\x17" "\x00\x18"
112 "\x00\x19" "\x00\x1A" "\x00\x1B" "\x00\x2F"
113 "\x00\x30" "\x00\x31" "\x00\x32" "\x00\x33"
114 "\x00\x34" "\x00\x35" "\x00\x36" "\x00\x37"
115 "\x00\x38" "\x00\x39" "\x00\x3A"
116 "\x01" /* Compression Length : 0x01 = 1 byte for types */
117 "\x00" /* Compression Type : 0x00 = NULL compression */
118};
119
Willy Tarreau3842f002009-06-14 11:39:52 +0200120/* various keyword modifiers */
121enum kw_mod {
122 KWM_STD = 0, /* normal */
123 KWM_NO, /* "no" prefixed before the keyword */
124 KWM_DEF, /* "default" prefixed before the keyword */
125};
126
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100127/* permit to store configuration section */
128struct cfg_section {
129 struct list list;
130 char *section_name;
131 int (*section_parser)(const char *, int, char **, int);
William Lallemandd2ff56d2017-10-16 11:06:50 +0200132 int (*post_section_parser)();
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100133};
134
135/* Used to chain configuration sections definitions. This list
136 * stores struct cfg_section
137 */
138struct list sections = LIST_HEAD_INIT(sections);
139
William Lallemand48b4bb42017-10-23 14:36:34 +0200140/* store post configuration parsing */
141
142struct cfg_postparser {
143 struct list list;
144 char *name;
145 int (*func)();
146};
147
148struct list postparsers = LIST_HEAD_INIT(postparsers);
149
Willy Tarreau13943ab2006-12-31 00:24:10 +0100150/* some of the most common options which are also the easiest to handle */
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100151struct cfg_opt {
Willy Tarreau13943ab2006-12-31 00:24:10 +0100152 const char *name;
153 unsigned int val;
154 unsigned int cap;
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100155 unsigned int checks;
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100156 unsigned int mode;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100157};
158
159/* proxy->options */
160static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100161{
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100162 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
163 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
164 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
165 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
166 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
167 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100168 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau9fbe18e2015-05-01 22:42:08 +0200169 { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau0f228a02015-05-01 15:37:53 +0200170 { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreau9420b122013-12-15 18:58:25 +0100171 { "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100172 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
173 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
174 { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100175 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100176#ifdef TPROXY
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100177 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100178#else
179 { "transparent", 0, 0, 0, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100180#endif
181
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100182 { NULL, 0, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100183};
184
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100185/* proxy->options2 */
186static const struct cfg_opt cfg_opts2[] =
187{
188#ifdef CONFIG_HAP_LINUX_SPLICE
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100189 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
190 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
191 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100192#else
193 { "splice-request", 0, 0, 0, 0 },
194 { "splice-response", 0, 0, 0, 0 },
195 { "splice-auto", 0, 0, 0, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100196#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100197 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
198 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
199 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
200 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
201 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0, 0 },
202 { "socket-stats", PR_O2_SOCKSTAT, PR_CAP_FE, 0, 0 },
203 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0, 0 },
204 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0, 0 },
205 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Jamie Gloudon801a0a32012-08-25 00:18:33 -0400206 { "independent-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100207 { "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreaue52564c2010-04-27 22:19:14 +0200208 { "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau96e31212011-05-30 18:10:30 +0200209 { "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100210 { NULL, 0, 0, 0 }
211};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200212
Willy Tarreau6daf3432008-01-22 16:44:08 +0100213static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200214static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
215int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100216int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100217char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200218
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200219/* List head of all known configuration keywords */
220static struct cfg_kw_list cfg_keywords = {
221 .list = LIST_HEAD_INIT(cfg_keywords.list)
222};
223
Willy Tarreaubaaee002006-06-26 02:48:02 +0200224/*
225 * converts <str> to a list of listeners which are dynamically allocated.
226 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
227 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
228 * - <port> is a numerical port from 1 to 65535 ;
229 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
230 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200231 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
232 * not NULL, it must be a valid pointer to either NULL or a freeable area that
233 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200234 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200235int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200236{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100237 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200238 int port, end;
239
240 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200241
Willy Tarreaubaaee002006-06-26 02:48:02 +0200242 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100243 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200244 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100245 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200246
247 str = next;
248 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100249 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200250 *next++ = 0;
251 }
252
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100253 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200254 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200255 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100256 if (!ss2)
257 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200258
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100259 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100260 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200261 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100262 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200263 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200264
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100265 if (!port || !end) {
266 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
267 goto fail;
268 }
269
Emeric Bruned760922010-10-22 17:59:25 +0200270 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200271 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200272 goto fail;
273 }
274
275 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200276 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200277 goto fail;
278 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200279 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100280 else if (ss2->ss_family == AF_UNSPEC) {
281 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100282 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100283
284 /* We want to attach to an already bound fd whose number
285 * is in the addr part of ss2 when cast to sockaddr_in.
286 * Note that by definition there is a single listener.
287 * We still have to determine the address family to
288 * register the correct protocol.
289 */
290 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
291 addr_len = sizeof(*ss2);
292 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
293 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
294 goto fail;
295 }
296
297 port = end = get_host_port(ss2);
298 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200299
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100300 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100301 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200302 memprintf(err, "%s for address '%s'.\n", *err, str);
303 goto fail;
304 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200305 } /* end while(next) */
306 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200307 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200308 fail:
309 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200310 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200311}
312
William Lallemand6e62fb62015-04-28 16:55:23 +0200313/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100314 * Report an error in <msg> when there are too many arguments. This version is
315 * intended to be used by keyword parsers so that the message will be included
316 * into the general error message. The index is the current keyword in args.
317 * Return 0 if the number of argument is correct, otherwise build a message and
318 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
319 * message may also be null, it will simply not be produced (useful to check only).
320 * <msg> and <err_code> are only affected on error.
321 */
322int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
323{
324 int i;
325
326 if (!*args[index + maxarg + 1])
327 return 0;
328
329 if (msg) {
330 *msg = NULL;
331 memprintf(msg, "%s", args[0]);
332 for (i = 1; i <= index; i++)
333 memprintf(msg, "%s %s", *msg, args[i]);
334
335 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
336 }
337 if (err_code)
338 *err_code |= ERR_ALERT | ERR_FATAL;
339
340 return 1;
341}
342
343/*
344 * same as too_many_args_idx with a 0 index
345 */
346int too_many_args(int maxarg, char **args, char **msg, int *err_code)
347{
348 return too_many_args_idx(maxarg, 0, args, msg, err_code);
349}
350
351/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200352 * Report a fatal Alert when there is too much arguments
353 * The index is the current keyword in args
354 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
355 * Fill err_code with an ERR_ALERT and an ERR_FATAL
356 */
357int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
358{
359 char *kw = NULL;
360 int i;
361
362 if (!*args[index + maxarg + 1])
363 return 0;
364
365 memprintf(&kw, "%s", args[0]);
366 for (i = 1; i <= index; i++) {
367 memprintf(&kw, "%s %s", kw, args[i]);
368 }
369
Christopher Faulet767a84b2017-11-24 16:50:31 +0100370 ha_alert("parsing [%s:%d] : '%s' cannot handle unexpected argument '%s'.\n", file, linenum, kw, args[index + maxarg + 1]);
William Lallemand6e62fb62015-04-28 16:55:23 +0200371 free(kw);
372 *err_code |= ERR_ALERT | ERR_FATAL;
373 return 1;
374}
375
376/*
377 * same as alertif_too_many_args_idx with a 0 index
378 */
379int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
380{
381 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
382}
383
Willy Tarreau620408f2016-10-21 16:37:51 +0200384/* Report a warning if a rule is placed after a 'tcp-request session' rule.
385 * Return 1 if the warning has been emitted, otherwise 0.
386 */
387int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
388{
389 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100390 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
391 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200392 return 1;
393 }
394 return 0;
395}
396
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200397/* Report a warning if a rule is placed after a 'tcp-request content' rule.
398 * Return 1 if the warning has been emitted, otherwise 0.
399 */
400int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
401{
402 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100403 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
404 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200405 return 1;
406 }
407 return 0;
408}
409
Willy Tarreau721d8e02017-12-01 18:25:08 +0100410/* Report a warning if a rule is placed after a 'monitor fail' rule.
411 * Return 1 if the warning has been emitted, otherwise 0.
412 */
413int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
414{
415 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
416 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
417 file, line, arg);
418 return 1;
419 }
420 return 0;
421}
422
Willy Tarreau61d18892009-03-31 10:49:21 +0200423/* Report a warning if a rule is placed after a 'block' rule.
424 * Return 1 if the warning has been emitted, otherwise 0.
425 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100426int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200427{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200428 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100429 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
430 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200431 return 1;
432 }
433 return 0;
434}
435
Willy Tarreau5002f572014-04-23 01:32:02 +0200436/* Report a warning if a rule is placed after an 'http_request' rule.
437 * Return 1 if the warning has been emitted, otherwise 0.
438 */
439int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
440{
441 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100442 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
443 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200444 return 1;
445 }
446 return 0;
447}
448
Willy Tarreau61d18892009-03-31 10:49:21 +0200449/* Report a warning if a rule is placed after a reqrewrite rule.
450 * Return 1 if the warning has been emitted, otherwise 0.
451 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100452int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200453{
454 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100455 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
456 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200457 return 1;
458 }
459 return 0;
460}
461
462/* Report a warning if a rule is placed after a reqadd rule.
463 * Return 1 if the warning has been emitted, otherwise 0.
464 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100465int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200466{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100467 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100468 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
469 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200470 return 1;
471 }
472 return 0;
473}
474
475/* Report a warning if a rule is placed after a redirect rule.
476 * Return 1 if the warning has been emitted, otherwise 0.
477 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100478int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200479{
480 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100481 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
482 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200483 return 1;
484 }
485 return 0;
486}
487
488/* Report a warning if a rule is placed after a 'use_backend' rule.
489 * Return 1 if the warning has been emitted, otherwise 0.
490 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100491int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200492{
493 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100494 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
495 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200496 return 1;
497 }
498 return 0;
499}
500
Willy Tarreauee445d92014-04-23 01:39:04 +0200501/* Report a warning if a rule is placed after a 'use-server' rule.
502 * Return 1 if the warning has been emitted, otherwise 0.
503 */
504int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
505{
506 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100507 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
508 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200509 return 1;
510 }
511 return 0;
512}
513
Willy Tarreaud39ad442016-11-25 15:16:12 +0100514/* report a warning if a redirect rule is dangerously placed */
515int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200516{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100517 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200518 warnif_rule_after_use_server(proxy, file, line, arg);
519}
520
Willy Tarreaud39ad442016-11-25 15:16:12 +0100521/* report a warning if a reqadd rule is dangerously placed */
522int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200523{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100524 return warnif_rule_after_redirect(proxy, file, line, arg) ||
525 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200526}
527
Willy Tarreaud39ad442016-11-25 15:16:12 +0100528/* report a warning if a reqxxx rule is dangerously placed */
529int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200530{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100531 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
532 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200533}
534
535/* report a warning if an http-request rule is dangerously placed */
536int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
537{
Willy Tarreau61d18892009-03-31 10:49:21 +0200538 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100539 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200540}
541
Willy Tarreaud39ad442016-11-25 15:16:12 +0100542/* report a warning if a block rule is dangerously placed */
543int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200544{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100545 return warnif_rule_after_http_req(proxy, file, line, arg) ||
546 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200547}
548
Willy Tarreau721d8e02017-12-01 18:25:08 +0100549/* report a warning if a block rule is dangerously placed */
550int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200551{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100552 return warnif_rule_after_block(proxy, file, line, arg) ||
553 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200554}
555
Willy Tarreau721d8e02017-12-01 18:25:08 +0100556/* report a warning if a "tcp request content" rule is dangerously placed */
557int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
558{
559 return warnif_rule_after_monitor(proxy, file, line, arg) ||
560 warnif_misplaced_monitor(proxy, file, line, arg);
561}
562
Willy Tarreaud39ad442016-11-25 15:16:12 +0100563/* report a warning if a "tcp request session" rule is dangerously placed */
564int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200565{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100566 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
567 warnif_misplaced_tcp_cont(proxy, file, line, arg);
568}
569
570/* report a warning if a "tcp request connection" rule is dangerously placed */
571int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
572{
573 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
574 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200575}
576
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100577/* Report it if a request ACL condition uses some keywords that are incompatible
578 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
579 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
580 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100581 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100582static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100583{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100584 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200585 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100586
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100587 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100588 return 0;
589
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100590 acl = acl_cond_conflicts(cond, where);
591 if (acl) {
592 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100593 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
594 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100595 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100596 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
597 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100598 return ERR_WARN;
599 }
600 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100601 return 0;
602
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100603 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100604 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
605 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100606 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100607 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
608 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100609 return ERR_WARN;
610}
611
Christopher Faulet62519022017-10-16 15:49:32 +0200612/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100613 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100614 * two such numbers delimited by a dash ('-'). On success, it returns
615 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200616 *
617 * Note: this function can also be used to parse a thread number or a set of
618 * threads.
619 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100620int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200621{
Christopher Faulet26028f62017-11-22 15:01:51 +0100622 if (autoinc) {
623 *autoinc = 0;
624 if (strncmp(arg, "auto:", 5) == 0) {
625 arg += 5;
626 *autoinc = 1;
627 }
628 }
629
Christopher Faulet62519022017-10-16 15:49:32 +0200630 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100631 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200632 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100633 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200634 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100635 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200636 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100637 char *dash;
638 unsigned int low, high;
639
Christopher Faulet5ab51772017-11-22 11:21:58 +0100640 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100641 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100642 return -1;
643 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100644
645 low = high = str2uic(arg);
646 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100647 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
648
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100649 if (high < low) {
650 unsigned int swap = low;
651 low = high;
652 high = swap;
653 }
654
Christopher Faulet5ab51772017-11-22 11:21:58 +0100655 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100656 memprintf(err, "'%s' is not a valid number/range."
657 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100658 arg, LONGBITS);
659 return 1;
660 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100661
662 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100663 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200664 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100665
Christopher Faulet5ab51772017-11-22 11:21:58 +0100666 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200667}
668
David Carlier7e351ee2017-12-01 09:14:02 +0000669#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200670/* Parse cpu sets. Each CPU set is either a unique number between 0 and
671 * <LONGBITS> or a range with two such numbers delimited by a dash
672 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
673 * returns 0. otherwise it returns 1 with an error message in <err>.
674 */
675static unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
676{
677 int cur_arg = 0;
678
679 *cpu_set = 0;
680 while (*args[cur_arg]) {
681 char *dash;
682 unsigned int low, high;
683
684 if (!isdigit((int)*args[cur_arg])) {
685 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
686 return -1;
687 }
688
689 low = high = str2uic(args[cur_arg]);
690 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100691 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200692
693 if (high < low) {
694 unsigned int swap = low;
695 low = high;
696 high = swap;
697 }
698
699 if (high >= LONGBITS) {
700 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
701 return 1;
702 }
703
704 while (low <= high)
705 *cpu_set |= 1UL << low++;
706
707 cur_arg++;
708 }
709 return 0;
710}
David Carlier7e351ee2017-12-01 09:14:02 +0000711#endif
712
Willy Tarreaubaaee002006-06-26 02:48:02 +0200713/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200714 * parse a line in a <global> section. Returns the error code, 0 if OK, or
715 * any combination of :
716 * - ERR_ABORT: must abort ASAP
717 * - ERR_FATAL: we can continue parsing but not start the service
718 * - ERR_WARN: a warning has been emitted
719 * - ERR_ALERT: an alert has been emitted
720 * Only the two first ones can stop processing, the two others are just
721 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200722 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200723int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200724{
Willy Tarreau058e9072009-07-20 09:30:05 +0200725 int err_code = 0;
Willy Tarreau0a3dd742012-05-08 19:47:01 +0200726 char *errmsg = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200727
728 if (!strcmp(args[0], "global")) { /* new section */
729 /* no option, nothing special to do */
William Lallemand6e62fb62015-04-28 16:55:23 +0200730 alertif_too_many_args(0, file, linenum, args, &err_code);
Willy Tarreau058e9072009-07-20 09:30:05 +0200731 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200732 }
733 else if (!strcmp(args[0], "daemon")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200734 if (alertif_too_many_args(0, file, linenum, args, &err_code))
735 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200736 global.mode |= MODE_DAEMON;
737 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200738 else if (!strcmp(args[0], "master-worker")) {
William Lallemand69f9b3b2017-06-01 17:38:54 +0200739 if (alertif_too_many_args(1, file, linenum, args, &err_code))
William Lallemand095ba4c2017-06-01 17:38:50 +0200740 goto out;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200741 if (*args[1]) {
William Lallemand4cfede82017-11-24 22:02:34 +0100742 if (!strcmp(args[1], "no-exit-on-failure")) {
743 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
William Lallemand69f9b3b2017-06-01 17:38:54 +0200744 } else {
Tim Duesterhusc578d9a2017-12-05 18:14:12 +0100745 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
William Lallemand69f9b3b2017-06-01 17:38:54 +0200746 err_code |= ERR_ALERT | ERR_FATAL;
747 goto out;
748 }
749 }
William Lallemand095ba4c2017-06-01 17:38:50 +0200750 global.mode |= MODE_MWORKER;
751 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200752 else if (!strcmp(args[0], "debug")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200753 if (alertif_too_many_args(0, file, linenum, args, &err_code))
754 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200755 global.mode |= MODE_DEBUG;
756 }
757 else if (!strcmp(args[0], "noepoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200758 if (alertif_too_many_args(0, file, linenum, args, &err_code))
759 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100760 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200761 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200762 else if (!strcmp(args[0], "nokqueue")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200763 if (alertif_too_many_args(0, file, linenum, args, &err_code))
764 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100765 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200766 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200767 else if (!strcmp(args[0], "nopoll")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200768 if (alertif_too_many_args(0, file, linenum, args, &err_code))
769 goto out;
Willy Tarreau43b78992009-01-25 15:42:27 +0100770 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200771 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100772 else if (!strcmp(args[0], "nosplice")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200773 if (alertif_too_many_args(0, file, linenum, args, &err_code))
774 goto out;
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100775 global.tune.options &= ~GTUNE_USE_SPLICE;
776 }
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200777 else if (!strcmp(args[0], "nogetaddrinfo")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200778 if (alertif_too_many_args(0, file, linenum, args, &err_code))
779 goto out;
Nenad Merdanovic88afe032014-04-14 15:56:58 +0200780 global.tune.options &= ~GTUNE_USE_GAI;
781 }
Lukas Tribusa0bcbdc2016-09-12 21:42:20 +0000782 else if (!strcmp(args[0], "noreuseport")) {
783 if (alertif_too_many_args(0, file, linenum, args, &err_code))
784 goto out;
785 global.tune.options &= ~GTUNE_USE_REUSEPORT;
786 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200787 else if (!strcmp(args[0], "quiet")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200788 if (alertif_too_many_args(0, file, linenum, args, &err_code))
789 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200790 global.mode |= MODE_QUIET;
791 }
Olivier Houchard1599b802018-05-24 18:59:04 +0200792 else if (!strcmp(args[0], "tune.runqueue-depth")) {
793 if (alertif_too_many_args(1, file, linenum, args, &err_code))
794 goto out;
795 if (global.tune.runqueue_depth != 0) {
796 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
797 err_code |= ERR_ALERT;
798 goto out;
799 }
800 if (*(args[1]) == 0) {
801 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
802 err_code |= ERR_ALERT | ERR_FATAL;
803 goto out;
804 }
805 global.tune.runqueue_depth = atol(args[1]);
806
807 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200808 else if (!strcmp(args[0], "tune.maxpollevents")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200809 if (alertif_too_many_args(1, file, linenum, args, &err_code))
810 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200811 if (global.tune.maxpollevents != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100812 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200813 err_code |= ERR_ALERT;
814 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200815 }
816 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100817 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200818 err_code |= ERR_ALERT | ERR_FATAL;
819 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200820 }
821 global.tune.maxpollevents = atol(args[1]);
822 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100823 else if (!strcmp(args[0], "tune.maxaccept")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200824 if (alertif_too_many_args(1, file, linenum, args, &err_code))
825 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100826 if (global.tune.maxaccept != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100827 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200828 err_code |= ERR_ALERT;
829 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100830 }
831 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100832 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200833 err_code |= ERR_ALERT | ERR_FATAL;
834 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100835 }
836 global.tune.maxaccept = atol(args[1]);
837 }
Willy Tarreau43961d52010-10-04 20:39:20 +0200838 else if (!strcmp(args[0], "tune.chksize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200839 if (alertif_too_many_args(1, file, linenum, args, &err_code))
840 goto out;
Willy Tarreau43961d52010-10-04 20:39:20 +0200841 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100842 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau43961d52010-10-04 20:39:20 +0200843 err_code |= ERR_ALERT | ERR_FATAL;
844 goto out;
845 }
846 global.tune.chksize = atol(args[1]);
847 }
Willy Tarreaub22fc302015-12-14 12:04:35 +0100848 else if (!strcmp(args[0], "tune.recv_enough")) {
849 if (alertif_too_many_args(1, file, linenum, args, &err_code))
850 goto out;
851 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100852 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaub22fc302015-12-14 12:04:35 +0100853 err_code |= ERR_ALERT | ERR_FATAL;
854 goto out;
855 }
856 global.tune.recv_enough = atol(args[1]);
857 }
Willy Tarreau33cb0652014-12-23 22:52:37 +0100858 else if (!strcmp(args[0], "tune.buffers.limit")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200859 if (alertif_too_many_args(1, file, linenum, args, &err_code))
860 goto out;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100861 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100862 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau33cb0652014-12-23 22:52:37 +0100863 err_code |= ERR_ALERT | ERR_FATAL;
864 goto out;
865 }
866 global.tune.buf_limit = atol(args[1]);
867 if (global.tune.buf_limit) {
868 if (global.tune.buf_limit < 3)
869 global.tune.buf_limit = 3;
870 if (global.tune.buf_limit <= global.tune.reserved_bufs)
871 global.tune.buf_limit = global.tune.reserved_bufs + 1;
872 }
873 }
Willy Tarreau1058ae72014-12-23 22:40:40 +0100874 else if (!strcmp(args[0], "tune.buffers.reserve")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200875 if (alertif_too_many_args(1, file, linenum, args, &err_code))
876 goto out;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100877 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100878 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau1058ae72014-12-23 22:40:40 +0100879 err_code |= ERR_ALERT | ERR_FATAL;
880 goto out;
881 }
882 global.tune.reserved_bufs = atol(args[1]);
883 if (global.tune.reserved_bufs < 2)
884 global.tune.reserved_bufs = 2;
Willy Tarreau33cb0652014-12-23 22:52:37 +0100885 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
886 global.tune.buf_limit = global.tune.reserved_bufs + 1;
Willy Tarreau1058ae72014-12-23 22:40:40 +0100887 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200888 else if (!strcmp(args[0], "tune.bufsize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200889 if (alertif_too_many_args(1, file, linenum, args, &err_code))
890 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200891 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100892 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200893 err_code |= ERR_ALERT | ERR_FATAL;
894 goto out;
895 }
896 global.tune.bufsize = atol(args[1]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200897 if (global.tune.bufsize <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100898 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau9b694542015-09-28 13:49:53 +0200899 err_code |= ERR_ALERT | ERR_FATAL;
900 goto out;
901 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200902 }
903 else if (!strcmp(args[0], "tune.maxrewrite")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200904 if (alertif_too_many_args(1, file, linenum, args, &err_code))
905 goto out;
Willy Tarreau27a674e2009-08-17 07:23:33 +0200906 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100907 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau27a674e2009-08-17 07:23:33 +0200908 err_code |= ERR_ALERT | ERR_FATAL;
909 goto out;
910 }
911 global.tune.maxrewrite = atol(args[1]);
Willy Tarreau27097842015-09-28 13:53:23 +0200912 if (global.tune.maxrewrite < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100913 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
Willy Tarreau27097842015-09-28 13:53:23 +0200914 err_code |= ERR_ALERT | ERR_FATAL;
915 goto out;
916 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200917 }
Willy Tarreau7e312732014-02-12 16:35:14 +0100918 else if (!strcmp(args[0], "tune.idletimer")) {
919 unsigned int idle;
920 const char *res;
921
William Lallemand1a748ae2015-05-19 16:37:23 +0200922 if (alertif_too_many_args(1, file, linenum, args, &err_code))
923 goto out;
Willy Tarreau7e312732014-02-12 16:35:14 +0100924 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100925 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100926 err_code |= ERR_ALERT | ERR_FATAL;
927 goto out;
928 }
929
930 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
931 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100932 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau7e312732014-02-12 16:35:14 +0100933 file, linenum, *res, args[0]);
934 err_code |= ERR_ALERT | ERR_FATAL;
935 goto out;
936 }
937
938 if (idle > 65535) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100939 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
Willy Tarreau7e312732014-02-12 16:35:14 +0100940 err_code |= ERR_ALERT | ERR_FATAL;
941 goto out;
942 }
943 global.tune.idle_timer = idle;
944 }
Willy Tarreaue803de22010-01-21 17:43:04 +0100945 else if (!strcmp(args[0], "tune.rcvbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200946 if (alertif_too_many_args(1, file, linenum, args, &err_code))
947 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100948 if (global.tune.client_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100949 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100950 err_code |= ERR_ALERT;
951 goto out;
952 }
953 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100954 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100955 err_code |= ERR_ALERT | ERR_FATAL;
956 goto out;
957 }
958 global.tune.client_rcvbuf = atol(args[1]);
959 }
960 else if (!strcmp(args[0], "tune.rcvbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200961 if (alertif_too_many_args(1, file, linenum, args, &err_code))
962 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100963 if (global.tune.server_rcvbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100964 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100965 err_code |= ERR_ALERT;
966 goto out;
967 }
968 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100969 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100970 err_code |= ERR_ALERT | ERR_FATAL;
971 goto out;
972 }
973 global.tune.server_rcvbuf = atol(args[1]);
974 }
975 else if (!strcmp(args[0], "tune.sndbuf.client")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200976 if (alertif_too_many_args(1, file, linenum, args, &err_code))
977 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100978 if (global.tune.client_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100979 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100980 err_code |= ERR_ALERT;
981 goto out;
982 }
983 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100984 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100985 err_code |= ERR_ALERT | ERR_FATAL;
986 goto out;
987 }
988 global.tune.client_sndbuf = atol(args[1]);
989 }
990 else if (!strcmp(args[0], "tune.sndbuf.server")) {
William Lallemand1a748ae2015-05-19 16:37:23 +0200991 if (alertif_too_many_args(1, file, linenum, args, &err_code))
992 goto out;
Willy Tarreaue803de22010-01-21 17:43:04 +0100993 if (global.tune.server_sndbuf != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100994 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +0100995 err_code |= ERR_ALERT;
996 goto out;
997 }
998 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100999 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue803de22010-01-21 17:43:04 +01001000 err_code |= ERR_ALERT | ERR_FATAL;
1001 goto out;
1002 }
1003 global.tune.server_sndbuf = atol(args[1]);
1004 }
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001005 else if (!strcmp(args[0], "tune.pipesize")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001006 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1007 goto out;
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001008 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001009 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaubd9a0a72011-10-23 21:14:29 +02001010 err_code |= ERR_ALERT | ERR_FATAL;
1011 goto out;
1012 }
1013 global.tune.pipesize = atol(args[1]);
1014 }
Willy Tarreau193b8c62012-11-22 00:17:38 +01001015 else if (!strcmp(args[0], "tune.http.cookielen")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001016 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1017 goto out;
Willy Tarreau193b8c62012-11-22 00:17:38 +01001018 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001019 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau193b8c62012-11-22 00:17:38 +01001020 err_code |= ERR_ALERT | ERR_FATAL;
1021 goto out;
1022 }
1023 global.tune.cookie_len = atol(args[1]) + 1;
1024 }
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001025 else if (!strcmp(args[0], "tune.http.logurilen")) {
1026 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1027 goto out;
1028 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001029 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Stéphane Cottin23e9e932017-05-18 08:58:41 +02001030 err_code |= ERR_ALERT | ERR_FATAL;
1031 goto out;
1032 }
1033 global.tune.requri_len = atol(args[1]) + 1;
1034 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001035 else if (!strcmp(args[0], "tune.http.maxhdr")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001036 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1037 goto out;
Willy Tarreauac1932d2011-10-24 19:14:41 +02001038 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001039 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreauac1932d2011-10-24 19:14:41 +02001040 err_code |= ERR_ALERT | ERR_FATAL;
1041 goto out;
1042 }
Christopher Faulet50174f32017-06-21 16:31:35 +02001043 global.tune.max_http_hdr = atoi(args[1]);
1044 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001045 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
1046 file, linenum, args[0]);
Christopher Faulet50174f32017-06-21 16:31:35 +02001047 err_code |= ERR_ALERT | ERR_FATAL;
1048 goto out;
1049 }
Willy Tarreauac1932d2011-10-24 19:14:41 +02001050 }
William Lallemandf3747832012-11-09 12:33:10 +01001051 else if (!strcmp(args[0], "tune.comp.maxlevel")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001052 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1053 goto out;
William Lallemandf3747832012-11-09 12:33:10 +01001054 if (*args[1]) {
1055 global.tune.comp_maxlevel = atoi(args[1]);
1056 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001057 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1058 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001059 err_code |= ERR_ALERT | ERR_FATAL;
1060 goto out;
1061 }
1062 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001063 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
1064 file, linenum, args[0]);
William Lallemandf3747832012-11-09 12:33:10 +01001065 err_code |= ERR_ALERT | ERR_FATAL;
1066 goto out;
1067 }
1068 }
Willy Tarreauf3045d22015-04-29 16:24:50 +02001069 else if (!strcmp(args[0], "tune.pattern.cache-size")) {
1070 if (*args[1]) {
1071 global.tune.pattern_cache = atoi(args[1]);
1072 if (global.tune.pattern_cache < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001073 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1074 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001075 err_code |= ERR_ALERT | ERR_FATAL;
1076 goto out;
1077 }
1078 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001079 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
1080 file, linenum, args[0]);
Willy Tarreauf3045d22015-04-29 16:24:50 +02001081 err_code |= ERR_ALERT | ERR_FATAL;
1082 goto out;
1083 }
1084 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001085 else if (!strcmp(args[0], "uid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001086 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1087 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001088 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001089 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001090 err_code |= ERR_ALERT;
1091 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001092 }
1093 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001094 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001095 err_code |= ERR_ALERT | ERR_FATAL;
1096 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001097 }
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001098 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001099 ha_warning("parsing [%s:%d] : uid: string '%s' is not a number.\n | You might want to use the 'user' parameter to use a system user name.\n", file, linenum, args[1]);
Baptiste Assmann79fee6a2016-03-11 17:10:04 +01001100 err_code |= ERR_WARN;
1101 goto out;
1102 }
1103
Willy Tarreaubaaee002006-06-26 02:48:02 +02001104 }
1105 else if (!strcmp(args[0], "gid")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001106 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1107 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001108 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001109 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001110 err_code |= ERR_ALERT;
1111 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001112 }
1113 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001114 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001115 err_code |= ERR_ALERT | ERR_FATAL;
1116 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001117 }
Baptiste Assmann776e5182016-03-11 17:21:15 +01001118 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001119 ha_warning("parsing [%s:%d] : gid: string '%s' is not a number.\n | You might want to use the 'group' parameter to use a system group name.\n", file, linenum, args[1]);
Baptiste Assmann776e5182016-03-11 17:21:15 +01001120 err_code |= ERR_WARN;
1121 goto out;
1122 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001123 }
Simon Horman98637e52014-06-20 12:30:16 +09001124 else if (!strcmp(args[0], "external-check")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001125 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1126 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09001127 global.external_check = 1;
1128 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001129 /* user/group name handling */
1130 else if (!strcmp(args[0], "user")) {
1131 struct passwd *ha_user;
William Lallemand1a748ae2015-05-19 16:37:23 +02001132 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1133 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001134 if (global.uid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001135 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001136 err_code |= ERR_ALERT;
1137 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001138 }
1139 errno = 0;
1140 ha_user = getpwnam(args[1]);
1141 if (ha_user != NULL) {
1142 global.uid = (int)ha_user->pw_uid;
1143 }
1144 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001145 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001146 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001147 }
1148 }
1149 else if (!strcmp(args[0], "group")) {
1150 struct group *ha_group;
William Lallemand1a748ae2015-05-19 16:37:23 +02001151 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1152 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001153 if (global.gid != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001154 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001155 err_code |= ERR_ALERT;
1156 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001157 }
1158 errno = 0;
1159 ha_group = getgrnam(args[1]);
1160 if (ha_group != NULL) {
1161 global.gid = (int)ha_group->gr_gid;
1162 }
1163 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001164 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +02001165 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +02001166 }
1167 }
1168 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +02001169 else if (!strcmp(args[0], "nbproc")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001170 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1171 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001172 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001173 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001174 err_code |= ERR_ALERT | ERR_FATAL;
1175 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001176 }
1177 global.nbproc = atol(args[1]);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001178 if (global.nbproc < 1 || global.nbproc > LONGBITS) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001179 ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
1180 file, linenum, args[0], LONGBITS, global.nbproc);
Willy Tarreaua9db57e2013-01-18 11:29:29 +01001181 err_code |= ERR_ALERT | ERR_FATAL;
1182 goto out;
1183 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001184 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001185 else if (!strcmp(args[0], "nbthread")) {
1186 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1187 goto out;
1188 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001189 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001190 err_code |= ERR_ALERT | ERR_FATAL;
1191 goto out;
1192 }
Willy Tarreau0ccd3222018-07-30 10:34:35 +02001193 global.nbthread = parse_nbthread(args[1], &errmsg);
1194 if (!global.nbthread) {
1195 ha_alert("parsing [%s:%d] : '%s' %s.\n",
1196 file, linenum, args[0], errmsg);
Willy Tarreau421f02e2018-01-20 18:19:22 +01001197 err_code |= ERR_ALERT | ERR_FATAL;
1198 goto out;
1199 }
Christopher Fauletbe0faa22017-08-29 15:37:10 +02001200 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001201 else if (!strcmp(args[0], "maxconn")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001202 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1203 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001204 if (global.maxconn != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001205 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001206 err_code |= ERR_ALERT;
1207 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001208 }
1209 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001210 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001211 err_code |= ERR_ALERT | ERR_FATAL;
1212 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001213 }
1214 global.maxconn = atol(args[1]);
1215#ifdef SYSTEM_MAXCONN
1216 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001217 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 +02001218 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +02001219 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001220 }
1221#endif /* SYSTEM_MAXCONN */
1222 }
Emeric Brun850efd52014-01-29 12:24:34 +01001223 else if (!strcmp(args[0], "ssl-server-verify")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001224 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1225 goto out;
Emeric Brun850efd52014-01-29 12:24:34 +01001226 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001227 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001228 err_code |= ERR_ALERT | ERR_FATAL;
1229 goto out;
1230 }
1231 if (strcmp(args[1],"none") == 0)
1232 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1233 else if (strcmp(args[1],"required") == 0)
1234 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
1235 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001236 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
Emeric Brun850efd52014-01-29 12:24:34 +01001237 err_code |= ERR_ALERT | ERR_FATAL;
1238 goto out;
1239 }
1240 }
Willy Tarreau81c25d02011-09-07 15:17:21 +02001241 else if (!strcmp(args[0], "maxconnrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001242 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1243 goto out;
Willy Tarreau81c25d02011-09-07 15:17:21 +02001244 if (global.cps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001245 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001246 err_code |= ERR_ALERT;
1247 goto out;
1248 }
1249 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001250 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau81c25d02011-09-07 15:17:21 +02001251 err_code |= ERR_ALERT | ERR_FATAL;
1252 goto out;
1253 }
1254 global.cps_lim = atol(args[1]);
1255 }
Willy Tarreau93e7c002013-10-07 18:51:07 +02001256 else if (!strcmp(args[0], "maxsessrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001257 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1258 goto out;
Willy Tarreau93e7c002013-10-07 18:51:07 +02001259 if (global.sps_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001260 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001261 err_code |= ERR_ALERT;
1262 goto out;
1263 }
1264 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001265 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93e7c002013-10-07 18:51:07 +02001266 err_code |= ERR_ALERT | ERR_FATAL;
1267 goto out;
1268 }
1269 global.sps_lim = atol(args[1]);
1270 }
Willy Tarreaue43d5322013-10-07 20:01:52 +02001271 else if (!strcmp(args[0], "maxsslrate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001272 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1273 goto out;
Willy Tarreaue43d5322013-10-07 20:01:52 +02001274 if (global.ssl_lim != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001275 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001276 err_code |= ERR_ALERT;
1277 goto out;
1278 }
1279 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001280 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreaue43d5322013-10-07 20:01:52 +02001281 err_code |= ERR_ALERT | ERR_FATAL;
1282 goto out;
1283 }
1284 global.ssl_lim = atol(args[1]);
1285 }
William Lallemandd85f9172012-11-09 17:05:39 +01001286 else if (!strcmp(args[0], "maxcomprate")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001287 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1288 goto out;
William Lallemandd85f9172012-11-09 17:05:39 +01001289 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001290 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 +01001291 err_code |= ERR_ALERT | ERR_FATAL;
1292 goto out;
1293 }
1294 global.comp_rate_lim = atoi(args[1]) * 1024;
1295 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001296 else if (!strcmp(args[0], "maxpipes")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001297 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1298 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001299 if (global.maxpipes != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001300 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001301 err_code |= ERR_ALERT;
1302 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001303 }
1304 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001305 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001306 err_code |= ERR_ALERT | ERR_FATAL;
1307 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +01001308 }
1309 global.maxpipes = atol(args[1]);
1310 }
William Lallemand9d5f5482012-11-07 16:12:57 +01001311 else if (!strcmp(args[0], "maxzlibmem")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001312 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1313 goto out;
William Lallemand9d5f5482012-11-07 16:12:57 +01001314 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]);
William Lallemand9d5f5482012-11-07 16:12:57 +01001316 err_code |= ERR_ALERT | ERR_FATAL;
1317 goto out;
1318 }
William Lallemande3a7d992012-11-20 11:25:20 +01001319 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
William Lallemand9d5f5482012-11-07 16:12:57 +01001320 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001321 else if (!strcmp(args[0], "maxcompcpuusage")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001322 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1323 goto out;
William Lallemand072a2bf2012-11-20 17:01:01 +01001324 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001325 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 +01001326 err_code |= ERR_ALERT | ERR_FATAL;
1327 goto out;
1328 }
1329 compress_min_idle = 100 - atoi(args[1]);
Willy Tarreaucb2699a2013-01-24 16:25:38 +01001330 if (compress_min_idle > 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001331 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 +01001332 err_code |= ERR_ALERT | ERR_FATAL;
1333 goto out;
1334 }
William Lallemand1a748ae2015-05-19 16:37:23 +02001335 }
William Lallemand072a2bf2012-11-20 17:01:01 +01001336
Willy Tarreaubaaee002006-06-26 02:48:02 +02001337 else if (!strcmp(args[0], "ulimit-n")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001338 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1339 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001340 if (global.rlimit_nofile != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001341 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001342 err_code |= ERR_ALERT;
1343 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001344 }
1345 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001346 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001347 err_code |= ERR_ALERT | ERR_FATAL;
1348 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001349 }
1350 global.rlimit_nofile = atol(args[1]);
1351 }
1352 else if (!strcmp(args[0], "chroot")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001353 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1354 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001355 if (global.chroot != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001356 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001357 err_code |= ERR_ALERT;
1358 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001359 }
1360 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001361 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001362 err_code |= ERR_ALERT | ERR_FATAL;
1363 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001364 }
1365 global.chroot = strdup(args[1]);
1366 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001367 else if (!strcmp(args[0], "description")) {
1368 int i, len=0;
1369 char *d;
1370
1371 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001372 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1373 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001374 err_code |= ERR_ALERT | ERR_FATAL;
1375 goto out;
1376 }
1377
Willy Tarreau348acfe2014-04-14 15:00:39 +02001378 for (i = 1; *args[i]; i++)
1379 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001380
1381 if (global.desc)
1382 free(global.desc);
1383
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001384 global.desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001385
Willy Tarreau348acfe2014-04-14 15:00:39 +02001386 d += snprintf(d, global.desc + len - d, "%s", args[1]);
1387 for (i = 2; *args[i]; i++)
1388 d += snprintf(d, global.desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001389 }
1390 else if (!strcmp(args[0], "node")) {
1391 int i;
1392 char c;
1393
William Lallemand1a748ae2015-05-19 16:37:23 +02001394 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1395 goto out;
1396
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001397 for (i=0; args[1][i]; i++) {
1398 c = args[1][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01001399 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
1400 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001401 break;
1402 }
1403
1404 if (!i || args[1][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001405 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
1406 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
1407 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001408 err_code |= ERR_ALERT | ERR_FATAL;
1409 goto out;
1410 }
1411
1412 if (global.node)
1413 free(global.node);
1414
1415 global.node = strdup(args[1]);
1416 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001417 else if (!strcmp(args[0], "pidfile")) {
William Lallemand1a748ae2015-05-19 16:37:23 +02001418 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1419 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001420 if (global.pidfile != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001421 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001422 err_code |= ERR_ALERT;
1423 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001424 }
1425 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001426 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 +02001427 err_code |= ERR_ALERT | ERR_FATAL;
1428 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001429 }
1430 global.pidfile = strdup(args[1]);
1431 }
Emeric Bruned760922010-10-22 17:59:25 +02001432 else if (!strcmp(args[0], "unix-bind")) {
1433 int cur_arg = 1;
1434 while (*(args[cur_arg])) {
1435 if (!strcmp(args[cur_arg], "prefix")) {
1436 if (global.unix_bind.prefix != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001437 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
Emeric Bruned760922010-10-22 17:59:25 +02001438 err_code |= ERR_ALERT;
1439 cur_arg += 2;
1440 continue;
1441 }
1442
1443 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001444 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 +02001445 err_code |= ERR_ALERT | ERR_FATAL;
1446 goto out;
1447 }
1448 global.unix_bind.prefix = strdup(args[cur_arg+1]);
1449 cur_arg += 2;
1450 continue;
1451 }
1452
1453 if (!strcmp(args[cur_arg], "mode")) {
1454
1455 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
1456 cur_arg += 2;
1457 continue;
1458 }
1459
1460 if (!strcmp(args[cur_arg], "uid")) {
1461
1462 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
1463 cur_arg += 2;
1464 continue;
1465 }
1466
1467 if (!strcmp(args[cur_arg], "gid")) {
1468
1469 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
1470 cur_arg += 2;
1471 continue;
1472 }
1473
1474 if (!strcmp(args[cur_arg], "user")) {
1475 struct passwd *user;
1476
1477 user = getpwnam(args[cur_arg + 1]);
1478 if (!user) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001479 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
1480 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001481 err_code |= ERR_ALERT | ERR_FATAL;
1482 goto out;
1483 }
1484
1485 global.unix_bind.ux.uid = user->pw_uid;
1486 cur_arg += 2;
1487 continue;
1488 }
1489
1490 if (!strcmp(args[cur_arg], "group")) {
1491 struct group *group;
1492
1493 group = getgrnam(args[cur_arg + 1]);
1494 if (!group) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001495 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
1496 file, linenum, args[0], args[cur_arg + 1 ]);
Emeric Bruned760922010-10-22 17:59:25 +02001497 err_code |= ERR_ALERT | ERR_FATAL;
1498 goto out;
1499 }
1500
1501 global.unix_bind.ux.gid = group->gr_gid;
1502 cur_arg += 2;
1503 continue;
1504 }
1505
Christopher Faulet767a84b2017-11-24 16:50:31 +01001506 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
1507 file, linenum, args[0]);
Emeric Bruned760922010-10-22 17:59:25 +02001508 err_code |= ERR_ALERT | ERR_FATAL;
1509 goto out;
1510 }
1511 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02001512 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
1513 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
1514 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001515 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau9b435bc2013-03-06 15:02:49 +01001516 goto out;
1517 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001518 }
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001519 else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
1520 char *name;
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001521
1522 if (global.log_send_hostname != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001523 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001524 err_code |= ERR_ALERT;
1525 goto out;
1526 }
1527
1528 if (*(args[1]))
1529 name = args[1];
1530 else
1531 name = hostname;
1532
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001533 free(global.log_send_hostname);
Dragan Dosenc8cfa7b2015-09-28 13:28:21 +02001534 global.log_send_hostname = strdup(name);
Joe Williamsdf5b38f2010-12-29 17:05:48 +01001535 }
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001536 else if (!strcmp(args[0], "server-state-base")) { /* path base where HAProxy can find server state files */
1537 if (global.server_state_base != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001538 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001539 err_code |= ERR_ALERT;
1540 goto out;
1541 }
1542
1543 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001544 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
Baptiste Assmann6bc89362015-08-23 09:22:25 +02001545 err_code |= ERR_FATAL;
1546 goto out;
1547 }
1548
1549 global.server_state_base = strdup(args[1]);
1550 }
Baptiste Assmanne0882262015-08-23 09:54:31 +02001551 else if (!strcmp(args[0], "server-state-file")) { /* path to the file where HAProxy can load the server states */
1552 if (global.server_state_file != NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001553 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001554 err_code |= ERR_ALERT;
1555 goto out;
1556 }
1557
1558 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001559 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
Baptiste Assmanne0882262015-08-23 09:54:31 +02001560 err_code |= ERR_FATAL;
1561 goto out;
1562 }
1563
1564 global.server_state_file = strdup(args[1]);
1565 }
Kevinm48936af2010-12-22 16:08:21 +00001566 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
William Lallemand1a748ae2015-05-19 16:37:23 +02001567 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1568 goto out;
Kevinm48936af2010-12-22 16:08:21 +00001569 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001570 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
Kevinm48936af2010-12-22 16:08:21 +00001571 err_code |= ERR_ALERT | ERR_FATAL;
1572 goto out;
1573 }
Dragan Dosen43885c72015-10-01 13:18:13 +02001574 chunk_destroy(&global.log_tag);
1575 chunk_initstr(&global.log_tag, strdup(args[1]));
Kevinm48936af2010-12-22 16:08:21 +00001576 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001577 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
William Lallemand1a748ae2015-05-19 16:37:23 +02001578 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1579 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001580 if (global.spread_checks != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001581 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02001582 err_code |= ERR_ALERT;
1583 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001584 }
1585 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001586 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02001587 err_code |= ERR_ALERT | ERR_FATAL;
1588 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001589 }
1590 global.spread_checks = atol(args[1]);
1591 if (global.spread_checks < 0 || global.spread_checks > 50) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001592 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 +02001593 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +02001594 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001595 }
Willy Tarreau1746eec2014-04-25 10:46:47 +02001596 else if (!strcmp(args[0], "max-spread-checks")) { /* maximum time between first and last check */
1597 const char *err;
1598 unsigned int val;
1599
William Lallemand1a748ae2015-05-19 16:37:23 +02001600 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1601 goto out;
Willy Tarreau1746eec2014-04-25 10:46:47 +02001602 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001603 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001604 err_code |= ERR_ALERT | ERR_FATAL;
1605 goto out;
1606 }
1607
1608 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1609 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001610 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 +02001611 err_code |= ERR_ALERT | ERR_FATAL;
1612 }
1613 global.max_spread_checks = val;
1614 if (global.max_spread_checks < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001615 ha_alert("parsing [%s:%d]: '%s' needs a positive delay in milliseconds.\n",file, linenum, args[0]);
Willy Tarreau1746eec2014-04-25 10:46:47 +02001616 err_code |= ERR_ALERT | ERR_FATAL;
1617 }
1618 }
Christopher Faulet62519022017-10-16 15:49:32 +02001619 else if (strcmp(args[0], "cpu-map") == 0) {
1620 /* map a process list to a CPU set */
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001621#ifdef USE_CPU_AFFINITY
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001622 char *slash;
1623 unsigned long proc = 0, thread = 0, cpus;
1624 int i, j, n, autoinc;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001625
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001626 if (!*args[1] || !*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001627 ha_alert("parsing [%s:%d] : %s expects a process number "
1628 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1629 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
1630 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001631 err_code |= ERR_ALERT | ERR_FATAL;
1632 goto out;
1633 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001634
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001635 if ((slash = strchr(args[1], '/')) != NULL)
1636 *slash = 0;
1637
Christopher Faulet26028f62017-11-22 15:01:51 +01001638 if (parse_process_number(args[1], &proc, &autoinc, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001639 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +01001640 err_code |= ERR_ALERT | ERR_FATAL;
1641 goto out;
1642 }
1643
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001644 if (slash) {
1645 if (parse_process_number(slash+1, &thread, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001646 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001647 err_code |= ERR_ALERT | ERR_FATAL;
1648 goto out;
1649 }
1650 *slash = '/';
1651
1652 if (autoinc && my_popcountl(proc) != 1 && my_popcountl(thread) != 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001653 ha_alert("parsing [%s:%d] : %s : '%s' : unable to automatically bind "
1654 "a process range _AND_ a thread range\n",
1655 file, linenum, args[0], args[1]);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001656 err_code |= ERR_ALERT | ERR_FATAL;
1657 goto out;
1658 }
1659 }
1660
Christopher Faulet62519022017-10-16 15:49:32 +02001661 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001662 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Christopher Faulet62519022017-10-16 15:49:32 +02001663 err_code |= ERR_ALERT | ERR_FATAL;
1664 goto out;
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001665 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001666
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001667 if (autoinc &&
1668 my_popcountl(proc) != my_popcountl(cpus) &&
1669 my_popcountl(thread) != my_popcountl(cpus)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001670 ha_alert("parsing [%s:%d] : %s : PROC/THREAD range and CPU sets "
1671 "must have the same size to be automatically bound\n",
1672 file, linenum, args[0]);
Christopher Faulet26028f62017-11-22 15:01:51 +01001673 err_code |= ERR_ALERT | ERR_FATAL;
1674 goto out;
1675 }
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001676
Christopher Faulet26028f62017-11-22 15:01:51 +01001677 for (i = n = 0; i < LONGBITS; i++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001678 /* No mapping for this process */
1679 if (!(proc & (1UL << i)))
1680 continue;
1681
1682 /* Mapping at the process level */
1683 if (!thread) {
1684 if (!autoinc)
1685 global.cpu_map.proc[i] = cpus;
1686 else {
1687 n += my_ffsl(cpus >> n);
1688 global.cpu_map.proc[i] = (1UL << (n-1));
1689 }
1690 continue;
1691 }
1692
1693 /* Mapping at the thread level */
Willy Tarreau421f02e2018-01-20 18:19:22 +01001694 for (j = 0; j < MAX_THREADS; j++) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001695 /* Np mapping for this thread */
1696 if (!(thread & (1UL << j)))
1697 continue;
1698
1699 if (!autoinc)
1700 global.cpu_map.thread[i][j] = cpus;
1701 else {
Christopher Faulet26028f62017-11-22 15:01:51 +01001702 n += my_ffsl(cpus >> n);
Christopher Fauletcb6a9452017-11-22 16:50:41 +01001703 global.cpu_map.thread[i][j] = (1UL << (n-1));
Christopher Faulet26028f62017-11-22 15:01:51 +01001704 }
Christopher Faulet26028f62017-11-22 15:01:51 +01001705 }
1706 }
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001707#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01001708 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1709 file, linenum, args[0]);
Willy Tarreaufc6c0322012-11-16 16:12:27 +01001710 err_code |= ERR_ALERT | ERR_FATAL;
1711 goto out;
Christopher Faulet62519022017-10-16 15:49:32 +02001712#endif /* ! USE_CPU_AFFINITY */
1713 }
Willy Tarreau1d549722016-02-16 12:41:57 +01001714 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1715 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1716 goto out;
1717
1718 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001719 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001720 err_code |= ERR_ALERT | ERR_FATAL;
1721 goto out;
1722 }
1723
1724 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1725 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001726 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 +01001727 err_code |= ERR_ALERT | ERR_FATAL;
1728 goto out;
1729 }
1730 }
1731 else if (!strcmp(args[0], "unsetenv")) {
1732 int arg;
1733
1734 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001735 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
Willy Tarreau1d549722016-02-16 12:41:57 +01001736 err_code |= ERR_ALERT | ERR_FATAL;
1737 goto out;
1738 }
1739
1740 for (arg = 1; *args[arg]; arg++) {
1741 if (unsetenv(args[arg]) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001742 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 +01001743 err_code |= ERR_ALERT | ERR_FATAL;
1744 goto out;
1745 }
1746 }
1747 }
1748 else if (!strcmp(args[0], "resetenv")) {
1749 extern char **environ;
1750 char **env = environ;
1751
1752 /* args contain variable names to keep, one per argument */
1753 while (*env) {
1754 int arg;
1755
1756 /* look for current variable in among all those we want to keep */
1757 for (arg = 1; *args[arg]; arg++) {
1758 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1759 (*env)[strlen(args[arg])] == '=')
1760 break;
1761 }
1762
1763 /* delete this variable */
1764 if (!*args[arg]) {
1765 char *delim = strchr(*env, '=');
1766
1767 if (!delim || delim - *env >= trash.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001768 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 +01001769 err_code |= ERR_ALERT | ERR_FATAL;
1770 goto out;
1771 }
1772
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001773 memcpy(trash.area, *env, delim - *env);
1774 trash.area[delim - *env] = 0;
Willy Tarreau1d549722016-02-16 12:41:57 +01001775
Willy Tarreau843b7cb2018-07-13 10:54:26 +02001776 if (unsetenv(trash.area) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001777 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 +01001778 err_code |= ERR_ALERT | ERR_FATAL;
1779 goto out;
1780 }
1781 }
1782 else
1783 env++;
1784 }
1785 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001786 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001787 struct cfg_kw_list *kwl;
1788 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001789 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001790
1791 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1792 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1793 if (kwl->kw[index].section != CFG_GLOBAL)
1794 continue;
1795 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Willy Tarreau28a47d62012-09-18 20:02:48 +02001796 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02001797 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001798 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001799 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001800 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02001801 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001802 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001803 err_code |= ERR_WARN;
1804 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02001805 }
Willy Tarreau058e9072009-07-20 09:30:05 +02001806 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02001807 }
1808 }
1809 }
1810
Christopher Faulet767a84b2017-11-24 16:50:31 +01001811 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +02001812 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001813 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001814
Willy Tarreau058e9072009-07-20 09:30:05 +02001815 out:
Willy Tarreau0a3dd742012-05-08 19:47:01 +02001816 free(errmsg);
Willy Tarreau058e9072009-07-20 09:30:05 +02001817 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001818}
1819
Willy Tarreau915e1eb2009-06-22 15:48:36 +02001820void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +02001821{
Willy Tarreau97cb7802010-01-03 20:23:58 +01001822 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001823 defproxy.mode = PR_MODE_TCP;
1824 defproxy.state = PR_STNEW;
1825 defproxy.maxconn = cfg_maxpconn;
1826 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -07001827 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001828 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001829
Simon Horman66183002013-02-23 10:16:43 +09001830 defproxy.defsrv.check.inter = DEF_CHKINTR;
1831 defproxy.defsrv.check.fastinter = 0;
1832 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001833 defproxy.defsrv.agent.inter = DEF_CHKINTR;
1834 defproxy.defsrv.agent.fastinter = 0;
1835 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +09001836 defproxy.defsrv.check.rise = DEF_RISETIME;
1837 defproxy.defsrv.check.fall = DEF_FALLTIME;
1838 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
1839 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +02001840 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +09001841 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001842 defproxy.defsrv.maxqueue = 0;
1843 defproxy.defsrv.minconn = 0;
1844 defproxy.defsrv.maxconn = 0;
1845 defproxy.defsrv.slowstart = 0;
1846 defproxy.defsrv.onerror = DEF_HANA_ONERR;
1847 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
1848 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +09001849
1850 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001851 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001852}
1853
Willy Tarreauade5ec42010-01-28 19:33:49 +01001854
Willy Tarreau63af98d2014-05-18 08:11:41 +02001855/* This function createss a new req* or rsp* rule to the proxy. It compiles the
1856 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
1857 * ERR_FATAL in case of error.
1858 */
Willy Tarreauade5ec42010-01-28 19:33:49 +01001859static int create_cond_regex_rule(const char *file, int line,
1860 struct proxy *px, int dir, int action, int flags,
1861 const char *cmd, const char *reg, const char *repl,
1862 const char **cond_start)
1863{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001864 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +02001865 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001866 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001867 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +02001868 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +01001869 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001870 int cs;
1871 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001872
1873 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001874 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001875 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001876 goto err;
1877 }
1878
1879 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001880 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001881 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001882 goto err;
1883 }
1884
Christopher Faulet898566e2016-10-26 11:06:28 +02001885 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001886 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001887
Willy Tarreau5321c422010-01-28 20:35:13 +01001888 if (cond_start &&
1889 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02001890 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001891 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
1892 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001893 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001894 goto err;
1895 }
1896 }
1897 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001898 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
1899 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001900 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +01001901 goto err;
1902 }
1903
Willy Tarreau63af98d2014-05-18 08:11:41 +02001904 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +01001905 (dir == SMP_OPT_DIR_REQ) ?
1906 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
1907 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
1908 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +01001909
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001910 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +01001911 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001912 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001913 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001914 goto err;
1915 }
1916
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001917 cs = !(flags & REG_ICASE);
1918 cap = !(flags & REG_NOSUB);
1919 error = NULL;
1920 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001921 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001922 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001923 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001924 goto err;
1925 }
1926
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001927 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +01001928 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001929 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001930 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
1931 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001932 ret_code |= ERR_ALERT | ERR_FATAL;
1933 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001934 }
1935
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02001936 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +02001937 ret_code |= ERR_WARN;
1938
1939 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001940
Willy Tarreau63af98d2014-05-18 08:11:41 +02001941 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001942 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +01001943 err:
1944 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +02001945 free(errmsg);
1946 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +01001947}
1948
Willy Tarreaubaaee002006-06-26 02:48:02 +02001949/*
William Lallemand51097192015-04-14 16:35:22 +02001950 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +02001951 * Returns the error code, 0 if OK, or any combination of :
1952 * - ERR_ABORT: must abort ASAP
1953 * - ERR_FATAL: we can continue parsing but not start the service
1954 * - ERR_WARN: a warning has been emitted
1955 * - ERR_ALERT: an alert has been emitted
1956 * Only the two first ones can stop processing, the two others are just
1957 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02001958 */
Emeric Brun32da3c42010-09-23 18:39:19 +02001959int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
1960{
1961 static struct peers *curpeers = NULL;
1962 struct peer *newpeer = NULL;
1963 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001964 struct bind_conf *bind_conf;
1965 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +02001966 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +01001967 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001968
1969 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001970 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001971 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +01001972 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001973 goto out;
1974 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001975
William Lallemand6e62fb62015-04-28 16:55:23 +02001976 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1977 goto out;
1978
Emeric Brun32da3c42010-09-23 18:39:19 +02001979 err = invalid_char(args[1]);
1980 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001981 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1982 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +01001983 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +01001984 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02001985 }
1986
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02001987 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02001988 /*
1989 * If there are two proxies with the same name only following
1990 * combinations are allowed:
1991 */
1992 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001993 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
1994 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02001995 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +02001996 }
1997 }
1998
Vincent Bernat02779b62016-04-03 13:48:43 +02001999 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002000 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002001 err_code |= ERR_ALERT | ERR_ABORT;
2002 goto out;
2003 }
2004
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002005 curpeers->next = cfg_peers;
2006 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002007 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002008 curpeers->conf.line = linenum;
2009 curpeers->last_change = now.tv_sec;
2010 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002011 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +02002012 }
2013 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +01002014 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +01002015 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002016 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +02002017
2018 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002019 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2020 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002021 err_code |= ERR_ALERT | ERR_FATAL;
2022 goto out;
2023 }
2024
2025 err = invalid_char(args[1]);
2026 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002027 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2028 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002029 err_code |= ERR_ALERT | ERR_FATAL;
2030 goto out;
2031 }
2032
Vincent Bernat02779b62016-04-03 13:48:43 +02002033 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002034 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002035 err_code |= ERR_ALERT | ERR_ABORT;
2036 goto out;
2037 }
2038
2039 /* the peers are linked backwards first */
2040 curpeers->count++;
2041 newpeer->next = curpeers->remote;
2042 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +02002043 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +02002044 newpeer->conf.line = linenum;
2045
2046 newpeer->last_change = now.tv_sec;
2047 newpeer->id = strdup(args[1]);
2048
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002049 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002050 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002051 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +01002052 err_code |= ERR_ALERT | ERR_FATAL;
2053 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +02002054 }
Willy Tarreaub36487e2013-03-10 18:37:42 +01002055
2056 proto = protocol_by_family(sk->ss_family);
2057 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002058 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
2059 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +01002060 err_code |= ERR_ALERT | ERR_FATAL;
2061 goto out;
2062 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002063
2064 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002065 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2066 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002067 err_code |= ERR_ALERT | ERR_FATAL;
2068 goto out;
2069 }
2070
Willy Tarreau2aa38802013-02-20 19:20:59 +01002071 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002072 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2073 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002074 err_code |= ERR_ALERT | ERR_FATAL;
2075 goto out;
2076 }
Willy Tarreau2aa38802013-02-20 19:20:59 +01002077
Emeric Brun32da3c42010-09-23 18:39:19 +02002078 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +01002079 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002080 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +02002081 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002082 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +02002083
Emeric Brun32da3c42010-09-23 18:39:19 +02002084 if (strcmp(newpeer->id, localpeer) == 0) {
2085 /* Current is local peer, it define a frontend */
2086 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02002087 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +02002088
2089 if (!curpeers->peers_fe) {
2090 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002091 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +02002092 err_code |= ERR_ALERT | ERR_ABORT;
2093 goto out;
2094 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002095
Willy Tarreau237250c2011-07-29 01:49:03 +02002096 init_new_proxy(curpeers->peers_fe);
2097 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02002098 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002099 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
2100 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +01002101 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002102
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002103 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +02002104
Willy Tarreau902636f2013-03-10 19:44:48 +01002105 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
2106 if (errmsg && *errmsg) {
2107 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002108 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002109 }
2110 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002111 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
2112 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +02002113 err_code |= ERR_FATAL;
2114 goto out;
2115 }
Willy Tarreau4348fad2012-09-20 16:48:07 +02002116
2117 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +01002118 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002119 l->maxconn = curpeers->peers_fe->maxconn;
2120 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +02002121 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002122 l->analysers |= curpeers->peers_fe->fe_req_ana;
2123 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02002124 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
2125 global.maxsock += l->maxconn;
2126 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002127 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002128 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002129 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
2130 file, linenum, args[0], args[1],
2131 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01002132 err_code |= ERR_FATAL;
2133 goto out;
2134 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002135 }
2136 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02002137 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
2138 curpeers->state = PR_STSTOPPED;
2139 }
2140 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
2141 curpeers->state = PR_STNEW;
2142 }
Emeric Brun32da3c42010-09-23 18:39:19 +02002143 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002144 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02002145 err_code |= ERR_ALERT | ERR_FATAL;
2146 goto out;
2147 }
2148
2149out:
Willy Tarreau902636f2013-03-10 19:44:48 +01002150 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02002151 return err_code;
2152}
2153
Baptiste Assmann325137d2015-04-13 23:40:55 +02002154/*
2155 * Parse a <resolvers> section.
2156 * Returns the error code, 0 if OK, or any combination of :
2157 * - ERR_ABORT: must abort ASAP
2158 * - ERR_FATAL: we can continue parsing but not start the service
2159 * - ERR_WARN: a warning has been emitted
2160 * - ERR_ALERT: an alert has been emitted
2161 * Only the two first ones can stop processing, the two others are just
2162 * indicators.
2163 */
2164int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
2165{
2166 static struct dns_resolvers *curr_resolvers = NULL;
2167 struct dns_nameserver *newnameserver = NULL;
2168 const char *err;
2169 int err_code = 0;
2170 char *errmsg = NULL;
2171
2172 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
2173 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002174 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002175 err_code |= ERR_ALERT | ERR_ABORT;
2176 goto out;
2177 }
2178
2179 err = invalid_char(args[1]);
2180 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002181 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2182 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002183 err_code |= ERR_ALERT | ERR_ABORT;
2184 goto out;
2185 }
2186
2187 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
2188 /* Error if two resolvers owns the same name */
2189 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002190 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
2191 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002192 err_code |= ERR_ALERT | ERR_ABORT;
2193 }
2194 }
2195
Vincent Bernat02779b62016-04-03 13:48:43 +02002196 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002197 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002198 err_code |= ERR_ALERT | ERR_ABORT;
2199 goto out;
2200 }
2201
2202 /* default values */
2203 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
2204 curr_resolvers->conf.file = strdup(file);
2205 curr_resolvers->conf.line = linenum;
2206 curr_resolvers->id = strdup(args[1]);
2207 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002208 /* default maximum response size */
2209 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002210 /* default hold period for nx, other, refuse and timeout is 30s */
2211 curr_resolvers->hold.nx = 30000;
2212 curr_resolvers->hold.other = 30000;
2213 curr_resolvers->hold.refused = 30000;
2214 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02002215 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002216 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02002217 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002218 curr_resolvers->timeout.resolve = 1000;
2219 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002220 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002221 curr_resolvers->nb_nameservers = 0;
2222 LIST_INIT(&curr_resolvers->nameservers);
2223 LIST_INIT(&curr_resolvers->resolutions.curr);
2224 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01002225 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002226 }
2227 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
2228 struct sockaddr_storage *sk;
2229 int port1, port2;
2230 struct protocol *proto;
2231
2232 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002233 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2234 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002235 err_code |= ERR_ALERT | ERR_FATAL;
2236 goto out;
2237 }
2238
2239 err = invalid_char(args[1]);
2240 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002241 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2242 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002243 err_code |= ERR_ALERT | ERR_FATAL;
2244 goto out;
2245 }
2246
Christopher Faulet67957bd2017-09-27 11:00:59 +02002247 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01002248 /* Error if two resolvers owns the same name */
2249 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002250 ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
Ben Draut44e609b2018-05-29 15:40:08 -06002251 file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01002252 err_code |= ERR_ALERT | ERR_FATAL;
2253 }
2254 }
2255
Vincent Bernat02779b62016-04-03 13:48:43 +02002256 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002257 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002258 err_code |= ERR_ALERT | ERR_ABORT;
2259 goto out;
2260 }
2261
2262 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02002263 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002264 newnameserver->resolvers = curr_resolvers;
2265 newnameserver->conf.file = strdup(file);
2266 newnameserver->conf.line = linenum;
2267 newnameserver->id = strdup(args[1]);
2268
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002269 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002270 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002271 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002272 err_code |= ERR_ALERT | ERR_FATAL;
2273 goto out;
2274 }
2275
2276 proto = protocol_by_family(sk->ss_family);
2277 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002278 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02002279 file, linenum, args[0], args[1]);
2280 err_code |= ERR_ALERT | ERR_FATAL;
2281 goto out;
2282 }
2283
2284 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002285 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2286 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002287 err_code |= ERR_ALERT | ERR_FATAL;
2288 goto out;
2289 }
2290
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002291 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002292 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
2293 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01002294 err_code |= ERR_ALERT | ERR_FATAL;
2295 goto out;
2296 }
2297
Baptiste Assmann325137d2015-04-13 23:40:55 +02002298 newnameserver->addr = *sk;
2299 }
Ben Draut44e609b2018-05-29 15:40:08 -06002300 else if (strcmp(args[0], "parse-resolv-conf") == 0) {
2301 const char *whitespace = "\r\n\t ";
2302 char *resolv_line = NULL;
2303 int resolv_linenum = 0;
2304 FILE *f = NULL;
2305 char *address = NULL;
2306 struct sockaddr_storage *sk = NULL;
2307 struct protocol *proto;
2308 int duplicate_name = 0;
2309
2310 if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
2311 ha_alert("parsing [%s:%d] : out of memory.\n",
2312 file, linenum);
2313 err_code |= ERR_ALERT | ERR_FATAL;
2314 goto resolv_out;
2315 }
2316
2317 if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
2318 ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n",
2319 file, linenum);
2320 err_code |= ERR_ALERT | ERR_FATAL;
2321 goto resolv_out;
2322 }
2323
2324 sk = calloc(1, sizeof(*sk));
2325 if (sk == NULL) {
2326 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n",
2327 resolv_linenum);
2328 err_code |= ERR_ALERT | ERR_FATAL;
2329 goto resolv_out;
2330 }
2331
2332 while (fgets(resolv_line, LINESIZE, f) != NULL) {
2333 resolv_linenum++;
2334 if (strncmp(resolv_line, "nameserver", 10) != 0)
2335 continue;
2336
2337 address = strtok(resolv_line + 10, whitespace);
2338 if (address == resolv_line + 10)
2339 continue;
2340
2341 if (address == NULL) {
2342 ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
2343 resolv_linenum);
2344 err_code |= ERR_WARN;
2345 continue;
2346 }
2347
2348 duplicate_name = 0;
2349 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
2350 if (strcmp(newnameserver->id, address) == 0) {
2351 ha_warning("Parsing [/etc/resolv.conf:%d] : generated name for /etc/resolv.conf nameserver '%s' conflicts with another nameserver (declared at %s:%d), it appears to be a duplicate and will be excluded.\n",
2352 resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line);
2353 err_code |= ERR_WARN;
2354 duplicate_name = 1;
2355 }
2356 }
2357
2358 if (duplicate_name)
2359 continue;
2360
2361 memset(sk, 0, sizeof(*sk));
2362 sk = str2ip2(address, sk, 1);
2363 if (!sk) {
2364 ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, namerserver will be excluded.\n",
2365 resolv_linenum, address);
2366 err_code |= ERR_WARN;
2367 continue;
2368 }
2369
2370 set_host_port(sk, 53);
2371
2372 proto = protocol_by_family(sk->ss_family);
2373 if (!proto || !proto->connect) {
2374 ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
2375 resolv_linenum, address);
2376 err_code |= ERR_WARN;
2377 continue;
2378 }
2379
2380 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
2381 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2382 err_code |= ERR_ALERT | ERR_FATAL;
2383 goto resolv_out;
2384 }
2385
2386 newnameserver->conf.file = strdup("/etc/resolv.conf");
2387 if (newnameserver->conf.file == NULL) {
2388 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2389 err_code |= ERR_ALERT | ERR_FATAL;
2390 goto resolv_out;
2391 }
2392
2393 newnameserver->id = strdup(address);
2394 if (newnameserver->id == NULL) {
2395 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
2396 err_code |= ERR_ALERT | ERR_FATAL;
2397 goto resolv_out;
2398 }
2399
2400 newnameserver->resolvers = curr_resolvers;
2401 newnameserver->conf.line = resolv_linenum;
2402 newnameserver->addr = *sk;
2403
2404 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
2405 }
2406
2407resolv_out:
2408 free(sk);
2409 free(resolv_line);
2410 if (f != NULL)
2411 fclose(f);
2412 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002413 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
2414 const char *res;
2415 unsigned int time;
2416
2417 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002418 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
2419 file, linenum, args[0]);
2420 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02002421 err_code |= ERR_ALERT | ERR_FATAL;
2422 goto out;
2423 }
2424 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
2425 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002426 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2427 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002428 err_code |= ERR_ALERT | ERR_FATAL;
2429 goto out;
2430 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01002431 if (strcmp(args[1], "nx") == 0)
2432 curr_resolvers->hold.nx = time;
2433 else if (strcmp(args[1], "other") == 0)
2434 curr_resolvers->hold.other = time;
2435 else if (strcmp(args[1], "refused") == 0)
2436 curr_resolvers->hold.refused = time;
2437 else if (strcmp(args[1], "timeout") == 0)
2438 curr_resolvers->hold.timeout = time;
2439 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02002440 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02002441 else if (strcmp(args[1], "obsolete") == 0)
2442 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02002443 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002444 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
2445 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002446 err_code |= ERR_ALERT | ERR_FATAL;
2447 goto out;
2448 }
2449
2450 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002451 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002452 int i = 0;
2453
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002454 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002455 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2456 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002457 err_code |= ERR_ALERT | ERR_FATAL;
2458 goto out;
2459 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002460
2461 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02002462 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002463 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
2464 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02002465 err_code |= ERR_ALERT | ERR_FATAL;
2466 goto out;
2467 }
2468
2469 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02002470 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002471 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002472 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
2473 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02002474 err_code |= ERR_WARN;
2475 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02002476 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002477 else if (strcmp(args[0], "resolve_retries") == 0) {
2478 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002479 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
2480 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002481 err_code |= ERR_ALERT | ERR_FATAL;
2482 goto out;
2483 }
2484 curr_resolvers->resolve_retries = atoi(args[1]);
2485 }
2486 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002487 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002488 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
2489 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002490 err_code |= ERR_ALERT | ERR_FATAL;
2491 goto out;
2492 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002493 else if (strcmp(args[1], "retry") == 0 ||
2494 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002495 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02002496 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002497
2498 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002499 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2500 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002501 err_code |= ERR_ALERT | ERR_FATAL;
2502 goto out;
2503 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002504 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002505 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002506 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
2507 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002508 err_code |= ERR_ALERT | ERR_FATAL;
2509 goto out;
2510 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02002511 if (args[1][2] == 't')
2512 curr_resolvers->timeout.retry = tout;
2513 else
2514 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01002515 }
2516 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002517 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
2518 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002519 err_code |= ERR_ALERT | ERR_FATAL;
2520 goto out;
2521 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02002522 } /* neither "nameserver" nor "resolvers" */
2523 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002524 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02002525 err_code |= ERR_ALERT | ERR_FATAL;
2526 goto out;
2527 }
2528
2529 out:
2530 free(errmsg);
2531 return err_code;
2532}
Simon Horman0d16a402015-01-30 11:22:58 +09002533
2534/*
William Lallemand51097192015-04-14 16:35:22 +02002535 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09002536 * Returns the error code, 0 if OK, or any combination of :
2537 * - ERR_ABORT: must abort ASAP
2538 * - ERR_FATAL: we can continue parsing but not start the service
2539 * - ERR_WARN: a warning has been emitted
2540 * - ERR_ALERT: an alert has been emitted
2541 * Only the two first ones can stop processing, the two others are just
2542 * indicators.
2543 */
2544int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
2545{
2546 static struct mailers *curmailers = NULL;
2547 struct mailer *newmailer = NULL;
2548 const char *err;
2549 int err_code = 0;
2550 char *errmsg = NULL;
2551
2552 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
2553 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002554 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002555 err_code |= ERR_ALERT | ERR_ABORT;
2556 goto out;
2557 }
2558
2559 err = invalid_char(args[1]);
2560 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002561 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2562 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002563 err_code |= ERR_ALERT | ERR_ABORT;
2564 goto out;
2565 }
2566
2567 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
2568 /*
2569 * If there are two proxies with the same name only following
2570 * combinations are allowed:
2571 */
2572 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002573 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
2574 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002575 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09002576 }
2577 }
2578
Vincent Bernat02779b62016-04-03 13:48:43 +02002579 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002580 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002581 err_code |= ERR_ALERT | ERR_ABORT;
2582 goto out;
2583 }
2584
2585 curmailers->next = mailers;
2586 mailers = curmailers;
2587 curmailers->conf.file = strdup(file);
2588 curmailers->conf.line = linenum;
2589 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002590 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
2591 * But need enough time so that timeouts don't occur
2592 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09002593 }
2594 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
2595 struct sockaddr_storage *sk;
2596 int port1, port2;
2597 struct protocol *proto;
2598
2599 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002600 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2601 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09002602 err_code |= ERR_ALERT | ERR_FATAL;
2603 goto out;
2604 }
2605
2606 err = invalid_char(args[1]);
2607 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002608 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2609 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002610 err_code |= ERR_ALERT | ERR_FATAL;
2611 goto out;
2612 }
2613
Vincent Bernat02779b62016-04-03 13:48:43 +02002614 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002615 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09002616 err_code |= ERR_ALERT | ERR_ABORT;
2617 goto out;
2618 }
2619
2620 /* the mailers are linked backwards first */
2621 curmailers->count++;
2622 newmailer->next = curmailers->mailer_list;
2623 curmailers->mailer_list = newmailer;
2624 newmailer->mailers = curmailers;
2625 newmailer->conf.file = strdup(file);
2626 newmailer->conf.line = linenum;
2627
2628 newmailer->id = strdup(args[1]);
2629
Willy Tarreau48ef4c92017-01-06 18:32:38 +01002630 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09002631 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002632 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09002633 err_code |= ERR_ALERT | ERR_FATAL;
2634 goto out;
2635 }
2636
2637 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09002638 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002639 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
2640 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09002641 err_code |= ERR_ALERT | ERR_FATAL;
2642 goto out;
2643 }
2644
2645 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002646 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
2647 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002648 err_code |= ERR_ALERT | ERR_FATAL;
2649 goto out;
2650 }
2651
2652 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002653 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
2654 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09002655 err_code |= ERR_ALERT | ERR_FATAL;
2656 goto out;
2657 }
2658
2659 newmailer->addr = *sk;
2660 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01002661 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09002662 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002663 }
2664 else if (strcmp(args[0], "timeout") == 0) {
2665 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002666 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
2667 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002668 err_code |= ERR_ALERT | ERR_FATAL;
2669 goto out;
2670 }
2671 else if (strcmp(args[1], "mail") == 0) {
2672 const char *res;
2673 unsigned int timeout_mail;
2674 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002675 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
2676 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002677 err_code |= ERR_ALERT | ERR_FATAL;
2678 goto out;
2679 }
2680 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
2681 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002682 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2683 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002684 err_code |= ERR_ALERT | ERR_FATAL;
2685 goto out;
2686 }
2687 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002688 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 +01002689 err_code |= ERR_ALERT | ERR_FATAL;
2690 goto out;
2691 }
2692 curmailers->timeout.mail = timeout_mail;
2693 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002694 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01002695 file, linenum, args[0], args[1]);
2696 err_code |= ERR_ALERT | ERR_FATAL;
2697 goto out;
2698 }
2699 }
Simon Horman0d16a402015-01-30 11:22:58 +09002700 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002701 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09002702 err_code |= ERR_ALERT | ERR_FATAL;
2703 goto out;
2704 }
2705
2706out:
2707 free(errmsg);
2708 return err_code;
2709}
2710
Simon Horman9dc49962015-01-30 11:22:59 +09002711static void free_email_alert(struct proxy *p)
2712{
2713 free(p->email_alert.mailers.name);
2714 p->email_alert.mailers.name = NULL;
2715 free(p->email_alert.from);
2716 p->email_alert.from = NULL;
2717 free(p->email_alert.to);
2718 p->email_alert.to = NULL;
2719 free(p->email_alert.myhostname);
2720 p->email_alert.myhostname = NULL;
2721}
2722
Willy Tarreau3842f002009-06-14 11:39:52 +02002723int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02002724{
2725 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02002726 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002727 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002728 int rc;
2729 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02002730 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01002731 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01002732 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02002733 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002734 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002735
Willy Tarreau977b8e42006-12-29 14:19:17 +01002736 if (!strcmp(args[0], "listen"))
2737 rc = PR_CAP_LISTEN;
2738 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002739 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02002740 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02002741 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002742 else
2743 rc = PR_CAP_NONE;
2744
2745 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002746 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002747 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
2748 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
2749 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002750 err_code |= ERR_ALERT | ERR_ABORT;
2751 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002752 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002753
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002754 err = invalid_char(args[1]);
2755 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002756 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
2757 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002758 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002759 }
2760
Willy Tarreau8f50b682015-05-26 11:45:02 +02002761 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
2762 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002763 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
2764 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
2765 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02002766 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02002767 }
2768
Vincent Bernat02779b62016-04-03 13:48:43 +02002769 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002770 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002771 err_code |= ERR_ALERT | ERR_ABORT;
2772 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002773 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01002774
Willy Tarreau97cb7802010-01-03 20:23:58 +01002775 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01002776 curproxy->next = proxies_list;
2777 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02002778 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
2779 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002780 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002781 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002782 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01002783 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002784
William Lallemand6e62fb62015-04-28 16:55:23 +02002785 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
2786 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01002787 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02002788 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002789 }
2790
2791 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002792 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02002793 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01002794
Willy Tarreaubaaee002006-06-26 02:48:02 +02002795 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002796 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002797 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002798 curproxy->no_options = defproxy.no_options;
2799 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002800 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002801 curproxy->except_net = defproxy.except_net;
2802 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02002803 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02002804 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002805
Willy Tarreau79f5fe82008-08-23 08:18:21 +02002806 if (defproxy.fwdfor_hdr_len) {
2807 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
2808 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
2809 }
2810
Willy Tarreaub86db342009-11-30 11:50:16 +01002811 if (defproxy.orgto_hdr_len) {
2812 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
2813 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
2814 }
2815
Mark Lamourinec2247f02012-01-04 13:02:01 -05002816 if (defproxy.server_id_hdr_len) {
2817 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
2818 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
2819 }
2820
Willy Tarreau977b8e42006-12-29 14:19:17 +01002821 if (curproxy->cap & PR_CAP_FE) {
2822 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002823 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02002824 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002825
2826 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02002827 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
2828 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01002829
2830 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
2831 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002832
Willy Tarreau977b8e42006-12-29 14:19:17 +01002833 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01002834 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04002835 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002836 curproxy->fullconn = defproxy.fullconn;
2837 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07002838 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02002839 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002840
Willy Tarreauaa2f3892010-10-22 16:15:31 +02002841 if (defproxy.check_req) {
2842 curproxy->check_req = calloc(1, defproxy.check_len);
2843 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
2844 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002845 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002846
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002847 if (defproxy.expect_str) {
2848 curproxy->expect_str = strdup(defproxy.expect_str);
2849 if (defproxy.expect_regex) {
2850 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02002851 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
2852 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02002853 }
2854 }
2855
Willy Tarreau67402132012-05-31 20:40:20 +02002856 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002857 if (defproxy.cookie_name)
2858 curproxy->cookie_name = strdup(defproxy.cookie_name);
2859 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01002860
2861 if (defproxy.dyncookie_key)
2862 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002863 if (defproxy.cookie_domain)
2864 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01002865
Willy Tarreau31936852010-10-06 16:59:56 +02002866 if (defproxy.cookie_maxidle)
2867 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
2868
2869 if (defproxy.cookie_maxlife)
2870 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
2871
Emeric Brun647caf12009-06-30 17:57:00 +02002872 if (defproxy.rdp_cookie_name)
2873 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
2874 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
2875
Willy Tarreau01732802007-11-01 22:48:15 +01002876 if (defproxy.url_param_name)
2877 curproxy->url_param_name = strdup(defproxy.url_param_name);
2878 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002879
Benoitaffb4812009-03-25 13:02:10 +01002880 if (defproxy.hh_name)
2881 curproxy->hh_name = strdup(defproxy.hh_name);
2882 curproxy->hh_len = defproxy.hh_len;
2883 curproxy->hh_match_domain = defproxy.hh_match_domain;
2884
Willy Tarreauef9a3602012-12-08 22:29:20 +01002885 if (defproxy.conn_src.iface_name)
2886 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
2887 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08002888 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02002889#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08002890 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02002891#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002892 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002893 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002894
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002895 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002896 if (defproxy.capture_name)
2897 curproxy->capture_name = strdup(defproxy.capture_name);
2898 curproxy->capture_namelen = defproxy.capture_namelen;
2899 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01002900 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002901
Willy Tarreau977b8e42006-12-29 14:19:17 +01002902 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002903 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002904 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002905 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01002906 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002907 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002908 curproxy->mon_net = defproxy.mon_net;
2909 curproxy->mon_mask = defproxy.mon_mask;
2910 if (defproxy.monitor_uri)
2911 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
2912 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002913 if (defproxy.defbe.name)
2914 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02002915
2916 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02002917 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
2918 if (curproxy->conf.logformat_string &&
2919 curproxy->conf.logformat_string != default_http_log_format &&
2920 curproxy->conf.logformat_string != default_tcp_log_format &&
2921 curproxy->conf.logformat_string != clf_http_log_format)
2922 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
2923
2924 if (defproxy.conf.lfs_file) {
2925 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
2926 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
2927 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02002928
2929 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
2930 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
2931 if (curproxy->conf.logformat_sd_string &&
2932 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
2933 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
2934
2935 if (defproxy.conf.lfsd_file) {
2936 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
2937 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
2938 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002939 }
2940
2941 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01002942 curproxy->timeout.connect = defproxy.timeout.connect;
2943 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02002944 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002945 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01002946 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01002947 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02002948 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01002949 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02002950 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01002951 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002952 }
2953
Willy Tarreaubaaee002006-06-26 02:48:02 +02002954 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02002955 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02002956
2957 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01002958 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02002959 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01002960 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02002961 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02002962 LIST_INIT(&node->list);
2963 LIST_ADDQ(&curproxy->logsrvs, &node->list);
2964 }
2965
Willy Tarreau62a61232013-04-12 18:13:46 +02002966 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
2967 if (curproxy->conf.uniqueid_format_string)
2968 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
2969
Dragan Dosen43885c72015-10-01 13:18:13 +02002970 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01002971
Willy Tarreau62a61232013-04-12 18:13:46 +02002972 if (defproxy.conf.uif_file) {
2973 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
2974 curproxy->conf.uif_line = defproxy.conf.uif_line;
2975 }
William Lallemanda73203e2012-03-12 12:48:57 +01002976
2977 /* copy default header unique id */
2978 if (defproxy.header_unique_id)
2979 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
2980
William Lallemand82fe75c2012-10-23 10:25:10 +02002981 /* default compression options */
2982 if (defproxy.comp != NULL) {
2983 curproxy->comp = calloc(1, sizeof(struct comp));
2984 curproxy->comp->algos = defproxy.comp->algos;
2985 curproxy->comp->types = defproxy.comp->types;
2986 }
2987
Willy Tarreaubaaee002006-06-26 02:48:02 +02002988 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002989 curproxy->conf.used_listener_id = EB_ROOT;
2990 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002991
Simon Horman98637e52014-06-20 12:30:16 +09002992 if (defproxy.check_path)
2993 curproxy->check_path = strdup(defproxy.check_path);
2994 if (defproxy.check_command)
2995 curproxy->check_command = strdup(defproxy.check_command);
2996
Simon Horman9dc49962015-01-30 11:22:59 +09002997 if (defproxy.email_alert.mailers.name)
2998 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
2999 if (defproxy.email_alert.from)
3000 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
3001 if (defproxy.email_alert.to)
3002 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
3003 if (defproxy.email_alert.myhostname)
3004 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09003005 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01003006 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09003007
Willy Tarreau93893792009-07-23 13:19:11 +02003008 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003009 }
3010 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
3011 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01003012 /* FIXME-20070101: we should do this too at the end of the
3013 * config parsing to free all default values.
3014 */
William Lallemand6e62fb62015-04-28 16:55:23 +02003015 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
3016 err_code |= ERR_ABORT;
3017 goto out;
3018 }
3019
Willy Tarreaua534fea2008-08-03 12:19:50 +02003020 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09003021 free(defproxy.check_command);
3022 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003023 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02003024 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01003025 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003026 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003027 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01003028 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02003029 free(defproxy.capture_name);
3030 free(defproxy.monitor_uri);
3031 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01003032 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02003033 free(defproxy.fwdfor_hdr_name);
3034 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01003035 free(defproxy.orgto_hdr_name);
3036 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05003037 free(defproxy.server_id_hdr_name);
3038 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02003039 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003040 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02003041 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02003042 free(defproxy.expect_regex);
3043 defproxy.expect_regex = NULL;
3044 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003045
Willy Tarreau62a61232013-04-12 18:13:46 +02003046 if (defproxy.conf.logformat_string != default_http_log_format &&
3047 defproxy.conf.logformat_string != default_tcp_log_format &&
3048 defproxy.conf.logformat_string != clf_http_log_format)
3049 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02003050
Willy Tarreau62a61232013-04-12 18:13:46 +02003051 free(defproxy.conf.uniqueid_format_string);
3052 free(defproxy.conf.lfs_file);
3053 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02003054 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09003055 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02003056
Dragan Dosen0b85ece2015-09-25 19:17:44 +02003057 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
3058 free(defproxy.conf.logformat_sd_string);
3059 free(defproxy.conf.lfsd_file);
3060
Willy Tarreaua534fea2008-08-03 12:19:50 +02003061 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003062 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01003063
Willy Tarreaubaaee002006-06-26 02:48:02 +02003064 /* we cannot free uri_auth because it might already be used */
3065 init_default_instance();
3066 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003067 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
3068 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003069 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02003070 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003071 }
3072 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003073 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003074 err_code |= ERR_ALERT | ERR_FATAL;
3075 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003076 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003077
3078 /* update the current file and line being parsed */
3079 curproxy->conf.args.file = curproxy->conf.file;
3080 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003081
3082 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02003083 if (!strcmp(args[0], "server") ||
3084 !strcmp(args[0], "default-server") ||
3085 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02003086 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
3087 if (err_code & ERR_FATAL)
3088 goto out;
3089 }
3090 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003091 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003092 int cur_arg;
3093
Willy Tarreaubaaee002006-06-26 02:48:02 +02003094 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003095 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003096 err_code |= ERR_ALERT | ERR_FATAL;
3097 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003098 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003099 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003100 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003101
Willy Tarreau24709282013-03-10 21:32:12 +01003102 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003103 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
3104 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003105 err_code |= ERR_ALERT | ERR_FATAL;
3106 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003107 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003108
Willy Tarreaua261e9b2016-12-22 20:44:00 +01003109 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01003110
3111 /* use default settings for unix sockets */
3112 bind_conf->ux.uid = global.unix_bind.ux.uid;
3113 bind_conf->ux.gid = global.unix_bind.ux.gid;
3114 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02003115
3116 /* NOTE: the following line might create several listeners if there
3117 * are comma-separated IPs or port ranges. So all further processing
3118 * will have to be applied to all listeners created after last_listen.
3119 */
Willy Tarreau902636f2013-03-10 19:44:48 +01003120 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
3121 if (errmsg && *errmsg) {
3122 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003123 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02003124 }
3125 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003126 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
3127 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003128 err_code |= ERR_ALERT | ERR_FATAL;
3129 goto out;
3130 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003131
Willy Tarreau4348fad2012-09-20 16:48:07 +02003132 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
3133 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01003134 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02003135 }
3136
Willy Tarreau5e6e2042009-02-04 17:19:29 +01003137 cur_arg = 2;
3138 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02003139 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02003140 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02003141 char *err;
3142
Willy Tarreau26982662012-09-12 23:17:10 +02003143 kw = bind_find_kw(args[cur_arg]);
3144 if (kw) {
3145 char *err = NULL;
3146 int code;
3147
3148 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003149 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
3150 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003151 cur_arg += 1 + kw->skip ;
3152 err_code |= ERR_ALERT | ERR_FATAL;
3153 goto out;
3154 }
3155
Willy Tarreau4348fad2012-09-20 16:48:07 +02003156 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02003157 err_code |= code;
3158
3159 if (code) {
3160 if (err && *err) {
3161 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003162 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02003163 }
3164 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01003165 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
3166 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02003167 if (code & ERR_FATAL) {
3168 free(err);
3169 cur_arg += 1 + kw->skip;
3170 goto out;
3171 }
3172 }
3173 free(err);
3174 cur_arg += 1 + kw->skip;
3175 continue;
3176 }
3177
Willy Tarreau8638f482012-09-18 18:01:17 +02003178 err = NULL;
3179 if (!bind_dumped) {
3180 bind_dump_kws(&err);
3181 indent_msg(&err, 4);
3182 bind_dumped = 1;
3183 }
3184
Christopher Faulet767a84b2017-11-24 16:50:31 +01003185 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
3186 file, linenum, args[0], args[1], args[cur_arg],
3187 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02003188 free(err);
3189
Willy Tarreau93893792009-07-23 13:19:11 +02003190 err_code |= ERR_ALERT | ERR_FATAL;
3191 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01003192 }
Willy Tarreau93893792009-07-23 13:19:11 +02003193 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003194 }
3195 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01003196 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003197 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
3198 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003199 err_code |= ERR_ALERT | ERR_FATAL;
3200 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003201 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003202 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003203 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003204
Willy Tarreaubaaee002006-06-26 02:48:02 +02003205 /* flush useless bits */
3206 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02003207 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003208 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02003209 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003210 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003211 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003212
William Lallemanddf1425a2015-04-28 20:17:49 +02003213 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3214 goto out;
3215
Willy Tarreau1c47f852006-07-09 08:22:27 +02003216 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003217 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
3218 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003219 err_code |= ERR_ALERT | ERR_FATAL;
3220 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003221 }
3222
Willy Tarreaua534fea2008-08-03 12:19:50 +02003223 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003224 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003225 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01003226 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02003227 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
3228
Willy Tarreau93893792009-07-23 13:19:11 +02003229 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02003230 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003231 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02003232 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3233 goto out;
3234
Willy Tarreaubaaee002006-06-26 02:48:02 +02003235 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
3236 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
3237 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
3238 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003239 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003240 err_code |= ERR_ALERT | ERR_FATAL;
3241 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003242 }
3243 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003244 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003245 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003246
3247 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003248 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003249 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003250 err_code |= ERR_ALERT | ERR_FATAL;
3251 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003252 }
3253
William Lallemanddf1425a2015-04-28 20:17:49 +02003254 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3255 goto out;
3256
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003257 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003258 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
3259 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003260 err_code |= ERR_ALERT | ERR_FATAL;
3261 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003262 }
3263
3264 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003265 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02003266 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003267
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003268 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003269 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
3270 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003271 err_code |= ERR_ALERT | ERR_FATAL;
3272 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003273 }
3274
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003275 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
3276 if (node) {
3277 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003278 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
3279 file, linenum, proxy_type_str(curproxy), curproxy->id,
3280 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02003281 err_code |= ERR_ALERT | ERR_FATAL;
3282 goto out;
3283 }
3284 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01003285 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003286 else if (!strcmp(args[0], "description")) {
3287 int i, len=0;
3288 char *d;
3289
Cyril Bonté99ed3272010-01-24 23:29:44 +01003290 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003291 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01003292 file, linenum, args[0]);
3293 err_code |= ERR_ALERT | ERR_FATAL;
3294 goto out;
3295 }
3296
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003297 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003298 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
3299 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003300 return -1;
3301 }
3302
Willy Tarreau348acfe2014-04-14 15:00:39 +02003303 for (i = 1; *args[i]; i++)
3304 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003305
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003306 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003307 curproxy->desc = d;
3308
Willy Tarreau348acfe2014-04-14 15:00:39 +02003309 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
3310 for (i = 2; *args[i]; i++)
3311 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003312
3313 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003314 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02003315 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3316 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003317 curproxy->state = PR_STSTOPPED;
3318 }
3319 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02003320 if (alertif_too_many_args(0, file, linenum, args, &err_code))
3321 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003322 curproxy->state = PR_STNEW;
3323 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003324 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
3325 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01003326 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003327
3328 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003329 if (strcmp(args[cur_arg], "all") == 0) {
3330 set = 0;
3331 break;
3332 }
Christopher Faulet26028f62017-11-22 15:01:51 +01003333 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003334 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01003335 err_code |= ERR_ALERT | ERR_FATAL;
3336 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01003337 }
3338 cur_arg++;
3339 }
3340 curproxy->bind_proc = set;
3341 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003342 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02003343 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003344 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003345 err_code |= ERR_ALERT | ERR_FATAL;
3346 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003347 }
3348
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003349 err = invalid_char(args[1]);
3350 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003351 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
3352 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003353 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02003354 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01003355 }
3356
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01003357 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003358 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
3359 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003360 err_code |= ERR_ALERT | ERR_FATAL;
3361 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003362 }
Olivier Houchard4e694042017-03-14 20:01:29 +01003363 }
3364 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
3365
3366 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3367 err_code |= ERR_WARN;
3368
3369 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003370 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
3371 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01003372 err_code |= ERR_ALERT | ERR_FATAL;
3373 goto out;
3374 }
3375 free(curproxy->dyncookie_key);
3376 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02003377 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003378 else if (!strcmp(args[0], "cookie")) { /* cookie name */
3379 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003380
Willy Tarreau977b8e42006-12-29 14:19:17 +01003381 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003382 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003383
Willy Tarreaubaaee002006-06-26 02:48:02 +02003384 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003385 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
3386 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003387 err_code |= ERR_ALERT | ERR_FATAL;
3388 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003389 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003390
Willy Tarreau67402132012-05-31 20:40:20 +02003391 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003392 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01003393 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003394 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003395 curproxy->cookie_name = strdup(args[1]);
3396 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02003397
Willy Tarreaubaaee002006-06-26 02:48:02 +02003398 cur_arg = 2;
3399 while (*(args[cur_arg])) {
3400 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003401 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003402 }
3403 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003404 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003405 }
3406 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003407 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003408 }
3409 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003410 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003411 }
3412 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003413 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003414 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003415 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003416 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003417 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003418 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02003419 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003420 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02003421 else if (!strcmp(args[cur_arg], "httponly")) {
3422 curproxy->ck_opts |= PR_CK_HTTPONLY;
3423 }
3424 else if (!strcmp(args[cur_arg], "secure")) {
3425 curproxy->ck_opts |= PR_CK_SECURE;
3426 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003427 else if (!strcmp(args[cur_arg], "domain")) {
3428 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003429 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
3430 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02003431 err_code |= ERR_ALERT | ERR_FATAL;
3432 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003433 }
3434
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003435 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003436 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003437 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
3438 " dots nor does not start with a dot."
3439 " RFC forbids it, this configuration may not work properly.\n",
3440 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01003441 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003442 }
3443
3444 err = invalid_domainchar(args[cur_arg + 1]);
3445 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003446 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
3447 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003448 err_code |= ERR_ALERT | ERR_FATAL;
3449 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003450 }
3451
Willy Tarreau68a897b2009-12-03 23:28:34 +01003452 if (!curproxy->cookie_domain) {
3453 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
3454 } else {
3455 /* one domain was already specified, add another one by
3456 * building the string which will be returned along with
3457 * the cookie.
3458 */
3459 char *new_ptr;
3460 int new_len = strlen(curproxy->cookie_domain) +
3461 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
3462 new_ptr = malloc(new_len);
3463 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
3464 free(curproxy->cookie_domain);
3465 curproxy->cookie_domain = new_ptr;
3466 }
Willy Tarreau31936852010-10-06 16:59:56 +02003467 cur_arg++;
3468 }
3469 else if (!strcmp(args[cur_arg], "maxidle")) {
3470 unsigned int maxidle;
3471 const char *res;
3472
3473 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003474 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
3475 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003476 err_code |= ERR_ALERT | ERR_FATAL;
3477 goto out;
3478 }
3479
3480 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
3481 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003482 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3483 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003484 err_code |= ERR_ALERT | ERR_FATAL;
3485 goto out;
3486 }
3487 curproxy->cookie_maxidle = maxidle;
3488 cur_arg++;
3489 }
3490 else if (!strcmp(args[cur_arg], "maxlife")) {
3491 unsigned int maxlife;
3492 const char *res;
3493
3494 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003495 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
3496 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003497 err_code |= ERR_ALERT | ERR_FATAL;
3498 goto out;
3499 }
3500
3501 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
3502 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003503 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
3504 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02003505 err_code |= ERR_ALERT | ERR_FATAL;
3506 goto out;
3507 }
3508 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02003509 cur_arg++;
3510 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01003511 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01003512
3513 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
3514 err_code |= ERR_WARN;
3515 curproxy->ck_opts |= PR_CK_DYNAMIC;
3516 }
3517
Willy Tarreaubaaee002006-06-26 02:48:02 +02003518 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003519 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
3520 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003521 err_code |= ERR_ALERT | ERR_FATAL;
3522 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003523 }
3524 cur_arg++;
3525 }
Willy Tarreau67402132012-05-31 20:40:20 +02003526 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003527 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
3528 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003529 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003530 }
3531
Willy Tarreau67402132012-05-31 20:40:20 +02003532 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003533 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
3534 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003535 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003536 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003537
Willy Tarreau67402132012-05-31 20:40:20 +02003538 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003539 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
3540 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02003541 err_code |= ERR_ALERT | ERR_FATAL;
3542 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003543 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09003544 else if (!strcmp(args[0], "email-alert")) {
3545 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003546 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3547 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09003548 err_code |= ERR_ALERT | ERR_FATAL;
3549 goto out;
3550 }
3551
3552 if (!strcmp(args[1], "from")) {
3553 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003554 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3555 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003556 err_code |= ERR_ALERT | ERR_FATAL;
3557 goto out;
3558 }
3559 free(curproxy->email_alert.from);
3560 curproxy->email_alert.from = strdup(args[2]);
3561 }
3562 else if (!strcmp(args[1], "mailers")) {
3563 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003564 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3565 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003566 err_code |= ERR_ALERT | ERR_FATAL;
3567 goto out;
3568 }
3569 free(curproxy->email_alert.mailers.name);
3570 curproxy->email_alert.mailers.name = strdup(args[2]);
3571 }
3572 else if (!strcmp(args[1], "myhostname")) {
3573 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003574 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3575 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003576 err_code |= ERR_ALERT | ERR_FATAL;
3577 goto out;
3578 }
3579 free(curproxy->email_alert.myhostname);
3580 curproxy->email_alert.myhostname = strdup(args[2]);
3581 }
Simon Horman64e34162015-02-06 11:11:57 +09003582 else if (!strcmp(args[1], "level")) {
3583 curproxy->email_alert.level = get_log_level(args[2]);
3584 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003585 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
3586 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09003587 err_code |= ERR_ALERT | ERR_FATAL;
3588 goto out;
3589 }
3590 }
Simon Horman9dc49962015-01-30 11:22:59 +09003591 else if (!strcmp(args[1], "to")) {
3592 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003593 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3594 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003595 err_code |= ERR_ALERT | ERR_FATAL;
3596 goto out;
3597 }
3598 free(curproxy->email_alert.to);
3599 curproxy->email_alert.to = strdup(args[2]);
3600 }
3601 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003602 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
3603 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09003604 err_code |= ERR_ALERT | ERR_FATAL;
3605 goto out;
3606 }
Simon Horman64e34162015-02-06 11:11:57 +09003607 /* Indicate that the email_alert is at least partially configured */
3608 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09003609 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09003610 else if (!strcmp(args[0], "external-check")) {
3611 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003612 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3613 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09003614 err_code |= ERR_ALERT | ERR_FATAL;
3615 goto out;
3616 }
3617
3618 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003619 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003620 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003621 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003622 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3623 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003624 err_code |= ERR_ALERT | ERR_FATAL;
3625 goto out;
3626 }
3627 free(curproxy->check_command);
3628 curproxy->check_command = strdup(args[2]);
3629 }
3630 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01003631 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02003632 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01003633 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003634 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
3635 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003636 err_code |= ERR_ALERT | ERR_FATAL;
3637 goto out;
3638 }
3639 free(curproxy->check_path);
3640 curproxy->check_path = strdup(args[2]);
3641 }
3642 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003643 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
3644 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09003645 err_code |= ERR_ALERT | ERR_FATAL;
3646 goto out;
3647 }
3648 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02003649 else if (!strcmp(args[0], "persist")) { /* persist */
3650 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003651 ha_alert("parsing [%s:%d] : missing persist method.\n",
3652 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003653 err_code |= ERR_ALERT | ERR_FATAL;
3654 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003655 }
3656
3657 if (!strncmp(args[1], "rdp-cookie", 10)) {
3658 curproxy->options2 |= PR_O2_RDPC_PRST;
3659
Emeric Brunb982a3d2010-01-04 15:45:53 +01003660 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02003661 const char *beg, *end;
3662
3663 beg = args[1] + 11;
3664 end = strchr(beg, ')');
3665
William Lallemanddf1425a2015-04-28 20:17:49 +02003666 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3667 goto out;
3668
Emeric Brun647caf12009-06-30 17:57:00 +02003669 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003670 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3671 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003672 err_code |= ERR_ALERT | ERR_FATAL;
3673 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003674 }
3675
3676 free(curproxy->rdp_cookie_name);
3677 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
3678 curproxy->rdp_cookie_len = end-beg;
3679 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003680 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02003681 free(curproxy->rdp_cookie_name);
3682 curproxy->rdp_cookie_name = strdup("msts");
3683 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
3684 }
3685 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003686 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
3687 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003688 err_code |= ERR_ALERT | ERR_FATAL;
3689 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003690 }
3691 }
3692 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003693 ha_alert("parsing [%s:%d] : unknown persist method.\n",
3694 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003695 err_code |= ERR_ALERT | ERR_FATAL;
3696 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02003697 }
3698 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003699 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003700 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 +02003701 err_code |= ERR_ALERT | ERR_FATAL;
3702 goto out;
3703 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003704 else if (!strcmp(args[0], "load-server-state-from-file")) {
3705 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3706 err_code |= ERR_WARN;
3707 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
3708 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
3709 }
3710 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
3711 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
3712 }
3713 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
3714 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
3715 }
3716 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003717 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
3718 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003719 err_code |= ERR_ALERT | ERR_FATAL;
3720 goto out;
3721 }
3722 }
3723 else if (!strcmp(args[0], "server-state-file-name")) {
3724 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3725 err_code |= ERR_WARN;
3726 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003727 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
3728 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02003729 err_code |= ERR_ALERT | ERR_FATAL;
3730 goto out;
3731 }
3732 else if (!strcmp(args[1], "use-backend-name"))
3733 curproxy->server_state_file_name = strdup(curproxy->id);
3734 else
3735 curproxy->server_state_file_name = strdup(args[1]);
3736 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003737 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02003738 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003739 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003740
Willy Tarreaubaaee002006-06-26 02:48:02 +02003741 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01003742 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003743 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 +01003744 err_code |= ERR_ALERT | ERR_FATAL;
3745 goto out;
3746 }
3747
William Lallemand1a748ae2015-05-19 16:37:23 +02003748 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3749 goto out;
3750
Willy Tarreaubaaee002006-06-26 02:48:02 +02003751 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003752 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
3753 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003754 err_code |= ERR_ALERT | ERR_FATAL;
3755 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003756 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003757 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003758 curproxy->capture_name = strdup(args[2]);
3759 curproxy->capture_namelen = strlen(curproxy->capture_name);
3760 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003761 curproxy->to_log |= LW_COOKIE;
3762 }
3763 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
3764 struct cap_hdr *hdr;
3765
3766 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003767 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 +02003768 err_code |= ERR_ALERT | ERR_FATAL;
3769 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003770 }
3771
William Lallemand1a748ae2015-05-19 16:37:23 +02003772 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3773 goto out;
3774
Willy Tarreaubaaee002006-06-26 02:48:02 +02003775 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003776 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3777 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003778 err_code |= ERR_ALERT | ERR_FATAL;
3779 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003780 }
3781
Vincent Bernat02779b62016-04-03 13:48:43 +02003782 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003783 hdr->next = curproxy->req_cap;
3784 hdr->name = strdup(args[3]);
3785 hdr->namelen = strlen(args[3]);
3786 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003787 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003788 hdr->index = curproxy->nb_req_cap++;
3789 curproxy->req_cap = hdr;
3790 curproxy->to_log |= LW_REQHDR;
3791 }
3792 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
3793 struct cap_hdr *hdr;
3794
3795 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003796 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 +02003797 err_code |= ERR_ALERT | ERR_FATAL;
3798 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003799 }
3800
William Lallemand1a748ae2015-05-19 16:37:23 +02003801 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
3802 goto out;
3803
Willy Tarreaubaaee002006-06-26 02:48:02 +02003804 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003805 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
3806 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003807 err_code |= ERR_ALERT | ERR_FATAL;
3808 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003809 }
Vincent Bernat02779b62016-04-03 13:48:43 +02003810 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02003811 hdr->next = curproxy->rsp_cap;
3812 hdr->name = strdup(args[3]);
3813 hdr->namelen = strlen(args[3]);
3814 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02003815 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003816 hdr->index = curproxy->nb_rsp_cap++;
3817 curproxy->rsp_cap = hdr;
3818 curproxy->to_log |= LW_RSPHDR;
3819 }
3820 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003821 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
3822 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003823 err_code |= ERR_ALERT | ERR_FATAL;
3824 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003825 }
3826 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003827 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01003828 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003829 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003830
William Lallemanddf1425a2015-04-28 20:17:49 +02003831 if (alertif_too_many_args(1, file, linenum, args, &err_code))
3832 goto out;
3833
Willy Tarreaubaaee002006-06-26 02:48:02 +02003834 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003835 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
3836 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003837 err_code |= ERR_ALERT | ERR_FATAL;
3838 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003839 }
3840 curproxy->conn_retries = atol(args[1]);
3841 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003842 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003843 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003844
3845 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003846 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003847 err_code |= ERR_ALERT | ERR_FATAL;
3848 goto out;
3849 }
3850
Willy Tarreau20b0de52012-12-24 15:45:22 +01003851 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003852 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003853 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3854 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
3855 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
3856 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003857 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3858 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003859 err_code |= ERR_WARN;
3860 }
3861
Willy Tarreauff011f22011-01-06 17:51:27 +01003862 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003863
Willy Tarreauff011f22011-01-06 17:51:27 +01003864 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003865 err_code |= ERR_ALERT | ERR_ABORT;
3866 goto out;
3867 }
3868
Willy Tarreau5002f572014-04-23 01:32:02 +02003869 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003870 err_code |= warnif_cond_conflicts(rule->cond,
3871 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3872 file, linenum);
3873
Willy Tarreauff011f22011-01-06 17:51:27 +01003874 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01003875 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003876 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003877 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003878
3879 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003880 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003881 err_code |= ERR_ALERT | ERR_FATAL;
3882 goto out;
3883 }
3884
3885 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003886 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02003887 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
3888 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003889 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
3890 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02003891 err_code |= ERR_WARN;
3892 }
3893
3894 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
3895
3896 if (!rule) {
3897 err_code |= ERR_ALERT | ERR_ABORT;
3898 goto out;
3899 }
3900
3901 err_code |= warnif_cond_conflicts(rule->cond,
3902 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
3903 file, linenum);
3904
3905 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
3906 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05003907 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
3908 /* set the header name and length into the proxy structure */
3909 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
3910 err_code |= ERR_WARN;
3911
3912 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003913 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
3914 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05003915 err_code |= ERR_ALERT | ERR_FATAL;
3916 goto out;
3917 }
3918
3919 /* set the desired header name */
3920 free(curproxy->server_id_hdr_name);
3921 curproxy->server_id_hdr_name = strdup(args[1]);
3922 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
3923 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003924 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003925 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003926
Willy Tarreaub099aca2008-10-12 17:26:37 +02003927 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003928 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003929 err_code |= ERR_ALERT | ERR_FATAL;
3930 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003931 }
3932
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003933 /* emulate "block" using "http-request block". Since these rules are supposed to
3934 * be processed before all http-request rules, we put them into their own list
3935 * and will insert them at the end.
3936 */
3937 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
3938 if (!rule) {
3939 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02003940 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003941 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02003942 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
3943 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);
3946 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02003947
3948 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01003949 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 +02003950
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02003951 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003952 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003953 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003954
Cyril Bonté99ed3272010-01-24 23:29:44 +01003955 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003956 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01003957 err_code |= ERR_ALERT | ERR_FATAL;
3958 goto out;
3959 }
3960
Willy Tarreaube4653b2015-05-28 15:26:58 +02003961 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003962 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
3963 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02003964 err_code |= ERR_ALERT | ERR_FATAL;
3965 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003966 }
3967
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003968 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02003969 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003970 err_code |= warnif_cond_conflicts(rule->cond,
3971 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3972 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02003973 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01003974 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003975 struct switching_rule *rule;
3976
Willy Tarreaub099aca2008-10-12 17:26:37 +02003977 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003978 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003979 err_code |= ERR_ALERT | ERR_FATAL;
3980 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02003981 }
3982
Willy Tarreau55ea7572007-06-17 19:56:27 +02003983 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003984 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003985
3986 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003987 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003988 err_code |= ERR_ALERT | ERR_FATAL;
3989 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003990 }
3991
Willy Tarreauf51658d2014-04-23 01:21:56 +02003992 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003993 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003994 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
3995 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02003996 err_code |= ERR_ALERT | ERR_FATAL;
3997 goto out;
3998 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02003999
Willy Tarreauf51658d2014-04-23 01:21:56 +02004000 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004001 }
Willy Tarreau4f862642017-02-28 09:34:39 +01004002 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004003 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
4004 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01004005 err_code |= ERR_ALERT | ERR_FATAL;
4006 goto out;
4007 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004008
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004009 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004010 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004011 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01004012 goto out;
4013 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004014 rule->cond = cond;
4015 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004016 rule->line = linenum;
4017 rule->file = strdup(file);
4018 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004019 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01004020 goto out;
4021 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004022 LIST_INIT(&rule->list);
4023 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
4024 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004025 else if (strcmp(args[0], "use-server") == 0) {
4026 struct server_rule *rule;
4027
4028 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004029 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004030 err_code |= ERR_ALERT | ERR_FATAL;
4031 goto out;
4032 }
4033
4034 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4035 err_code |= ERR_WARN;
4036
4037 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004038 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004039 err_code |= ERR_ALERT | ERR_FATAL;
4040 goto out;
4041 }
4042
4043 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004044 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4045 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004046 err_code |= ERR_ALERT | ERR_FATAL;
4047 goto out;
4048 }
4049
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004050 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004051 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
4052 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004053 err_code |= ERR_ALERT | ERR_FATAL;
4054 goto out;
4055 }
4056
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004057 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004058
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004059 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02004060 rule->cond = cond;
4061 rule->srv.name = strdup(args[1]);
4062 LIST_INIT(&rule->list);
4063 LIST_ADDQ(&curproxy->server_rules, &rule->list);
4064 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
4065 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004066 else if ((!strcmp(args[0], "force-persist")) ||
4067 (!strcmp(args[0], "ignore-persist"))) {
4068 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01004069
4070 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004071 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004072 err_code |= ERR_ALERT | ERR_FATAL;
4073 goto out;
4074 }
4075
Cyril Bonté4288c5a2018-03-12 22:02:59 +01004076 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01004077 err_code |= ERR_WARN;
4078
Willy Tarreauef6494c2010-01-28 17:12:36 +01004079 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004080 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
4081 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01004082 err_code |= ERR_ALERT | ERR_FATAL;
4083 goto out;
4084 }
4085
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004086 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004087 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
4088 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01004089 err_code |= ERR_ALERT | ERR_FATAL;
4090 goto out;
4091 }
4092
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004093 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
4094 * where force-persist is applied.
4095 */
4096 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01004097
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004098 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01004099 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004100 if (!strcmp(args[0], "force-persist")) {
4101 rule->type = PERSIST_TYPE_FORCE;
4102 } else {
4103 rule->type = PERSIST_TYPE_IGNORE;
4104 }
Willy Tarreau4de91492010-01-22 19:10:05 +01004105 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02004106 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01004107 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004108 else if (!strcmp(args[0], "stick-table")) {
4109 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02004110 struct proxy *other;
4111
Willy Tarreauc7867682018-07-27 10:26:22 +02004112 if (curproxy == &defproxy) {
4113 ha_alert("parsing [%s:%d] : 'stick-table' is not supported in 'defaults' section.\n",
4114 file, linenum);
4115 err_code |= ERR_ALERT | ERR_FATAL;
4116 goto out;
4117 }
4118
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02004119 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004120 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004121 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
4122 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02004123 err_code |= ERR_ALERT | ERR_FATAL;
4124 goto out;
4125 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004126
Emeric Brun32da3c42010-09-23 18:39:19 +02004127 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004128 curproxy->table.type = (unsigned int)-1;
4129 while (*args[myidx]) {
4130 const char *err;
4131
4132 if (strcmp(args[myidx], "size") == 0) {
4133 myidx++;
4134 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004135 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4136 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004137 err_code |= ERR_ALERT | ERR_FATAL;
4138 goto out;
4139 }
4140 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004141 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4142 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004143 err_code |= ERR_ALERT | ERR_FATAL;
4144 goto out;
4145 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004146 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004147 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004148 else if (strcmp(args[myidx], "peers") == 0) {
4149 myidx++;
Godbach50523162013-12-11 19:48:57 +08004150 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004151 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4152 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08004153 err_code |= ERR_ALERT | ERR_FATAL;
4154 goto out;
Godbach50523162013-12-11 19:48:57 +08004155 }
Emeric Brun32da3c42010-09-23 18:39:19 +02004156 curproxy->table.peers.name = strdup(args[myidx++]);
4157 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004158 else if (strcmp(args[myidx], "expire") == 0) {
4159 myidx++;
4160 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004161 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
4162 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004163 err_code |= ERR_ALERT | ERR_FATAL;
4164 goto out;
4165 }
4166 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
4167 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004168 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
4169 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004170 err_code |= ERR_ALERT | ERR_FATAL;
4171 goto out;
4172 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004173 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004174 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
4175 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00004176 err_code |= ERR_ALERT | ERR_FATAL;
4177 goto out;
4178 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004179 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01004180 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004181 }
4182 else if (strcmp(args[myidx], "nopurge") == 0) {
4183 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01004184 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004185 }
4186 else if (strcmp(args[myidx], "type") == 0) {
4187 myidx++;
4188 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004189 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
4190 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004191 err_code |= ERR_ALERT | ERR_FATAL;
4192 goto out;
4193 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004194 /* myidx already points to next arg */
4195 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004196 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02004197 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02004198 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02004199
4200 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004201 nw = args[myidx];
4202 while (*nw) {
4203 /* the "store" keyword supports a comma-separated list */
4204 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02004205 sa = NULL; /* store arg */
4206 while (*nw && *nw != ',') {
4207 if (*nw == '(') {
4208 *nw = 0;
4209 sa = ++nw;
4210 while (*nw != ')') {
4211 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004212 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
4213 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02004214 err_code |= ERR_ALERT | ERR_FATAL;
4215 goto out;
4216 }
4217 nw++;
4218 }
4219 *nw = '\0';
4220 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004221 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02004222 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004223 if (*nw)
4224 *nw++ = '\0';
4225 type = stktable_get_data_type(cw);
4226 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004227 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
4228 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004229 err_code |= ERR_ALERT | ERR_FATAL;
4230 goto out;
4231 }
Willy Tarreauac782882010-06-20 10:41:54 +02004232
4233 err = stktable_alloc_data_type(&curproxy->table, type, sa);
4234 switch (err) {
4235 case PE_NONE: break;
4236 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004237 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
4238 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004239 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02004240 break;
4241
4242 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004243 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
4244 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004245 err_code |= ERR_ALERT | ERR_FATAL;
4246 goto out;
4247
4248 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004249 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
4250 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004251 err_code |= ERR_ALERT | ERR_FATAL;
4252 goto out;
4253
4254 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004255 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
4256 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02004257 err_code |= ERR_ALERT | ERR_FATAL;
4258 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02004259 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02004260 }
4261 myidx++;
4262 }
Willy Tarreau0c559312010-01-26 18:36:26 +01004263 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004264 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
4265 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01004266 err_code |= ERR_ALERT | ERR_FATAL;
4267 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004268 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004269 }
4270
4271 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004272 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
4273 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004274 err_code |= ERR_ALERT | ERR_FATAL;
4275 goto out;
4276 }
4277
4278 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004279 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
4280 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004281 err_code |= ERR_ALERT | ERR_FATAL;
4282 goto out;
4283 }
4284 }
4285 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01004286 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02004287 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01004288 int myidx = 0;
4289 const char *name = NULL;
4290 int flags;
4291
4292 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004293 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004294 err_code |= ERR_ALERT | ERR_FATAL;
4295 goto out;
4296 }
4297
4298 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
4299 err_code |= ERR_WARN;
4300 goto out;
4301 }
4302
4303 myidx++;
4304 if ((strcmp(args[myidx], "store") == 0) ||
4305 (strcmp(args[myidx], "store-request") == 0)) {
4306 myidx++;
4307 flags = STK_IS_STORE;
4308 }
4309 else if (strcmp(args[myidx], "store-response") == 0) {
4310 myidx++;
4311 flags = STK_IS_STORE | STK_ON_RSP;
4312 }
4313 else if (strcmp(args[myidx], "match") == 0) {
4314 myidx++;
4315 flags = STK_IS_MATCH;
4316 }
4317 else if (strcmp(args[myidx], "on") == 0) {
4318 myidx++;
4319 flags = STK_IS_MATCH | STK_IS_STORE;
4320 }
4321 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004322 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004323 err_code |= ERR_ALERT | ERR_FATAL;
4324 goto out;
4325 }
4326
4327 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004328 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004329 err_code |= ERR_ALERT | ERR_FATAL;
4330 goto out;
4331 }
4332
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004333 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01004334 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004335 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004336 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004337 err_code |= ERR_ALERT | ERR_FATAL;
4338 goto out;
4339 }
4340
4341 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01004342 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004343 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
4344 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004345 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004346 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004347 goto out;
4348 }
4349 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01004350 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004351 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
4352 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004353 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004354 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004355 goto out;
4356 }
4357 }
4358
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004359 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01004360 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02004361
Emeric Brunb982a3d2010-01-04 15:45:53 +01004362 if (strcmp(args[myidx], "table") == 0) {
4363 myidx++;
4364 name = args[myidx++];
4365 }
4366
Willy Tarreauef6494c2010-01-28 17:12:36 +01004367 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004368 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004369 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
4370 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004371 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004372 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01004373 goto out;
4374 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01004375 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01004376 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004377 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
4378 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004379 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09004380 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01004381 goto out;
4382 }
Emeric Brun97679e72010-09-23 17:56:44 +02004383 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004384 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02004385 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004386 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01004387
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004388 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01004389 rule->cond = cond;
4390 rule->expr = expr;
4391 rule->flags = flags;
4392 rule->table.name = name ? strdup(name) : NULL;
4393 LIST_INIT(&rule->list);
4394 if (flags & STK_ON_RSP)
4395 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
4396 else
4397 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
4398 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004399 else if (!strcmp(args[0], "stats")) {
4400 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
4401 curproxy->uri_auth = NULL; /* we must detach from the default config */
4402
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004403 if (!*args[1]) {
4404 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02004405 } else if (!strcmp(args[1], "admin")) {
4406 struct stats_admin_rule *rule;
4407
4408 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004409 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 +02004410 err_code |= ERR_ALERT | ERR_FATAL;
4411 goto out;
4412 }
4413
4414 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004415 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004416 err_code |= ERR_ALERT | ERR_ABORT;
4417 goto out;
4418 }
4419
4420 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004421 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4422 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02004423 err_code |= ERR_ALERT | ERR_FATAL;
4424 goto out;
4425 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004426 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004427 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
4428 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02004429 err_code |= ERR_ALERT | ERR_FATAL;
4430 goto out;
4431 }
4432
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004433 err_code |= warnif_cond_conflicts(cond,
4434 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4435 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02004436
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004437 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02004438 rule->cond = cond;
4439 LIST_INIT(&rule->list);
4440 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004441 } else if (!strcmp(args[1], "uri")) {
4442 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004443 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004444 err_code |= ERR_ALERT | ERR_FATAL;
4445 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004446 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004447 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004448 err_code |= ERR_ALERT | ERR_ABORT;
4449 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004450 }
4451 } else if (!strcmp(args[1], "realm")) {
4452 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004453 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004454 err_code |= ERR_ALERT | ERR_FATAL;
4455 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004456 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004457 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004458 err_code |= ERR_ALERT | ERR_ABORT;
4459 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004460 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02004461 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004462 unsigned interval;
4463
4464 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
4465 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004466 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
4467 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004468 err_code |= ERR_ALERT | ERR_FATAL;
4469 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004470 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004471 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004472 err_code |= ERR_ALERT | ERR_ABORT;
4473 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02004474 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004475 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004476 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004477
4478 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004479 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004480 err_code |= ERR_ALERT | ERR_FATAL;
4481 goto out;
4482 }
4483
4484 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004485 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004486 err_code |= ERR_ALERT | ERR_ABORT;
4487 goto out;
4488 }
4489
Willy Tarreauff011f22011-01-06 17:51:27 +01004490 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02004491 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004492 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
4493 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004494 err_code |= ERR_WARN;
4495 }
4496
Willy Tarreauff011f22011-01-06 17:51:27 +01004497 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004498
Willy Tarreauff011f22011-01-06 17:51:27 +01004499 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004500 err_code |= ERR_ALERT | ERR_ABORT;
4501 goto out;
4502 }
4503
Willy Tarreaua91d0a52013-03-25 08:12:18 +01004504 err_code |= warnif_cond_conflicts(rule->cond,
4505 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
4506 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01004507 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01004508
Willy Tarreaubaaee002006-06-26 02:48:02 +02004509 } else if (!strcmp(args[1], "auth")) {
4510 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004511 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004512 err_code |= ERR_ALERT | ERR_FATAL;
4513 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004514 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004515 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004516 err_code |= ERR_ALERT | ERR_ABORT;
4517 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004518 }
4519 } else if (!strcmp(args[1], "scope")) {
4520 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004521 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004522 err_code |= ERR_ALERT | ERR_FATAL;
4523 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004524 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004525 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004526 err_code |= ERR_ALERT | ERR_ABORT;
4527 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004528 }
4529 } else if (!strcmp(args[1], "enable")) {
4530 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004531 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004532 err_code |= ERR_ALERT | ERR_ABORT;
4533 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004534 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004535 } else if (!strcmp(args[1], "hide-version")) {
4536 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004537 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02004538 err_code |= ERR_ALERT | ERR_ABORT;
4539 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02004540 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004541 } else if (!strcmp(args[1], "show-legends")) {
4542 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004543 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01004544 err_code |= ERR_ALERT | ERR_ABORT;
4545 goto out;
4546 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004547 } else if (!strcmp(args[1], "show-node")) {
4548
4549 if (*args[2]) {
4550 int i;
4551 char c;
4552
4553 for (i=0; args[2][i]; i++) {
4554 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01004555 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
4556 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004557 break;
4558 }
4559
4560 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004561 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
4562 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
4563 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004564 err_code |= ERR_ALERT | ERR_FATAL;
4565 goto out;
4566 }
4567 }
4568
4569 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004570 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004571 err_code |= ERR_ALERT | ERR_ABORT;
4572 goto out;
4573 }
4574 } else if (!strcmp(args[1], "show-desc")) {
4575 char *desc = NULL;
4576
4577 if (*args[2]) {
4578 int i, len=0;
4579 char *d;
4580
Willy Tarreau348acfe2014-04-14 15:00:39 +02004581 for (i = 2; *args[i]; i++)
4582 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004583
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004584 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004585
Willy Tarreau348acfe2014-04-14 15:00:39 +02004586 d += snprintf(d, desc + len - d, "%s", args[2]);
4587 for (i = 3; *args[i]; i++)
4588 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004589 }
4590
4591 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01004592 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
4593 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004594 else {
4595 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
4596 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01004597 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02004598 err_code |= ERR_ALERT | ERR_ABORT;
4599 goto out;
4600 }
4601 free(desc);
4602 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004603 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01004604stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01004605 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
4606 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004607 err_code |= ERR_ALERT | ERR_FATAL;
4608 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004609 }
4610 }
4611 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004612 int optnum;
4613
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004614 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004615 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
4616 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004617 err_code |= ERR_ALERT | ERR_FATAL;
4618 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004619 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01004620
4621 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
4622 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004623 if (cfg_opts[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_opts[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;
4631
Willy Tarreau93893792009-07-23 13:19:11 +02004632 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
4633 err_code |= ERR_WARN;
4634 goto out;
4635 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004636
Willy Tarreau3842f002009-06-14 11:39:52 +02004637 curproxy->no_options &= ~cfg_opts[optnum].val;
4638 curproxy->options &= ~cfg_opts[optnum].val;
4639
4640 switch (kwm) {
4641 case KWM_STD:
4642 curproxy->options |= cfg_opts[optnum].val;
4643 break;
4644 case KWM_NO:
4645 curproxy->no_options |= cfg_opts[optnum].val;
4646 break;
4647 case KWM_DEF: /* already cleared */
4648 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004649 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004650
Willy Tarreau93893792009-07-23 13:19:11 +02004651 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004652 }
4653 }
4654
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004655 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
4656 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01004657 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004658 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
4659 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01004660 err_code |= ERR_ALERT | ERR_FATAL;
4661 goto out;
4662 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004663 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4664 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02004665 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
4666 err_code |= ERR_WARN;
4667 goto out;
4668 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004669
Willy Tarreau3842f002009-06-14 11:39:52 +02004670 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
4671 curproxy->options2 &= ~cfg_opts2[optnum].val;
4672
4673 switch (kwm) {
4674 case KWM_STD:
4675 curproxy->options2 |= cfg_opts2[optnum].val;
4676 break;
4677 case KWM_NO:
4678 curproxy->no_options2 |= cfg_opts2[optnum].val;
4679 break;
4680 case KWM_DEF: /* already cleared */
4681 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02004682 }
Willy Tarreau93893792009-07-23 13:19:11 +02004683 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004684 }
4685 }
4686
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004687 /* HTTP options override each other. They can be cancelled using
4688 * "no option xxx" which only switches to default mode if the mode
4689 * was this one (useful for cancelling options set in defaults
4690 * sections).
4691 */
4692 if (strcmp(args[1], "httpclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004693 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4694 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004695 if (kwm == KWM_STD) {
4696 curproxy->options &= ~PR_O_HTTP_MODE;
4697 curproxy->options |= PR_O_HTTP_PCL;
4698 goto out;
4699 }
4700 else if (kwm == KWM_NO) {
4701 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL)
4702 curproxy->options &= ~PR_O_HTTP_MODE;
4703 goto out;
4704 }
4705 }
4706 else if (strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004707 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4708 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004709 if (kwm == KWM_STD) {
4710 curproxy->options &= ~PR_O_HTTP_MODE;
4711 curproxy->options |= PR_O_HTTP_FCL;
4712 goto out;
4713 }
4714 else if (kwm == KWM_NO) {
4715 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL)
4716 curproxy->options &= ~PR_O_HTTP_MODE;
4717 goto out;
4718 }
4719 }
4720 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004721 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4722 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004723 if (kwm == KWM_STD) {
4724 curproxy->options &= ~PR_O_HTTP_MODE;
4725 curproxy->options |= PR_O_HTTP_SCL;
4726 goto out;
4727 }
4728 else if (kwm == KWM_NO) {
4729 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
4730 curproxy->options &= ~PR_O_HTTP_MODE;
4731 goto out;
4732 }
4733 }
4734 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004735 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4736 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004737 if (kwm == KWM_STD) {
4738 curproxy->options &= ~PR_O_HTTP_MODE;
4739 curproxy->options |= PR_O_HTTP_KAL;
4740 goto out;
4741 }
4742 else if (kwm == KWM_NO) {
4743 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
4744 curproxy->options &= ~PR_O_HTTP_MODE;
4745 goto out;
4746 }
4747 }
4748 else if (strcmp(args[1], "http-tunnel") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02004749 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4750 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01004751 if (kwm == KWM_STD) {
4752 curproxy->options &= ~PR_O_HTTP_MODE;
4753 curproxy->options |= PR_O_HTTP_TUN;
4754 goto out;
4755 }
4756 else if (kwm == KWM_NO) {
4757 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
4758 curproxy->options &= ~PR_O_HTTP_MODE;
4759 goto out;
4760 }
4761 }
4762
Joseph Lynch726ab712015-05-11 23:25:34 -07004763 /* Redispatch can take an integer argument that control when the
4764 * resispatch occurs. All values are relative to the retries option.
4765 * This can be cancelled using "no option xxx".
4766 */
4767 if (strcmp(args[1], "redispatch") == 0) {
4768 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
4769 err_code |= ERR_WARN;
4770 goto out;
4771 }
4772
4773 curproxy->no_options &= ~PR_O_REDISP;
4774 curproxy->options &= ~PR_O_REDISP;
4775
4776 switch (kwm) {
4777 case KWM_STD:
4778 curproxy->options |= PR_O_REDISP;
4779 curproxy->redispatch_after = -1;
4780 if(*args[2]) {
4781 curproxy->redispatch_after = atol(args[2]);
4782 }
4783 break;
4784 case KWM_NO:
4785 curproxy->no_options |= PR_O_REDISP;
4786 curproxy->redispatch_after = 0;
4787 break;
4788 case KWM_DEF: /* already cleared */
4789 break;
4790 }
4791 goto out;
4792 }
4793
Willy Tarreau3842f002009-06-14 11:39:52 +02004794 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004795 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
4796 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004797 err_code |= ERR_ALERT | ERR_FATAL;
4798 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004799 }
4800
Emeric Brun3a058f32009-06-30 18:26:00 +02004801 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01004802 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004803 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01004804 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004805 if (*(args[2]) != '\0') {
4806 if (!strcmp(args[2], "clf")) {
4807 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01004808 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02004809 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004810 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004811 err_code |= ERR_ALERT | ERR_FATAL;
4812 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004813 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004814 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4815 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02004816 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004817 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4818 char *oldlogformat = "log-format";
4819 char *clflogformat = "";
4820
4821 if (curproxy->conf.logformat_string == default_http_log_format)
4822 oldlogformat = "option httplog";
4823 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4824 oldlogformat = "option tcplog";
4825 else if (curproxy->conf.logformat_string == clf_http_log_format)
4826 oldlogformat = "option httplog clf";
4827 if (logformat == clf_http_log_format)
4828 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004829 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
4830 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004831 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004832 if (curproxy->conf.logformat_string != default_http_log_format &&
4833 curproxy->conf.logformat_string != default_tcp_log_format &&
4834 curproxy->conf.logformat_string != clf_http_log_format)
4835 free(curproxy->conf.logformat_string);
4836 curproxy->conf.logformat_string = logformat;
4837
4838 free(curproxy->conf.lfs_file);
4839 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4840 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004841
4842 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4843 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
4844 file, linenum, curproxy->id);
4845 err_code |= ERR_WARN;
4846 }
Emeric Brun3a058f32009-06-30 18:26:00 +02004847 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004848 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004849 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4850 char *oldlogformat = "log-format";
4851
4852 if (curproxy->conf.logformat_string == default_http_log_format)
4853 oldlogformat = "option httplog";
4854 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4855 oldlogformat = "option tcplog";
4856 else if (curproxy->conf.logformat_string == clf_http_log_format)
4857 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004858 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
4859 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004860 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004861 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02004862 if (curproxy->conf.logformat_string != default_http_log_format &&
4863 curproxy->conf.logformat_string != default_tcp_log_format &&
4864 curproxy->conf.logformat_string != clf_http_log_format)
4865 free(curproxy->conf.logformat_string);
4866 curproxy->conf.logformat_string = default_tcp_log_format;
4867
4868 free(curproxy->conf.lfs_file);
4869 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4870 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02004871
4872 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4873 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01004874
4875 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
4876 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
4877 file, linenum, curproxy->id);
4878 err_code |= ERR_WARN;
4879 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01004880 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004881 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02004882 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004883 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004884 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004885
William Lallemanddf1425a2015-04-28 20:17:49 +02004886 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4887 goto out;
4888
Willy Tarreau13943ab2006-12-31 00:24:10 +01004889 if (curproxy->cap & PR_CAP_FE)
4890 curproxy->options |= PR_O_TCP_CLI_KA;
4891 if (curproxy->cap & PR_CAP_BE)
4892 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004893 }
4894 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01004895 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004896 err_code |= ERR_WARN;
4897
Willy Tarreaubaaee002006-06-26 02:48:02 +02004898 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004899 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004900 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004901 curproxy->options2 &= ~PR_O2_CHK_ANY;
4902 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004903 if (!*args[2]) { /* no argument */
4904 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
4905 curproxy->check_len = strlen(DEF_CHECK_REQ);
4906 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004907 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004908 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004909 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004910 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004911 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01004912 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004913 if (*args[4])
4914 reqlen += strlen(args[4]);
4915 else
4916 reqlen += strlen("HTTP/1.0");
4917
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004918 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02004919 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01004920 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02004921 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004922 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
4923 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02004924 }
4925 else if (!strcmp(args[1], "ssl-hello-chk")) {
4926 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01004927 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004928 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01004929
Willy Tarreaua534fea2008-08-03 12:19:50 +02004930 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004931 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004932 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02004933 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004934
4935 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4936 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004937 }
Willy Tarreau23677902007-05-08 23:50:35 +02004938 else if (!strcmp(args[1], "smtpchk")) {
4939 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02004940 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01004941 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004942 curproxy->options2 &= ~PR_O2_CHK_ANY;
4943 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02004944
4945 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
4946 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4947 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4948 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
4949 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
4950 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004951 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02004952 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
4953 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
4954 } else {
4955 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
4956 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
4957 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
4958 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
4959 }
4960 }
William Lallemanddf1425a2015-04-28 20:17:49 +02004961 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
4962 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02004963 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004964 else if (!strcmp(args[1], "pgsql-check")) {
4965 /* use PostgreSQL request to check servers' health */
4966 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4967 err_code |= ERR_WARN;
4968
4969 free(curproxy->check_req);
4970 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004971 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004972 curproxy->options2 |= PR_O2_PGSQL_CHK;
4973
4974 if (*(args[2])) {
4975 int cur_arg = 2;
4976
4977 while (*(args[cur_arg])) {
4978 if (strcmp(args[cur_arg], "user") == 0) {
4979 char * packet;
4980 uint32_t packet_len;
4981 uint32_t pv;
4982
4983 /* suboption header - needs additional argument for it */
4984 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004985 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
4986 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004987 err_code |= ERR_ALERT | ERR_FATAL;
4988 goto out;
4989 }
4990
4991 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
4992 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
4993 pv = htonl(0x30000); /* protocol version 3.0 */
4994
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004995 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01004996
4997 memcpy(packet + 4, &pv, 4);
4998
4999 /* copy "user" */
5000 memcpy(packet + 8, "user", 4);
5001
5002 /* copy username */
5003 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
5004
5005 free(curproxy->check_req);
5006 curproxy->check_req = packet;
5007 curproxy->check_len = packet_len;
5008
5009 packet_len = htonl(packet_len);
5010 memcpy(packet, &packet_len, 4);
5011 cur_arg += 2;
5012 } else {
5013 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005014 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5015 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005016 err_code |= ERR_ALERT | ERR_FATAL;
5017 goto out;
5018 }
5019 } /* end while loop */
5020 }
William Lallemanddf1425a2015-04-28 20:17:49 +02005021 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
5022 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01005023 }
5024
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005025 else if (!strcmp(args[1], "redis-check")) {
5026 /* use REDIS PING request to check servers' health */
5027 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5028 err_code |= ERR_WARN;
5029
5030 free(curproxy->check_req);
5031 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005032 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005033 curproxy->options2 |= PR_O2_REDIS_CHK;
5034
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005035 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005036 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
5037 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005038
5039 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5040 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02005041 }
5042
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005043 else if (!strcmp(args[1], "mysql-check")) {
5044 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005045 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5046 err_code |= ERR_WARN;
5047
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005048 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01005049 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005050 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005051 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005052
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005053 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005054 * const char mysql40_client_auth_pkt[] = {
5055 * "\x0e\x00\x00" // packet length
5056 * "\x01" // packet number
5057 * "\x00\x00" // client capabilities
5058 * "\x00\x00\x01" // max packet
5059 * "haproxy\x00" // username (null terminated string)
5060 * "\x00" // filler (always 0x00)
5061 * "\x01\x00\x00" // packet length
5062 * "\x00" // packet number
5063 * "\x01" // COM_QUIT command
5064 * };
5065 */
5066
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005067 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
5068 * const char mysql41_client_auth_pkt[] = {
5069 * "\x0e\x00\x00\" // packet length
5070 * "\x01" // packet number
5071 * "\x00\x00\x00\x00" // client capabilities
5072 * "\x00\x00\x00\x01" // max packet
5073 * "\x21" // character set (UTF-8)
5074 * char[23] // All zeroes
5075 * "haproxy\x00" // username (null terminated string)
5076 * "\x00" // filler (always 0x00)
5077 * "\x01\x00\x00" // packet length
5078 * "\x00" // packet number
5079 * "\x01" // COM_QUIT command
5080 * };
5081 */
5082
5083
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005084 if (*(args[2])) {
5085 int cur_arg = 2;
5086
5087 while (*(args[cur_arg])) {
5088 if (strcmp(args[cur_arg], "user") == 0) {
5089 char *mysqluser;
5090 int packetlen, reqlen, userlen;
5091
5092 /* suboption header - needs additional argument for it */
5093 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005094 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
5095 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005096 err_code |= ERR_ALERT | ERR_FATAL;
5097 goto out;
5098 }
5099 mysqluser = args[cur_arg + 1];
5100 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005101
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005102 if (*(args[cur_arg+2])) {
5103 if (!strcmp(args[cur_arg+2], "post-41")) {
5104 packetlen = userlen + 7 + 27;
5105 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005106
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005107 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005108 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005109 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005110
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005111 snprintf(curproxy->check_req, 4, "%c%c%c",
5112 ((unsigned char) packetlen & 0xff),
5113 ((unsigned char) (packetlen >> 8) & 0xff),
5114 ((unsigned char) (packetlen >> 16) & 0xff));
5115
5116 curproxy->check_req[3] = 1;
5117 curproxy->check_req[5] = 130;
5118 curproxy->check_req[11] = 1;
5119 curproxy->check_req[12] = 33;
5120 memcpy(&curproxy->check_req[36], mysqluser, userlen);
5121 curproxy->check_req[36 + userlen + 1 + 1] = 1;
5122 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
5123 cur_arg += 3;
5124 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005125 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 +02005126 err_code |= ERR_ALERT | ERR_FATAL;
5127 goto out;
5128 }
5129 } else {
5130 packetlen = userlen + 7;
5131 reqlen = packetlen + 9;
5132
5133 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005134 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02005135 curproxy->check_len = reqlen;
5136
5137 snprintf(curproxy->check_req, 4, "%c%c%c",
5138 ((unsigned char) packetlen & 0xff),
5139 ((unsigned char) (packetlen >> 8) & 0xff),
5140 ((unsigned char) (packetlen >> 16) & 0xff));
5141
5142 curproxy->check_req[3] = 1;
5143 curproxy->check_req[5] = 128;
5144 curproxy->check_req[8] = 1;
5145 memcpy(&curproxy->check_req[9], mysqluser, userlen);
5146 curproxy->check_req[9 + userlen + 1 + 1] = 1;
5147 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
5148 cur_arg += 2;
5149 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005150 } else {
5151 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005152 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
5153 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02005154 err_code |= ERR_ALERT | ERR_FATAL;
5155 goto out;
5156 }
5157 } /* end while loop */
5158 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01005159 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005160 else if (!strcmp(args[1], "ldap-check")) {
5161 /* use LDAP request to check servers' health */
5162 free(curproxy->check_req);
5163 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005164 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005165 curproxy->options2 |= PR_O2_LDAP_CHK;
5166
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005167 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005168 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
5169 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02005170 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5171 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02005172 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01005173 else if (!strcmp(args[1], "spop-check")) {
5174 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005175 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
5176 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005177 err_code |= ERR_ALERT | ERR_FATAL;
5178 goto out;
5179 }
5180 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005181 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
5182 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005183 err_code |= ERR_ALERT | ERR_FATAL;
5184 goto out;
5185 }
5186
5187 /* use SPOE request to check servers' health */
5188 free(curproxy->check_req);
5189 curproxy->check_req = NULL;
5190 curproxy->options2 &= ~PR_O2_CHK_ANY;
5191 curproxy->options2 |= PR_O2_SPOP_CHK;
5192
Christopher Faulet8ef75252017-02-20 22:56:03 +01005193 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005194 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01005195 err_code |= ERR_ALERT | ERR_FATAL;
5196 goto out;
5197 }
5198 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5199 goto out;
5200 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005201 else if (!strcmp(args[1], "tcp-check")) {
5202 /* use raw TCPCHK send/expect to check servers' health */
5203 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
5204 err_code |= ERR_WARN;
5205
5206 free(curproxy->check_req);
5207 curproxy->check_req = NULL;
5208 curproxy->options2 &= ~PR_O2_CHK_ANY;
5209 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005210 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5211 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005212 }
Simon Horman98637e52014-06-20 12:30:16 +09005213 else if (!strcmp(args[1], "external-check")) {
5214 /* excute an external command to check servers' health */
5215 free(curproxy->check_req);
5216 curproxy->check_req = NULL;
5217 curproxy->options2 &= ~PR_O2_CHK_ANY;
5218 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02005219 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5220 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09005221 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005222 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02005223 int cur_arg;
5224
5225 /* insert x-forwarded-for field, but not for the IP address listed as an except.
5226 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005227 */
Ross Westaf72a1d2008-08-03 10:51:45 +02005228
Willy Tarreau87cf5142011-08-19 22:57:24 +02005229 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02005230
5231 free(curproxy->fwdfor_hdr_name);
5232 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
5233 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
5234
5235 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
5236 cur_arg = 2;
5237 while (*(args[cur_arg])) {
5238 if (!strcmp(args[cur_arg], "except")) {
5239 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005240 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005241 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5242 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005243 err_code |= ERR_ALERT | ERR_FATAL;
5244 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005245 }
5246 /* flush useless bits */
5247 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02005248 cur_arg += 2;
5249 } else if (!strcmp(args[cur_arg], "header")) {
5250 /* suboption header - needs additional argument for it */
5251 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005252 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5253 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005254 err_code |= ERR_ALERT | ERR_FATAL;
5255 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02005256 }
5257 free(curproxy->fwdfor_hdr_name);
5258 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
5259 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
5260 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02005261 } else if (!strcmp(args[cur_arg], "if-none")) {
5262 curproxy->options &= ~PR_O_FF_ALWAYS;
5263 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005264 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02005265 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005266 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
5267 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005268 err_code |= ERR_ALERT | ERR_FATAL;
5269 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005270 }
Ross Westaf72a1d2008-08-03 10:51:45 +02005271 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02005272 }
Maik Broemme2850cb42009-04-17 18:53:21 +02005273 else if (!strcmp(args[1], "originalto")) {
5274 int cur_arg;
5275
5276 /* insert x-original-to field, but not for the IP address listed as an except.
5277 * set default options (ie: bitfield, header name, etc)
5278 */
5279
5280 curproxy->options |= PR_O_ORGTO;
5281
5282 free(curproxy->orgto_hdr_name);
5283 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
5284 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
5285
Willy Tarreau87cf5142011-08-19 22:57:24 +02005286 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02005287 cur_arg = 2;
5288 while (*(args[cur_arg])) {
5289 if (!strcmp(args[cur_arg], "except")) {
5290 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01005291 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 +01005292 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
5293 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005294 err_code |= ERR_ALERT | ERR_FATAL;
5295 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005296 }
5297 /* flush useless bits */
5298 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
5299 cur_arg += 2;
5300 } else if (!strcmp(args[cur_arg], "header")) {
5301 /* suboption header - needs additional argument for it */
5302 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005303 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
5304 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005305 err_code |= ERR_ALERT | ERR_FATAL;
5306 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005307 }
5308 free(curproxy->orgto_hdr_name);
5309 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
5310 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
5311 cur_arg += 2;
5312 } else {
5313 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005314 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
5315 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005316 err_code |= ERR_ALERT | ERR_FATAL;
5317 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02005318 }
5319 } /* end while loop */
5320 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005321 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005322 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005323 err_code |= ERR_ALERT | ERR_FATAL;
5324 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005325 }
Willy Tarreau93893792009-07-23 13:19:11 +02005326 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005327 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005328 else if (!strcmp(args[0], "default_backend")) {
5329 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005330 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005331
5332 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005333 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005334 err_code |= ERR_ALERT | ERR_FATAL;
5335 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005336 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02005337 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005338 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005339
5340 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5341 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01005342 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005343 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01005344 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005345 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005346
Willy Tarreaua3c504c2014-04-28 22:37:32 +02005347 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01005348 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
5349 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005350 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005351 /* enable reconnections to dispatch */
5352 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005353
5354 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
5355 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005356 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005357 else if (!strcmp(args[0], "http-reuse")) {
5358 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5359 err_code |= ERR_WARN;
5360
5361 if (strcmp(args[1], "never") == 0) {
5362 /* enable a graceful server shutdown on an HTTP 404 response */
5363 curproxy->options &= ~PR_O_REUSE_MASK;
5364 curproxy->options |= PR_O_REUSE_NEVR;
5365 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5366 goto out;
5367 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02005368 else if (strcmp(args[1], "safe") == 0) {
5369 /* enable a graceful server shutdown on an HTTP 404 response */
5370 curproxy->options &= ~PR_O_REUSE_MASK;
5371 curproxy->options |= PR_O_REUSE_SAFE;
5372 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5373 goto out;
5374 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02005375 else if (strcmp(args[1], "aggressive") == 0) {
5376 curproxy->options &= ~PR_O_REUSE_MASK;
5377 curproxy->options |= PR_O_REUSE_AGGR;
5378 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5379 goto out;
5380 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005381 else if (strcmp(args[1], "always") == 0) {
5382 /* enable a graceful server shutdown on an HTTP 404 response */
5383 curproxy->options &= ~PR_O_REUSE_MASK;
5384 curproxy->options |= PR_O_REUSE_ALWS;
5385 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5386 goto out;
5387 }
5388 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005389 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02005390 err_code |= ERR_ALERT | ERR_FATAL;
5391 goto out;
5392 }
5393 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005394 else if (!strcmp(args[0], "http-check")) {
5395 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005396 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01005397
5398 if (strcmp(args[1], "disable-on-404") == 0) {
5399 /* enable a graceful server shutdown on an HTTP 404 response */
5400 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02005401 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5402 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005403 }
Willy Tarreauef781042010-01-27 11:53:01 +01005404 else if (strcmp(args[1], "send-state") == 0) {
5405 /* enable emission of the apparent state of a server in HTTP checks */
5406 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02005407 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
5408 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01005409 }
Willy Tarreaubd741542010-03-16 18:46:54 +01005410 else if (strcmp(args[1], "expect") == 0) {
5411 const char *ptr_arg;
5412 int cur_arg;
5413
5414 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005415 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01005416 err_code |= ERR_ALERT | ERR_FATAL;
5417 goto out;
5418 }
5419
5420 cur_arg = 2;
5421 /* consider exclamation marks, sole or at the beginning of a word */
5422 while (*(ptr_arg = args[cur_arg])) {
5423 while (*ptr_arg == '!') {
5424 curproxy->options2 ^= PR_O2_EXP_INV;
5425 ptr_arg++;
5426 }
5427 if (*ptr_arg)
5428 break;
5429 cur_arg++;
5430 }
5431 /* now ptr_arg points to the beginning of a word past any possible
5432 * exclamation mark, and cur_arg is the argument which holds this word.
5433 */
5434 if (strcmp(ptr_arg, "status") == 0) {
5435 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005436 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5437 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005438 err_code |= ERR_ALERT | ERR_FATAL;
5439 goto out;
5440 }
5441 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005442 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005443 curproxy->expect_str = strdup(args[cur_arg + 1]);
5444 }
5445 else if (strcmp(ptr_arg, "string") == 0) {
5446 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005447 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5448 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005449 err_code |= ERR_ALERT | ERR_FATAL;
5450 goto out;
5451 }
5452 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005453 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01005454 curproxy->expect_str = strdup(args[cur_arg + 1]);
5455 }
5456 else if (strcmp(ptr_arg, "rstatus") == 0) {
5457 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005458 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5459 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005460 err_code |= ERR_ALERT | ERR_FATAL;
5461 goto out;
5462 }
5463 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005464 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005465 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005466 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005467 free(curproxy->expect_regex);
5468 curproxy->expect_regex = NULL;
5469 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005470 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005471 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5472 error = NULL;
5473 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005474 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5475 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005476 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005477 err_code |= ERR_ALERT | ERR_FATAL;
5478 goto out;
5479 }
5480 }
5481 else if (strcmp(ptr_arg, "rstring") == 0) {
5482 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005483 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5484 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005485 err_code |= ERR_ALERT | ERR_FATAL;
5486 goto out;
5487 }
5488 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005489 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005490 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005491 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02005492 free(curproxy->expect_regex);
5493 curproxy->expect_regex = NULL;
5494 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02005495 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005496 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
5497 error = NULL;
5498 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005499 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5500 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005501 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01005502 err_code |= ERR_ALERT | ERR_FATAL;
5503 goto out;
5504 }
5505 }
5506 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005507 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
5508 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01005509 err_code |= ERR_ALERT | ERR_FATAL;
5510 goto out;
5511 }
5512 }
Willy Tarreau48494c02007-11-30 10:41:39 +01005513 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005514 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 +02005515 err_code |= ERR_ALERT | ERR_FATAL;
5516 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01005517 }
5518 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005519 else if (!strcmp(args[0], "tcp-check")) {
5520 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
5521 err_code |= ERR_WARN;
5522
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005523 if (strcmp(args[1], "comment") == 0) {
5524 int cur_arg;
5525 struct tcpcheck_rule *tcpcheck;
5526
5527 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005528 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005529 tcpcheck->action = TCPCHK_ACT_COMMENT;
5530
5531 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005532 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5533 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005534 err_code |= ERR_ALERT | ERR_FATAL;
5535 goto out;
5536 }
5537
5538 tcpcheck->comment = strdup(args[cur_arg + 1]);
5539
5540 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02005541 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
5542 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005543 }
5544 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005545 const char *ptr_arg;
5546 int cur_arg;
5547 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005548
5549 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02005550 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
5551 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
5552 tcpcheck->action == TCPCHK_ACT_COMMENT) {
5553 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
5554 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005555
Willy Tarreau5581c272015-05-13 12:24:53 +02005556 if (&tcpcheck->list != &curproxy->tcpcheck_rules
5557 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005558 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
5559 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02005560 err_code |= ERR_ALERT | ERR_FATAL;
5561 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005562 }
5563
5564 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005565 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005566 tcpcheck->action = TCPCHK_ACT_CONNECT;
5567
5568 /* parsing each parameters to fill up the rule */
5569 while (*(ptr_arg = args[cur_arg])) {
5570 /* tcp port */
5571 if (strcmp(args[cur_arg], "port") == 0) {
5572 if ( (atol(args[cur_arg + 1]) > 65535) ||
5573 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01005574 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
5575 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005576 err_code |= ERR_ALERT | ERR_FATAL;
5577 goto out;
5578 }
5579 tcpcheck->port = atol(args[cur_arg + 1]);
5580 cur_arg += 2;
5581 }
5582 /* send proxy protocol */
5583 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
5584 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
5585 cur_arg++;
5586 }
5587#ifdef USE_OPENSSL
5588 else if (strcmp(args[cur_arg], "ssl") == 0) {
5589 curproxy->options |= PR_O_TCPCHK_SSL;
5590 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
5591 cur_arg++;
5592 }
5593#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005594 /* comment for this tcpcheck line */
5595 else if (strcmp(args[cur_arg], "comment") == 0) {
5596 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005597 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5598 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005599 err_code |= ERR_ALERT | ERR_FATAL;
5600 goto out;
5601 }
5602 tcpcheck->comment = strdup(args[cur_arg + 1]);
5603 cur_arg += 2;
5604 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005605 else {
5606#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01005607 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 +01005608#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005609 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 +01005610#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005611 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01005612 err_code |= ERR_ALERT | ERR_FATAL;
5613 goto out;
5614 }
5615
5616 }
5617
5618 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5619 }
5620 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005621 if (! *(args[2]) ) {
5622 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005623 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
5624 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005625 err_code |= ERR_ALERT | ERR_FATAL;
5626 goto out;
5627 } else {
5628 struct tcpcheck_rule *tcpcheck;
5629
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005630 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005631
5632 tcpcheck->action = TCPCHK_ACT_SEND;
5633 tcpcheck->string_len = strlen(args[2]);
5634 tcpcheck->string = strdup(args[2]);
5635 tcpcheck->expect_regex = NULL;
5636
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005637 /* comment for this tcpcheck line */
5638 if (strcmp(args[3], "comment") == 0) {
5639 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005640 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5641 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005642 err_code |= ERR_ALERT | ERR_FATAL;
5643 goto out;
5644 }
5645 tcpcheck->comment = strdup(args[4]);
5646 }
5647
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005648 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5649 }
5650 }
5651 else if (strcmp(args[1], "send-binary") == 0) {
5652 if (! *(args[2]) ) {
5653 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005654 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
5655 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005656 err_code |= ERR_ALERT | ERR_FATAL;
5657 goto out;
5658 } else {
5659 struct tcpcheck_rule *tcpcheck;
5660 char *err = NULL;
5661
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005662 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005663
5664 tcpcheck->action = TCPCHK_ACT_SEND;
5665 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005666 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5667 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005668 err_code |= ERR_ALERT | ERR_FATAL;
5669 goto out;
5670 }
5671 tcpcheck->expect_regex = NULL;
5672
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005673 /* comment for this tcpcheck line */
5674 if (strcmp(args[3], "comment") == 0) {
5675 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005676 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5677 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005678 err_code |= ERR_ALERT | ERR_FATAL;
5679 goto out;
5680 }
5681 tcpcheck->comment = strdup(args[4]);
5682 }
5683
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005684 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5685 }
5686 }
5687 else if (strcmp(args[1], "expect") == 0) {
5688 const char *ptr_arg;
5689 int cur_arg;
5690 int inverse = 0;
5691
5692 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005693 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005694 err_code |= ERR_ALERT | ERR_FATAL;
5695 goto out;
5696 }
5697
5698 cur_arg = 2;
5699 /* consider exclamation marks, sole or at the beginning of a word */
5700 while (*(ptr_arg = args[cur_arg])) {
5701 while (*ptr_arg == '!') {
5702 inverse = !inverse;
5703 ptr_arg++;
5704 }
5705 if (*ptr_arg)
5706 break;
5707 cur_arg++;
5708 }
5709 /* now ptr_arg points to the beginning of a word past any possible
5710 * exclamation mark, and cur_arg is the argument which holds this word.
5711 */
5712 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005713 struct tcpcheck_rule *tcpcheck;
5714 char *err = NULL;
5715
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005716 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005717 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
5718 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005719 err_code |= ERR_ALERT | ERR_FATAL;
5720 goto out;
5721 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005722
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005723 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005724
5725 tcpcheck->action = TCPCHK_ACT_EXPECT;
5726 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005727 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
5728 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005729 err_code |= ERR_ALERT | ERR_FATAL;
5730 goto out;
5731 }
5732 tcpcheck->expect_regex = NULL;
5733 tcpcheck->inverse = inverse;
5734
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005735 /* tcpcheck comment */
5736 cur_arg += 2;
5737 if (strcmp(args[cur_arg], "comment") == 0) {
5738 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005739 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5740 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005741 err_code |= ERR_ALERT | ERR_FATAL;
5742 goto out;
5743 }
5744 tcpcheck->comment = strdup(args[cur_arg + 1]);
5745 }
5746
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005747 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5748 }
5749 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005750 struct tcpcheck_rule *tcpcheck;
5751
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005752 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005753 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
5754 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005755 err_code |= ERR_ALERT | ERR_FATAL;
5756 goto out;
5757 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005758
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005759 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005760
5761 tcpcheck->action = TCPCHK_ACT_EXPECT;
5762 tcpcheck->string_len = strlen(args[cur_arg + 1]);
5763 tcpcheck->string = strdup(args[cur_arg + 1]);
5764 tcpcheck->expect_regex = NULL;
5765 tcpcheck->inverse = inverse;
5766
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005767 /* tcpcheck comment */
5768 cur_arg += 2;
5769 if (strcmp(args[cur_arg], "comment") == 0) {
5770 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005771 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5772 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005773 err_code |= ERR_ALERT | ERR_FATAL;
5774 goto out;
5775 }
5776 tcpcheck->comment = strdup(args[cur_arg + 1]);
5777 }
5778
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005779 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5780 }
5781 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01005782 struct tcpcheck_rule *tcpcheck;
5783
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005784 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005785 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
5786 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005787 err_code |= ERR_ALERT | ERR_FATAL;
5788 goto out;
5789 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005790
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02005791 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005792
5793 tcpcheck->action = TCPCHK_ACT_EXPECT;
5794 tcpcheck->string_len = 0;
5795 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005796 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
5797 error = NULL;
5798 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005799 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
5800 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02005801 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005802 err_code |= ERR_ALERT | ERR_FATAL;
5803 goto out;
5804 }
5805 tcpcheck->inverse = inverse;
5806
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005807 /* tcpcheck comment */
5808 cur_arg += 2;
5809 if (strcmp(args[cur_arg], "comment") == 0) {
5810 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005811 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
5812 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02005813 err_code |= ERR_ALERT | ERR_FATAL;
5814 goto out;
5815 }
5816 tcpcheck->comment = strdup(args[cur_arg + 1]);
5817 }
5818
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005819 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
5820 }
5821 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005822 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
5823 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02005824 err_code |= ERR_ALERT | ERR_FATAL;
5825 goto out;
5826 }
5827 }
5828 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005829 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 +02005830 err_code |= ERR_ALERT | ERR_FATAL;
5831 goto out;
5832 }
5833 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01005834 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02005835 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005836 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005837 err_code |= ERR_ALERT | ERR_FATAL;
5838 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02005839 }
5840
Willy Tarreaub80c2302007-11-30 20:51:32 +01005841 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005842 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005843
5844 if (strcmp(args[1], "fail") == 0) {
5845 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01005846 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005847 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
5848 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005849 err_code |= ERR_ALERT | ERR_FATAL;
5850 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005851 }
5852
Willy Tarreau721d8e02017-12-01 18:25:08 +01005853 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005854 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005855 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
5856 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005857 err_code |= ERR_ALERT | ERR_FATAL;
5858 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005859 }
5860 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
5861 }
5862 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005863 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005864 err_code |= ERR_ALERT | ERR_FATAL;
5865 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01005866 }
5867 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005868#ifdef TPROXY
5869 else if (!strcmp(args[0], "transparent")) {
5870 /* enable transparent proxy connections */
5871 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02005872 if (alertif_too_many_args(0, file, linenum, args, &err_code))
5873 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005874 }
5875#endif
5876 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005877 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005878 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005879
Willy Tarreaubaaee002006-06-26 02:48:02 +02005880 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005881 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005882 err_code |= ERR_ALERT | ERR_FATAL;
5883 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005884 }
5885 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005886 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5887 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005888 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005889 else if (!strcmp(args[0], "backlog")) { /* backlog */
5890 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005891 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005892
5893 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005894 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005895 err_code |= ERR_ALERT | ERR_FATAL;
5896 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005897 }
5898 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005899 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5900 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01005901 }
Willy Tarreau86034312006-12-29 00:10:33 +01005902 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005903 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02005904 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005905
Willy Tarreau86034312006-12-29 00:10:33 +01005906 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005907 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005908 err_code |= ERR_ALERT | ERR_FATAL;
5909 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005910 }
5911 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02005912 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5913 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01005914 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005915 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
5916 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005917 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005918 err_code |= ERR_ALERT | ERR_FATAL;
5919 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005920 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005921 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
5922 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005923 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
5924 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02005925 err_code |= ERR_ALERT | ERR_FATAL;
5926 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01005927 }
5928 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02005929 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5930 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005931 }
5932 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01005933 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005934 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005935 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005936
Willy Tarreaubaaee002006-06-26 02:48:02 +02005937 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005938 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005939 err_code |= ERR_ALERT | ERR_FATAL;
5940 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005941 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005942 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005943 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005944
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005945 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005946 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005947 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005948 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005949 goto out;
5950 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01005951
5952 proto = protocol_by_family(sk->ss_family);
5953 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005954 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5955 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005956 err_code |= ERR_ALERT | ERR_FATAL;
5957 goto out;
5958 }
5959
5960 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005961 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
5962 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02005963 err_code |= ERR_ALERT | ERR_FATAL;
5964 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005965 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005966
5967 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005968 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
5969 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005970 err_code |= ERR_ALERT | ERR_FATAL;
5971 goto out;
5972 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005973
William Lallemanddf1425a2015-04-28 20:17:49 +02005974 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5975 goto out;
5976
Willy Tarreaud5191e72010-02-09 20:50:45 +01005977 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02005978 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005979 }
5980 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01005981 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005982 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005983
Willy Tarreaua93c74b2012-05-08 18:14:39 +02005984 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005985 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005986 err_code |= ERR_ALERT | ERR_FATAL;
5987 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02005988 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005989 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005990 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05005991 /**
5992 * The syntax for hash-type config element is
5993 * hash-type {map-based|consistent} [[<algo>] avalanche]
5994 *
5995 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
5996 */
5997 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04005998
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02005999 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
6000 err_code |= ERR_WARN;
6001
6002 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006003 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
6004 }
6005 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006006 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
6007 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006008 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006009 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 -05006010 err_code |= ERR_ALERT | ERR_FATAL;
6011 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01006012 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006013 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006014 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02006015 err_code |= ERR_ALERT | ERR_FATAL;
6016 goto out;
6017 }
Bhaskar98634f02013-10-29 23:30:51 -04006018
6019 /* set the hash function to use */
6020 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006021 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04006022 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006023
6024 /* if consistent with no argument, then avalanche modifier is also applied */
6025 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
6026 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04006027 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006028 /* set the hash function */
6029 if (!strcmp(args[2], "sdbm")) {
6030 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
6031 }
6032 else if (!strcmp(args[2], "djb2")) {
6033 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01006034 }
6035 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01006036 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006037 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01006038 else if (!strcmp(args[2], "crc32")) {
6039 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
6040 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05006041 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006042 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 -05006043 err_code |= ERR_ALERT | ERR_FATAL;
6044 goto out;
6045 }
6046
6047 /* set the hash modifier */
6048 if (!strcmp(args[3], "avalanche")) {
6049 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
6050 }
6051 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006052 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 -05006053 err_code |= ERR_ALERT | ERR_FATAL;
6054 goto out;
6055 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01006056 }
William Lallemanda73203e2012-03-12 12:48:57 +01006057 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006058 else if (strcmp(args[0], "hash-balance-factor") == 0) {
6059 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006060 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04006061 err_code |= ERR_ALERT | ERR_FATAL;
6062 goto out;
6063 }
6064 curproxy->lbprm.chash.balance_factor = atol(args[1]);
6065 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006066 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 -04006067 err_code |= ERR_ALERT | ERR_FATAL;
6068 goto out;
6069 }
6070 }
William Lallemanda73203e2012-03-12 12:48:57 +01006071 else if (strcmp(args[0], "unique-id-format") == 0) {
6072 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006073 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006074 err_code |= ERR_ALERT | ERR_FATAL;
6075 goto out;
6076 }
William Lallemand3203ff42012-11-11 17:30:56 +01006077 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006078 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 +01006079 err_code |= ERR_ALERT | ERR_FATAL;
6080 goto out;
6081 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006082 free(curproxy->conf.uniqueid_format_string);
6083 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006084
Willy Tarreau62a61232013-04-12 18:13:46 +02006085 free(curproxy->conf.uif_file);
6086 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
6087 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01006088 }
William Lallemanda73203e2012-03-12 12:48:57 +01006089
6090 else if (strcmp(args[0], "unique-id-header") == 0) {
6091 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006092 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01006093 err_code |= ERR_ALERT | ERR_FATAL;
6094 goto out;
6095 }
6096 free(curproxy->header_unique_id);
6097 curproxy->header_unique_id = strdup(args[1]);
6098 }
6099
William Lallemand723b73a2012-02-08 16:37:49 +01006100 else if (strcmp(args[0], "log-format") == 0) {
6101 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006102 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01006103 err_code |= ERR_ALERT | ERR_FATAL;
6104 goto out;
6105 }
William Lallemand3203ff42012-11-11 17:30:56 +01006106 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006107 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 +01006108 err_code |= ERR_ALERT | ERR_FATAL;
6109 goto out;
6110 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006111 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
6112 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02006113
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006114 if (curproxy->conf.logformat_string == default_http_log_format)
6115 oldlogformat = "option httplog";
6116 else if (curproxy->conf.logformat_string == default_tcp_log_format)
6117 oldlogformat = "option tcplog";
6118 else if (curproxy->conf.logformat_string == clf_http_log_format)
6119 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01006120 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
6121 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02006122 }
Willy Tarreau62a61232013-04-12 18:13:46 +02006123 if (curproxy->conf.logformat_string != default_http_log_format &&
6124 curproxy->conf.logformat_string != default_tcp_log_format &&
6125 curproxy->conf.logformat_string != clf_http_log_format)
6126 free(curproxy->conf.logformat_string);
6127 curproxy->conf.logformat_string = strdup(args[1]);
6128
6129 free(curproxy->conf.lfs_file);
6130 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
6131 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006132
6133 /* get a chance to improve log-format error reporting by
6134 * reporting the correct line-number when possible.
6135 */
6136 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006137 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
6138 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02006139 err_code |= ERR_WARN;
6140 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006141 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006142 else if (!strcmp(args[0], "log-format-sd")) {
6143 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006144 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006145 err_code |= ERR_ALERT | ERR_FATAL;
6146 goto out;
6147 }
6148 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006149 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 +02006150 err_code |= ERR_ALERT | ERR_FATAL;
6151 goto out;
6152 }
6153
6154 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
6155 free(curproxy->conf.logformat_sd_string);
6156 curproxy->conf.logformat_sd_string = strdup(args[1]);
6157
6158 free(curproxy->conf.lfsd_file);
6159 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
6160 curproxy->conf.lfsd_line = curproxy->conf.args.line;
6161
6162 /* get a chance to improve log-format-sd error reporting by
6163 * reporting the correct line-number when possible.
6164 */
6165 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006166 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
6167 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02006168 err_code |= ERR_WARN;
6169 }
6170 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01006171 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
6172 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006173 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 +01006174 err_code |= ERR_ALERT | ERR_FATAL;
6175 goto out;
6176 }
Dragan Dosen43885c72015-10-01 13:18:13 +02006177 chunk_destroy(&curproxy->log_tag);
6178 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01006179 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02006180 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
6181 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
6182 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006183 err_code |= ERR_ALERT | ERR_FATAL;
6184 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006185 }
6186 }
6187 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006188 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006189 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01006190 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006191 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006192
Willy Tarreau977b8e42006-12-29 14:19:17 +01006193 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006194 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006195
Willy Tarreaubaaee002006-06-26 02:48:02 +02006196 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006197 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
6198 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02006199 err_code |= ERR_ALERT | ERR_FATAL;
6200 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006201 }
Willy Tarreau368480c2009-03-01 08:27:21 +01006202
6203 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01006204 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6205 free(curproxy->conn_src.iface_name);
6206 curproxy->conn_src.iface_name = NULL;
6207 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01006208
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006209 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006210 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006211 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6212 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006213 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006214 goto out;
6215 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006216
6217 proto = protocol_by_family(sk->ss_family);
6218 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006219 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6220 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006221 err_code |= ERR_ALERT | ERR_FATAL;
6222 goto out;
6223 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006224
6225 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006226 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6227 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006228 err_code |= ERR_ALERT | ERR_FATAL;
6229 goto out;
6230 }
6231
Willy Tarreauef9a3602012-12-08 22:29:20 +01006232 curproxy->conn_src.source_addr = *sk;
6233 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006234
6235 cur_arg = 2;
6236 while (*(args[cur_arg])) {
6237 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02006238#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006239 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006240 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
6241 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006242 err_code |= ERR_ALERT | ERR_FATAL;
6243 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006244 }
6245
6246 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006247 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6248 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006249 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01006250 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6251 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02006252 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
6253 char *name, *end;
6254
6255 name = args[cur_arg+1] + 7;
6256 while (isspace(*name))
6257 name++;
6258
6259 end = name;
6260 while (*end && !isspace(*end) && *end != ',' && *end != ')')
6261 end++;
6262
Willy Tarreauef9a3602012-12-08 22:29:20 +01006263 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
6264 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
6265 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
6266 curproxy->conn_src.bind_hdr_len = end - name;
6267 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
6268 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
6269 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02006270
6271 /* now look for an occurrence number */
6272 while (isspace(*end))
6273 end++;
6274 if (*end == ',') {
6275 end++;
6276 name = end;
6277 if (*end == '-')
6278 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01006279 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02006280 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01006281 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02006282 }
6283
Willy Tarreauef9a3602012-12-08 22:29:20 +01006284 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006285 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
6286 " occurrences values smaller than %d.\n",
6287 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02006288 err_code |= ERR_ALERT | ERR_FATAL;
6289 goto out;
6290 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006291 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01006292 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006293
Willy Tarreau48ef4c92017-01-06 18:32:38 +01006294 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006295 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006296 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
6297 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006298 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006299 goto out;
6300 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006301
6302 proto = protocol_by_family(sk->ss_family);
6303 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006304 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
6305 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006306 err_code |= ERR_ALERT | ERR_FATAL;
6307 goto out;
6308 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01006309
Willy Tarreau6d03cc32013-02-20 17:26:02 +01006310 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006311 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
6312 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01006313 err_code |= ERR_ALERT | ERR_FATAL;
6314 goto out;
6315 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006316 curproxy->conn_src.tproxy_addr = *sk;
6317 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006318 }
6319 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006320#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006321 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
6322 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006323 err_code |= ERR_ALERT | ERR_FATAL;
6324 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006325#endif
6326 cur_arg += 2;
6327 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01006328 }
6329
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006330 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
6331#ifdef SO_BINDTODEVICE
6332 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006333 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
6334 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006335 err_code |= ERR_ALERT | ERR_FATAL;
6336 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006337 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01006338 free(curproxy->conn_src.iface_name);
6339 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
6340 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006341 global.last_checks |= LSTCHK_NETADM;
6342#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006343 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
6344 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02006345 err_code |= ERR_ALERT | ERR_FATAL;
6346 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01006347#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01006348 cur_arg += 2;
6349 continue;
6350 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01006351 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
6352 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02006353 err_code |= ERR_ALERT | ERR_FATAL;
6354 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006355 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006356 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006357 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01006358 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
6359 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02006360 err_code |= ERR_ALERT | ERR_FATAL;
6361 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01006362 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006363 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006364 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006365 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6366 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006367 err_code |= ERR_ALERT | ERR_FATAL;
6368 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006369 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006370
6371 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006372 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006373 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006374 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006375 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006376 }
6377 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006378 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006379 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006380 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006381 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006382 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006383 }
6384 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006385 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006386 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006387 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006388 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006389 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006390 }
6391 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006392 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006393 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006394 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006395 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006396 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006397 }
6398 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006399 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006400 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006401 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006402 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006403 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006404 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006405 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006406 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006407 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01006408 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006409 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006410 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02006411 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006412 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006413 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006414 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6415 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006416 err_code |= ERR_ALERT | ERR_FATAL;
6417 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006418 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01006419
6420 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006421 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006422 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006423 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006424 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006425 }
6426 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006427 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006428 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006429 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006430 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006431 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006432 }
6433 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006434 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006435 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006436 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006437 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006438 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006439 }
6440 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006441 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006442 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006443 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006444 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006445 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006446 }
6447 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006448 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006449 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01006450 args[0], args[1], NULL, (const char **)args+2);
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 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02006454 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
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_TARPIT, REG_ICASE,
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 Tarreaub8750a82006-09-03 09:56:00 +02006460 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006461 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006462 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006463
Willy Tarreaubaaee002006-06-26 02:48:02 +02006464 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006465 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006466 err_code |= ERR_ALERT | ERR_FATAL;
6467 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006468 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006469 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006470 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006471
Willy Tarreaubaaee002006-06-26 02:48:02 +02006472 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006473 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006474 err_code |= ERR_ALERT | ERR_FATAL;
6475 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006476 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006477
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006478 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006479 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006480 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6481 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006482 err_code |= ERR_ALERT | ERR_FATAL;
6483 goto out;
6484 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006485 err_code |= warnif_cond_conflicts(cond,
6486 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
6487 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006488 }
6489 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006490 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6491 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006492 err_code |= ERR_ALERT | ERR_FATAL;
6493 goto out;
6494 }
6495
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006496 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01006497 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006498 wl->s = strdup(args[1]);
6499 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02006500 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006501 }
6502 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006503 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006504 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6505 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006506 err_code |= ERR_ALERT | ERR_FATAL;
6507 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006508 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01006509
Willy Tarreauade5ec42010-01-28 19:33:49 +01006510 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006511 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006512 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006513 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006514 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006515 }
6516 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006517 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006518 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006519 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006520 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006521 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006522 }
6523 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006524 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006525 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006526 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006527 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006528 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006529 }
6530 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006531 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006532 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
6533 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006534 err_code |= ERR_ALERT | ERR_FATAL;
6535 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006536 }
6537
Willy Tarreauade5ec42010-01-28 19:33:49 +01006538 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006539 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006540 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006541 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006542 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006543 }
6544 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006545 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006546 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006547 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006548 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006549 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006550 }
6551 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01006552 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02006553 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006554 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01006555 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02006556 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006557 }
6558 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01006559 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006560
Willy Tarreaubaaee002006-06-26 02:48:02 +02006561 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006562 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006563 err_code |= ERR_ALERT | ERR_FATAL;
6564 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006565 }
Christopher Faulet898566e2016-10-26 11:06:28 +02006566 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006567 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006568
Willy Tarreaubaaee002006-06-26 02:48:02 +02006569 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006570 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006571 err_code |= ERR_ALERT | ERR_FATAL;
6572 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006573 }
6574
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006575 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02006576 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006577 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
6578 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006579 err_code |= ERR_ALERT | ERR_FATAL;
6580 goto out;
6581 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01006582 err_code |= warnif_cond_conflicts(cond,
6583 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
6584 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006585 }
6586 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006587 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
6588 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006589 err_code |= ERR_ALERT | ERR_FATAL;
6590 goto out;
6591 }
6592
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006593 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01006594 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01006595 wl->s = strdup(args[1]);
6596 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006597 }
6598 else if (!strcmp(args[0], "errorloc") ||
6599 !strcmp(args[0], "errorloc302") ||
6600 !strcmp(args[0], "errorloc303")) { /* error location */
6601 int errnum, errlen;
6602 char *err;
6603
Willy Tarreau977b8e42006-12-29 14:19:17 +01006604 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02006605 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01006606
Willy Tarreaubaaee002006-06-26 02:48:02 +02006607 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006608 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 +02006609 err_code |= ERR_ALERT | ERR_FATAL;
6610 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006611 }
6612
6613 errnum = atol(args[1]);
6614 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006615 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
6616 err = malloc(errlen);
6617 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006618 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02006619 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
6620 err = malloc(errlen);
6621 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006622 }
6623
Willy Tarreau0f772532006-12-23 20:51:41 +01006624 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6625 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006626 chunk_destroy(&curproxy->errmsg[rc]);
6627 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01006628 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006629 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006630 }
Willy Tarreau0f772532006-12-23 20:51:41 +01006631
6632 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006633 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
6634 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006635 free(err);
6636 }
6637 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02006638 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
6639 int errnum, errlen, fd;
6640 char *err;
6641 struct stat stat;
6642
6643 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 Tarreau3f49b302007-06-11 00:29:26 +02006645
6646 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006647 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 +02006648 err_code |= ERR_ALERT | ERR_FATAL;
6649 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006650 }
6651
6652 fd = open(args[2], O_RDONLY);
6653 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006654 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
6655 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006656 if (fd >= 0)
6657 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02006658 err_code |= ERR_ALERT | ERR_FATAL;
6659 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006660 }
6661
Willy Tarreau27a674e2009-08-17 07:23:33 +02006662 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02006663 errlen = stat.st_size;
6664 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006665 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
6666 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02006667 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02006668 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006669 }
6670
6671 err = malloc(errlen); /* malloc() must succeed during parsing */
6672 errnum = read(fd, err, errlen);
6673 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006674 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
6675 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006676 close(fd);
6677 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02006678 err_code |= ERR_ALERT | ERR_FATAL;
6679 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006680 }
6681 close(fd);
6682
6683 errnum = atol(args[1]);
6684 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
6685 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02006686 chunk_destroy(&curproxy->errmsg[rc]);
6687 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02006688 break;
6689 }
6690 }
6691
6692 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006693 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
6694 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02006695 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02006696 free(err);
6697 }
6698 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006699 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006700 struct cfg_kw_list *kwl;
6701 int index;
6702
6703 list_for_each_entry(kwl, &cfg_keywords.list, list) {
6704 for (index = 0; kwl->kw[index].kw != NULL; index++) {
6705 if (kwl->kw[index].section != CFG_LISTEN)
6706 continue;
6707 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
6708 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02006709 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02006710 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006711 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006712 err_code |= ERR_ALERT | ERR_FATAL;
6713 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006714 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02006715 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006716 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006717 err_code |= ERR_WARN;
6718 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02006719 }
Willy Tarreau93893792009-07-23 13:19:11 +02006720 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02006721 }
6722 }
6723 }
William Lallemand82fe75c2012-10-23 10:25:10 +02006724
Christopher Faulet767a84b2017-11-24 16:50:31 +01006725 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02006726 err_code |= ERR_ALERT | ERR_FATAL;
6727 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006728 }
Willy Tarreau93893792009-07-23 13:19:11 +02006729 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02006730 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02006731 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006732}
6733
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006734int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006735cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
6736{
6737#ifdef CONFIG_HAP_NS
6738 const char *err;
6739 const char *item = args[0];
6740
6741 if (!strcmp(item, "namespace_list")) {
6742 return 0;
6743 }
6744 else if (!strcmp(item, "namespace")) {
6745 size_t idx = 1;
6746 const char *current;
6747 while (*(current = args[idx++])) {
6748 err = invalid_char(current);
6749 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006750 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6751 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006752 return ERR_ALERT | ERR_FATAL;
6753 }
6754
6755 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006756 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
6757 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006758 return ERR_ALERT | ERR_FATAL;
6759 }
6760 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006761 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
6762 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006763 return ERR_ALERT | ERR_FATAL;
6764 }
6765 }
6766 }
6767
6768 return 0;
6769#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006770 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
6771 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01006772 return ERR_ALERT | ERR_FATAL;
6773#endif
6774}
6775
6776int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006777cfg_parse_users(const char *file, int linenum, char **args, int kwm)
6778{
6779
6780 int err_code = 0;
6781 const char *err;
6782
6783 if (!strcmp(args[0], "userlist")) { /* new userlist */
6784 struct userlist *newul;
6785
6786 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006787 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6788 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006789 err_code |= ERR_ALERT | ERR_FATAL;
6790 goto out;
6791 }
William Lallemand6e62fb62015-04-28 16:55:23 +02006792 if (alertif_too_many_args(1, file, linenum, args, &err_code))
6793 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006794
6795 err = invalid_char(args[1]);
6796 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006797 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6798 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006799 err_code |= ERR_ALERT | ERR_FATAL;
6800 goto out;
6801 }
6802
6803 for (newul = userlist; newul; newul = newul->next)
6804 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006805 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
6806 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006807 err_code |= ERR_WARN;
6808 goto out;
6809 }
6810
Vincent Bernat02779b62016-04-03 13:48:43 +02006811 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006812 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006813 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006814 err_code |= ERR_ALERT | ERR_ABORT;
6815 goto out;
6816 }
6817
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006818 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006819 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006820 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006821 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01006822 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006823 goto out;
6824 }
6825
6826 newul->next = userlist;
6827 userlist = newul;
6828
6829 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006830 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006831 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006832 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006833
6834 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006835 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6836 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006837 err_code |= ERR_ALERT | ERR_FATAL;
6838 goto out;
6839 }
6840
6841 err = invalid_char(args[1]);
6842 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006843 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
6844 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006845 err_code |= ERR_ALERT | ERR_FATAL;
6846 goto out;
6847 }
6848
William Lallemand4ac9f542015-05-28 18:03:51 +02006849 if (!userlist)
6850 goto out;
6851
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006852 for (ag = userlist->groups; ag; ag = ag->next)
6853 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006854 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
6855 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006856 err_code |= ERR_ALERT;
6857 goto out;
6858 }
6859
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006860 ag = calloc(1, sizeof(*ag));
6861 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006862 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006863 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006864 goto out;
6865 }
6866
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006867 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01006868 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006869 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006870 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01006871 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006872 goto out;
6873 }
6874
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006875 cur_arg = 2;
6876
6877 while (*args[cur_arg]) {
6878 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006879 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006880 cur_arg += 2;
6881 continue;
6882 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006883 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
6884 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006885 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01006886 free(ag->groupusers);
6887 free(ag->name);
6888 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006889 goto out;
6890 }
6891 }
6892
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006893 ag->next = userlist->groups;
6894 userlist->groups = ag;
6895
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006896 } else if (!strcmp(args[0], "user")) { /* new user */
6897 struct auth_users *newuser;
6898 int cur_arg;
6899
6900 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006901 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
6902 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006903 err_code |= ERR_ALERT | ERR_FATAL;
6904 goto out;
6905 }
William Lallemand4ac9f542015-05-28 18:03:51 +02006906 if (!userlist)
6907 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006908
6909 for (newuser = userlist->users; newuser; newuser = newuser->next)
6910 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006911 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
6912 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006913 err_code |= ERR_ALERT;
6914 goto out;
6915 }
6916
Vincent Bernat02779b62016-04-03 13:48:43 +02006917 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006918 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006919 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006920 err_code |= ERR_ALERT | ERR_ABORT;
6921 goto out;
6922 }
6923
6924 newuser->user = strdup(args[1]);
6925
6926 newuser->next = userlist->users;
6927 userlist->users = newuser;
6928
6929 cur_arg = 2;
6930
6931 while (*args[cur_arg]) {
6932 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006933#ifdef CONFIG_HAP_CRYPT
6934 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006935 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
6936 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02006937 err_code |= ERR_ALERT | ERR_FATAL;
6938 goto out;
6939 }
6940#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01006941 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
6942 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006943 err_code |= ERR_ALERT;
6944#endif
6945 newuser->pass = strdup(args[cur_arg + 1]);
6946 cur_arg += 2;
6947 continue;
6948 } else if (!strcmp(args[cur_arg], "insecure-password")) {
6949 newuser->pass = strdup(args[cur_arg + 1]);
6950 newuser->flags |= AU_O_INSECURE;
6951 cur_arg += 2;
6952 continue;
6953 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006954 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006955 cur_arg += 2;
6956 continue;
6957 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006958 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
6959 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01006960 err_code |= ERR_ALERT | ERR_FATAL;
6961 goto out;
6962 }
6963 }
6964 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006965 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 +01006966 err_code |= ERR_ALERT | ERR_FATAL;
6967 }
6968
6969out:
6970 return err_code;
6971}
Willy Tarreaubaaee002006-06-26 02:48:02 +02006972
Christopher Faulet79bdef32016-11-04 22:36:15 +01006973int
6974cfg_parse_scope(const char *file, int linenum, char *line)
6975{
6976 char *beg, *end, *scope = NULL;
6977 int err_code = 0;
6978 const char *err;
6979
6980 beg = line + 1;
6981 end = strchr(beg, ']');
6982
6983 /* Detect end of scope declaration */
6984 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006985 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
6986 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006987 err_code |= ERR_ALERT | ERR_FATAL;
6988 goto out;
6989 }
6990
6991 /* Get scope name and check its validity */
6992 scope = my_strndup(beg, end-beg);
6993 err = invalid_char(scope);
6994 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006995 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
6996 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01006997 err_code |= ERR_ALERT | ERR_ABORT;
6998 goto out;
6999 }
7000
7001 /* Be sure to have a scope declaration alone on its line */
7002 line = end+1;
7003 while (isspace((unsigned char)*line))
7004 line++;
7005 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007006 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
7007 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01007008 err_code |= ERR_ALERT | ERR_ABORT;
7009 goto out;
7010 }
7011
7012 /* We have a valid scope declaration, save it */
7013 free(cfg_scope);
7014 cfg_scope = scope;
7015 scope = NULL;
7016
7017 out:
7018 free(scope);
7019 return err_code;
7020}
7021
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01007022int
7023cfg_parse_track_sc_num(unsigned int *track_sc_num,
7024 const char *arg, const char *end, char **errmsg)
7025{
7026 const char *p;
7027 unsigned int num;
7028
7029 p = arg;
7030 num = read_uint64(&arg, end);
7031
7032 if (arg != end) {
7033 memprintf(errmsg, "Wrong track-sc number '%s'", p);
7034 return -1;
7035 }
7036
7037 if (num >= MAX_SESS_STKCTR) {
7038 memprintf(errmsg, "%u track-sc number exceeding "
7039 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
7040 return -1;
7041 }
7042
7043 *track_sc_num = num;
7044 return 0;
7045}
7046
Willy Tarreaubaaee002006-06-26 02:48:02 +02007047/*
7048 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02007049 * Returns the error code, 0 if OK, or any combination of :
7050 * - ERR_ABORT: must abort ASAP
7051 * - ERR_FATAL: we can continue parsing but not start the service
7052 * - ERR_WARN: a warning has been emitted
7053 * - ERR_ALERT: an alert has been emitted
7054 * Only the two first ones can stop processing, the two others are just
7055 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02007056 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02007057int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02007058{
William Lallemand64e84512015-05-12 14:25:37 +02007059 char *thisline;
7060 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007061 FILE *f;
7062 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02007063 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007064 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007065 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02007066 int readbytes = 0;
7067
7068 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007069 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02007070 return -1;
7071 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007072
David Carlier97880bb2016-04-08 10:35:26 +01007073 if ((f=fopen(file,"r")) == NULL) {
7074 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007075 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01007076 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007077
William Lallemandb2f07452015-05-12 14:27:13 +02007078next_line:
William Lallemand64e84512015-05-12 14:25:37 +02007079 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02007080 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007081 char *end;
7082 char *args[MAX_LINE_ARGS + 1];
7083 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02007084 int dquote = 0; /* double quote */
7085 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007086
Willy Tarreaubaaee002006-06-26 02:48:02 +02007087 linenum++;
7088
7089 end = line + strlen(line);
7090
William Lallemand64e84512015-05-12 14:25:37 +02007091 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007092 /* Check if we reached the limit and the last char is not \n.
7093 * Watch out for the last line without the terminating '\n'!
7094 */
William Lallemand64e84512015-05-12 14:25:37 +02007095 char *newline;
7096 int newlinesize = linesize * 2;
7097
7098 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
7099 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007100 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
7101 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02007102 err_code |= ERR_ALERT | ERR_FATAL;
7103 continue;
7104 }
7105
7106 readbytes = linesize - 1;
7107 linesize = newlinesize;
7108 thisline = newline;
7109 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007110 }
7111
William Lallemand64e84512015-05-12 14:25:37 +02007112 readbytes = 0;
7113
Willy Tarreaubaaee002006-06-26 02:48:02 +02007114 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007115 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007116 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02007117
Christopher Faulet79bdef32016-11-04 22:36:15 +01007118
7119 if (*line == '[') {/* This is the begining if a scope */
7120 err_code |= cfg_parse_scope(file, linenum, line);
7121 goto next_line;
7122 }
7123
Willy Tarreaubaaee002006-06-26 02:48:02 +02007124 arg = 0;
7125 args[arg] = line;
7126
7127 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02007128 if (*line == '"' && !squote) { /* double quote outside single quotes */
7129 if (dquote)
7130 dquote = 0;
7131 else
7132 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007133 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007134 end--;
7135 }
7136 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
7137 if (squote)
7138 squote = 0;
7139 else
7140 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02007141 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02007142 end--;
7143 }
7144 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007145 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
7146 * C equivalent value. Other combinations left unchanged (eg: \1).
7147 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007148 int skip = 0;
7149 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
7150 *line = line[1];
7151 skip = 1;
7152 }
7153 else if (line[1] == 'r') {
7154 *line = '\r';
7155 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02007156 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007157 else if (line[1] == 'n') {
7158 *line = '\n';
7159 skip = 1;
7160 }
7161 else if (line[1] == 't') {
7162 *line = '\t';
7163 skip = 1;
7164 }
7165 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01007166 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007167 unsigned char hex1, hex2;
7168 hex1 = toupper(line[2]) - '0';
7169 hex2 = toupper(line[3]) - '0';
7170 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
7171 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
7172 *line = (hex1<<4) + hex2;
7173 skip = 3;
7174 }
7175 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007176 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007177 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007178 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007179 } else if (line[1] == '"') {
7180 *line = '"';
7181 skip = 1;
7182 } else if (line[1] == '\'') {
7183 *line = '\'';
7184 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02007185 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
7186 *line = '$';
7187 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007188 }
7189 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01007190 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02007191 end -= skip;
7192 }
7193 line++;
7194 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007195 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007196 /* end of string, end of loop */
7197 *line = 0;
7198 break;
7199 }
William Lallemandf9873ba2015-05-05 17:37:14 +02007200 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007201 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01007202 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02007203 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02007204 line++;
7205 args[++arg] = line;
7206 }
William Lallemandb2f07452015-05-12 14:27:13 +02007207 else if (dquote && *line == '$') {
7208 /* environment variables are evaluated inside double quotes */
7209 char *var_beg;
7210 char *var_end;
7211 char save_char;
7212 char *value;
7213 int val_len;
7214 int newlinesize;
7215 int braces = 0;
7216
7217 var_beg = line + 1;
7218 var_end = var_beg;
7219
7220 if (*var_beg == '{') {
7221 var_beg++;
7222 var_end++;
7223 braces = 1;
7224 }
7225
7226 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007227 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 +02007228 err_code |= ERR_ALERT | ERR_FATAL;
7229 goto next_line; /* skip current line */
7230 }
7231
7232 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
7233 var_end++;
7234
7235 save_char = *var_end;
7236 *var_end = '\0';
7237 value = getenv(var_beg);
7238 *var_end = save_char;
7239 val_len = value ? strlen(value) : 0;
7240
7241 if (braces) {
7242 if (*var_end == '}') {
7243 var_end++;
7244 braces = 0;
7245 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007246 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007247 err_code |= ERR_ALERT | ERR_FATAL;
7248 goto next_line; /* skip current line */
7249 }
7250 }
7251
7252 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
7253
7254 /* if not enough space in thisline */
7255 if (newlinesize > linesize) {
7256 char *newline;
7257
7258 newline = realloc(thisline, newlinesize * sizeof(*thisline));
7259 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007260 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02007261 err_code |= ERR_ALERT | ERR_FATAL;
7262 goto next_line; /* slip current line */
7263 }
7264 /* recompute pointers if realloc returns a new pointer */
7265 if (newline != thisline) {
7266 int i;
7267 int diff;
7268
7269 for (i = 0; i <= arg; i++) {
7270 diff = args[i] - thisline;
7271 args[i] = newline + diff;
7272 }
7273
7274 diff = var_end - thisline;
7275 var_end = newline + diff;
7276 diff = end - thisline;
7277 end = newline + diff;
7278 diff = line - thisline;
7279 line = newline + diff;
7280 thisline = newline;
7281 }
7282 linesize = newlinesize;
7283 }
7284
7285 /* insert value inside the line */
7286 memmove(line + val_len, var_end, end - var_end + 1);
7287 memcpy(line, value, val_len);
7288 end += val_len - (var_end - line);
7289 line += val_len;
7290 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007291 else {
7292 line++;
7293 }
7294 }
William Lallemandb2f07452015-05-12 14:27:13 +02007295
William Lallemandf9873ba2015-05-05 17:37:14 +02007296 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007297 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007298 err_code |= ERR_ALERT | ERR_FATAL;
7299 }
7300
7301 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007302 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02007303 err_code |= ERR_ALERT | ERR_FATAL;
7304 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007305
7306 /* empty line */
7307 if (!**args)
7308 continue;
7309
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007310 if (*line) {
7311 /* we had to stop due to too many args.
7312 * Let's terminate the string, print the offending part then cut the
7313 * last arg.
7314 */
7315 while (*line && *line != '#' && *line != '\n' && *line != '\r')
7316 line++;
7317 *line = '\0';
7318
Christopher Faulet767a84b2017-11-24 16:50:31 +01007319 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
7320 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01007321 err_code |= ERR_ALERT | ERR_FATAL;
7322 args[arg] = line;
7323 }
7324
Willy Tarreau540abe42007-05-02 20:50:16 +02007325 /* zero out remaining args and ensure that at least one entry
7326 * is zeroed out.
7327 */
7328 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02007329 args[arg] = line;
7330 }
7331
Willy Tarreau3842f002009-06-14 11:39:52 +02007332 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007333 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02007334 char *tmp;
7335
Willy Tarreau3842f002009-06-14 11:39:52 +02007336 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02007337 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007338 for (arg=0; *args[arg+1]; arg++)
7339 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02007340 *tmp = '\0'; // fix the next arg to \0
7341 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007342 }
Willy Tarreau3842f002009-06-14 11:39:52 +02007343 else if (!strcmp(args[0], "default")) {
7344 kwm = KWM_DEF;
7345 for (arg=0; *args[arg+1]; arg++)
7346 args[arg] = args[arg+1]; // shift args after inversion
7347 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007348
William Lallemand0f99e342011-10-12 17:50:54 +02007349 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
7350 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007351 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02007352 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007353 }
7354
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01007355 /* detect section start */
7356 list_for_each_entry(ics, &sections, list) {
7357 if (strcmp(args[0], ics->section_name) == 0) {
7358 cursection = ics->section_name;
7359 cs = ics;
7360 break;
7361 }
Emeric Brun32da3c42010-09-23 18:39:19 +02007362 }
7363
William Lallemandd2ff56d2017-10-16 11:06:50 +02007364 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007365 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02007366 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02007367 } else {
7368 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02007369
William Lallemandd2ff56d2017-10-16 11:06:50 +02007370 if (pcs != cs && pcs && pcs->post_section_parser) {
7371 err_code |= pcs->post_section_parser();
7372 if (err_code & ERR_ABORT)
7373 goto err;
7374 }
7375
7376 err_code |= cs->section_parser(file, linenum, args, kwm);
7377 if (err_code & ERR_ABORT)
7378 goto err;
7379 }
7380 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007381 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02007382
7383 if (pcs == cs && pcs && pcs->post_section_parser)
7384 err_code |= pcs->post_section_parser();
7385
7386err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01007387 free(cfg_scope);
7388 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01007389 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02007390 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007391 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02007392 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007393}
7394
Willy Tarreau64ab6072014-09-16 12:17:36 +02007395/* This function propagates processes from frontend <from> to backend <to> so
7396 * that it is always guaranteed that a backend pointed to by a frontend is
7397 * bound to all of its processes. After that, if the target is a "listen"
7398 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02007399 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02007400 * checked first to ensure that <to> is already bound to all processes of
7401 * <from>, there is no risk of looping and we ensure to follow the shortest
7402 * path to the destination.
7403 *
7404 * It is possible to set <to> to NULL for the first call so that the function
7405 * takes care of visiting the initial frontend in <from>.
7406 *
7407 * It is important to note that the function relies on the fact that all names
7408 * have already been resolved.
7409 */
7410void propagate_processes(struct proxy *from, struct proxy *to)
7411{
7412 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007413
7414 if (to) {
7415 /* check whether we need to go down */
7416 if (from->bind_proc &&
7417 (from->bind_proc & to->bind_proc) == from->bind_proc)
7418 return;
7419
7420 if (!from->bind_proc && !to->bind_proc)
7421 return;
7422
7423 to->bind_proc = from->bind_proc ?
7424 (to->bind_proc | from->bind_proc) : 0;
7425
7426 /* now propagate down */
7427 from = to;
7428 }
7429
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01007430 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02007431 return;
7432
Willy Tarreauf6b70012014-12-18 14:00:43 +01007433 if (from->state == PR_STSTOPPED)
7434 return;
7435
Willy Tarreau64ab6072014-09-16 12:17:36 +02007436 /* default_backend */
7437 if (from->defbe.be)
7438 propagate_processes(from, from->defbe.be);
7439
7440 /* use_backend */
7441 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02007442 if (rule->dynamic)
7443 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02007444 to = rule->be.backend;
7445 propagate_processes(from, to);
7446 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02007447}
7448
Willy Tarreaubb925012009-07-23 13:36:36 +02007449/*
7450 * Returns the error code, 0 if OK, or any combination of :
7451 * - ERR_ABORT: must abort ASAP
7452 * - ERR_FATAL: we can continue parsing but not start the service
7453 * - ERR_WARN: a warning has been emitted
7454 * - ERR_ALERT: an alert has been emitted
7455 * Only the two first ones can stop processing, the two others are just
7456 * indicators.
7457 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007458int check_config_validity()
7459{
7460 int cfgerr = 0;
7461 struct proxy *curproxy = NULL;
7462 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02007463 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007464 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007465 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007466 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02007467 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06007468 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007469
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007470 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007471 /*
7472 * Now, check for the integrity of all that we have collected.
7473 */
7474
7475 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02007476 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007477
Willy Tarreau193b8c62012-11-22 00:17:38 +01007478 if (!global.tune.max_http_hdr)
7479 global.tune.max_http_hdr = MAX_HTTP_HDR;
7480
7481 if (!global.tune.cookie_len)
7482 global.tune.cookie_len = CAPTURE_LEN;
7483
Stéphane Cottin23e9e932017-05-18 08:58:41 +02007484 if (!global.tune.requri_len)
7485 global.tune.requri_len = REQURI_LEN;
7486
Willy Tarreaubafbe012017-11-24 17:34:44 +01007487 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02007488
Willy Tarreaubafbe012017-11-24 17:34:44 +01007489 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007490
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007491 /* Post initialisation of the users and groups lists. */
7492 err_code = userlist_postinit();
7493 if (err_code != ERR_NONE)
7494 goto out;
7495
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007496 /* first, we will invert the proxy list order */
7497 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007498 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007499 struct proxy *next;
7500
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007501 next = proxies_list->next;
7502 proxies_list->next = curproxy;
7503 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007504 if (!next)
7505 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007506 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01007507 }
7508
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007509 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007510 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007511 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01007512 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007513 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02007514 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007515 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01007516 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007517
Willy Tarreau050536d2012-10-04 08:47:34 +02007518 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007519 /* proxy ID not set, use automatic numbering with first
7520 * spare entry starting with next_pxid.
7521 */
7522 next_pxid = get_next_id(&used_proxy_id, next_pxid);
7523 curproxy->conf.id.key = curproxy->uuid = next_pxid;
7524 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007525 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007526 next_pxid++;
7527
Willy Tarreau55ea7572007-06-17 19:56:27 +02007528
Willy Tarreaubaaee002006-06-26 02:48:02 +02007529 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02007530 /* ensure we don't keep listeners uselessly bound */
7531 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02007532 free((void *)curproxy->table.peers.name);
7533 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007534 continue;
7535 }
7536
Willy Tarreau102df612014-05-07 23:56:38 +02007537 /* Check multi-process mode compatibility for the current proxy */
7538
7539 if (curproxy->bind_proc) {
7540 /* an explicit bind-process was specified, let's check how many
7541 * processes remain.
7542 */
David Carliere6c39412015-07-02 07:00:17 +00007543 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02007544
7545 curproxy->bind_proc &= nbits(global.nbproc);
7546 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007547 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 +02007548 curproxy->bind_proc = 1;
7549 }
7550 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007551 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 +02007552 curproxy->bind_proc = 0;
7553 }
7554 }
7555
Willy Tarreau3d209582014-05-09 17:06:11 +02007556 /* check and reduce the bind-proc of each listener */
7557 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7558 unsigned long mask;
7559
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007560 /* HTTP frontends with "h2" as ALPN/NPN will work in
7561 * HTTP/2 and absolutely require buffers 16kB or larger.
7562 */
7563#ifdef USE_OPENSSL
7564 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
7565#ifdef OPENSSL_NPN_NEGOTIATED
7566 /* check NPN */
7567 if (bind_conf->ssl_conf.npn_str && strcmp(bind_conf->ssl_conf.npn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007568 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",
7569 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007570 cfgerr++;
7571 }
7572#endif
7573#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
7574 /* check ALPN */
7575 if (bind_conf->ssl_conf.alpn_str && strcmp(bind_conf->ssl_conf.alpn_str, "\002h2") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007576 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",
7577 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01007578 cfgerr++;
7579 }
7580#endif
7581 } /* HTTP && bufsize < 16384 */
7582#endif
7583
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007584 /* detect and address thread affinity inconsistencies */
7585 nbproc = 0;
7586 if (bind_conf->bind_proc)
7587 nbproc = my_ffsl(bind_conf->bind_proc);
7588
7589 mask = bind_conf->bind_thread[nbproc - 1];
Willy Tarreau0c026f42018-08-01 19:12:20 +02007590 if (mask && !(mask & all_threads_mask)) {
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007591 unsigned long new_mask = 0;
7592
7593 while (mask) {
Willy Tarreau0c026f42018-08-01 19:12:20 +02007594 new_mask |= mask & all_threads_mask;
Willy Tarreauc477b6f2018-07-27 18:07:41 +02007595 mask >>= global.nbthread;
7596 }
7597
7598 for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
7599 if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
7600 bind_conf->bind_thread[nbproc] = new_mask;
7601 }
7602 ha_warning("Proxy '%s': the thread range specified on the 'process' directive of 'bind %s' at [%s:%d] only refers to thread numbers out of the range defined by the global 'nbthread' directive. The thread numbers were remapped to existing threads instead (mask 0x%lx).\n",
7603 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
7604 }
7605
7606 /* detect process and nbproc affinity inconsistencies */
Willy Tarreau3d209582014-05-09 17:06:11 +02007607 if (!bind_conf->bind_proc)
7608 continue;
7609
7610 mask = nbits(global.nbproc);
7611 if (curproxy->bind_proc)
7612 mask &= curproxy->bind_proc;
7613 /* mask cannot be null here thanks to the previous checks */
7614
David Carliere6c39412015-07-02 07:00:17 +00007615 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02007616 bind_conf->bind_proc &= mask;
7617
7618 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007619 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",
7620 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007621 bind_conf->bind_proc = mask & ~(mask - 1);
7622 }
7623 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007624 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",
7625 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02007626 bind_conf->bind_proc = 0;
7627 }
7628 }
7629
Willy Tarreauff01a212009-03-15 13:46:16 +01007630 switch (curproxy->mode) {
7631 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007632 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007633 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007634 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
7635 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007636 cfgerr++;
7637 }
7638
7639 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007640 ha_warning("config : servers will be ignored for %s '%s'.\n",
7641 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01007642 break;
7643
7644 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02007645 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01007646 break;
7647
7648 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01007649 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01007650 break;
7651 }
7652
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01007653 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007654 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
7655 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02007656 err_code |= ERR_WARN;
7657 }
7658
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007659 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007660 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007661 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007662 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
7663 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007664 cfgerr++;
7665 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007666#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007667 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007668 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
7669 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007670 cfgerr++;
7671 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007672#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02007673 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007674 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
7675 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007676 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007677 }
7678 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02007679 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01007680 /* If no LB algo is set in a backend, and we're not in
7681 * transparent mode, dispatch mode nor proxy mode, we
7682 * want to use balance roundrobin by default.
7683 */
7684 curproxy->lbprm.algo &= ~BE_LB_ALGO;
7685 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02007686 }
7687 }
Willy Tarreau193cf932007-09-17 10:17:23 +02007688
Willy Tarreau1620ec32011-08-06 17:05:02 +02007689 if (curproxy->options & PR_O_DISPATCH)
7690 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
7691 else if (curproxy->options & PR_O_HTTP_PROXY)
7692 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
7693 else if (curproxy->options & PR_O_TRANSP)
7694 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01007695
Willy Tarreau1620ec32011-08-06 17:05:02 +02007696 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
7697 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007698 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7699 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007700 err_code |= ERR_WARN;
7701 curproxy->options &= ~PR_O_DISABLE404;
7702 }
7703 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007704 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
7705 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02007706 err_code |= ERR_WARN;
7707 curproxy->options &= ~PR_O2_CHK_SNDST;
7708 }
Willy Tarreauef781042010-01-27 11:53:01 +01007709 }
7710
Simon Horman98637e52014-06-20 12:30:16 +09007711 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
7712 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007713 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
7714 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007715 cfgerr++;
7716 }
7717 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007718 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
7719 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09007720 cfgerr++;
7721 }
7722 }
7723
Simon Horman64e34162015-02-06 11:11:57 +09007724 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007725 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007726 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
7727 "'email-alert from', 'email-alert level' 'email-alert mailers', "
7728 "'email-alert myhostname', or 'email-alert to' "
7729 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
7730 "to be present).\n",
7731 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09007732 err_code |= ERR_WARN;
7733 free_email_alert(curproxy);
7734 }
7735 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01007736 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09007737 }
7738
Simon Horman98637e52014-06-20 12:30:16 +09007739 if (curproxy->check_command) {
7740 int clear = 0;
7741 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007742 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7743 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007744 err_code |= ERR_WARN;
7745 clear = 1;
7746 }
7747 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007748 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
7749 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09007750 cfgerr++;
7751 }
7752 if (clear) {
7753 free(curproxy->check_command);
7754 curproxy->check_command = NULL;
7755 }
7756 }
7757
7758 if (curproxy->check_path) {
7759 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007760 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
7761 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09007762 err_code |= ERR_WARN;
7763 free(curproxy->check_path);
7764 curproxy->check_path = NULL;
7765 }
7766 }
7767
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007768 /* if a default backend was specified, let's find it */
7769 if (curproxy->defbe.name) {
7770 struct proxy *target;
7771
Willy Tarreauafb39922015-05-26 12:04:09 +02007772 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007773 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007774 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
7775 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007776 cfgerr++;
7777 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007778 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
7779 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02007780 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007781 } else if (target->mode != curproxy->mode &&
7782 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7783
Christopher Faulet767a84b2017-11-24 16:50:31 +01007784 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
7785 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7786 curproxy->conf.file, curproxy->conf.line,
7787 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7788 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007789 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01007790 } else {
7791 free(curproxy->defbe.name);
7792 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007793 /* Update tot_fe_maxconn for a further fullconn's computation */
7794 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01007795 /* Emit a warning if this proxy also has some servers */
7796 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007797 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
7798 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01007799 err_code |= ERR_WARN;
7800 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02007801 }
7802 }
7803
Emeric Brun3f783572017-01-12 11:21:28 +01007804 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
7805 /* Case of listen without default backend
7806 * The curproxy will be its own default backend
7807 * so we update tot_fe_maxconn for a further
7808 * fullconn's computation */
7809 curproxy->tot_fe_maxconn += curproxy->maxconn;
7810 }
7811
Willy Tarreau55ea7572007-06-17 19:56:27 +02007812 /* find the target proxy for 'use_backend' rules */
7813 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02007814 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007815 struct logformat_node *node;
7816 char *pxname;
7817
7818 /* Try to parse the string as a log format expression. If the result
7819 * of the parsing is only one entry containing a simple string, then
7820 * it's a standard string corresponding to a static rule, thus the
7821 * parsing is cancelled and be.name is restored to be resolved.
7822 */
7823 pxname = rule->be.name;
7824 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01007825 curproxy->conf.args.ctx = ARGC_UBK;
7826 curproxy->conf.args.file = rule->file;
7827 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007828 err = NULL;
7829 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007830 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
7831 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007832 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007833 cfgerr++;
7834 continue;
7835 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01007836 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
7837
7838 if (!LIST_ISEMPTY(&rule->be.expr)) {
7839 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
7840 rule->dynamic = 1;
7841 free(pxname);
7842 continue;
7843 }
7844 /* simple string: free the expression and fall back to static rule */
7845 free(node->arg);
7846 free(node);
7847 }
7848
7849 rule->dynamic = 0;
7850 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007851
Willy Tarreauafb39922015-05-26 12:04:09 +02007852 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01007853 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007854 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
7855 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007856 cfgerr++;
7857 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007858 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
7859 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02007860 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02007861 } else if (target->mode != curproxy->mode &&
7862 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
7863
Christopher Faulet767a84b2017-11-24 16:50:31 +01007864 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
7865 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
7866 curproxy->conf.file, curproxy->conf.line,
7867 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
7868 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02007869 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007870 } else {
7871 free((void *)rule->be.name);
7872 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01007873 /* For each target of switching rules, we update
7874 * their tot_fe_maxconn, except if a previous rule point
7875 * on the same backend or on the default backend */
7876 if (rule->be.backend != curproxy->defbe.be) {
7877 struct switching_rule *swrule;
7878
7879 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
7880 if (rule == swrule) {
7881 target->tot_fe_maxconn += curproxy->maxconn;
7882 break;
7883 }
7884 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
7885 /* there is multiple ref of this backend */
7886 break;
7887 }
7888 }
7889 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02007890 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007891 }
7892
Willy Tarreau64ab6072014-09-16 12:17:36 +02007893 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007894 list_for_each_entry(srule, &curproxy->server_rules, list) {
7895 struct server *target = findserver(curproxy, srule->srv.name);
7896
7897 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007898 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
7899 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02007900 cfgerr++;
7901 continue;
7902 }
7903 free((void *)srule->srv.name);
7904 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02007905 }
7906
Emeric Brunb982a3d2010-01-04 15:45:53 +01007907 /* find the target table for 'stick' rules */
7908 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
7909 struct proxy *target;
7910
Emeric Brun1d33b292010-01-04 15:47:17 +01007911 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
7912 if (mrule->flags & STK_IS_STORE)
7913 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7914
Emeric Brunb982a3d2010-01-04 15:45:53 +01007915 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007916 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007917 else
7918 target = curproxy;
7919
7920 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007921 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
7922 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007923 cfgerr++;
7924 }
7925 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007926 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7927 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007928 cfgerr++;
7929 }
Willy Tarreau12785782012-04-27 21:37:17 +02007930 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007931 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7932 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007933 cfgerr++;
7934 }
7935 else {
7936 free((void *)mrule->table.name);
7937 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007938 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007939 }
7940 }
7941
7942 /* find the target table for 'store response' rules */
7943 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
7944 struct proxy *target;
7945
Emeric Brun1d33b292010-01-04 15:47:17 +01007946 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
7947
Emeric Brunb982a3d2010-01-04 15:45:53 +01007948 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007949 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007950 else
7951 target = curproxy;
7952
7953 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007954 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
7955 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007956 cfgerr++;
7957 }
7958 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007959 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
7960 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007961 cfgerr++;
7962 }
Willy Tarreau12785782012-04-27 21:37:17 +02007963 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007964 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
7965 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007966 cfgerr++;
7967 }
7968 else {
7969 free((void *)mrule->table.name);
7970 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02007971 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01007972 }
7973 }
7974
Christopher Faulete4e830d2017-09-18 14:51:41 +02007975 /* check validity for 'tcp-request' layer 4 rules */
7976 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
7977 err = NULL;
7978 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007979 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007980 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01007981 cfgerr++;
7982 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02007983 }
7984
Christopher Faulete4e830d2017-09-18 14:51:41 +02007985 /* check validity for 'tcp-request' layer 5 rules */
7986 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
7987 err = NULL;
7988 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007989 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02007990 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01007991 cfgerr++;
7992 }
7993 }
7994
Christopher Faulete4e830d2017-09-18 14:51:41 +02007995 /* check validity for 'tcp-request' layer 6 rules */
7996 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
7997 err = NULL;
7998 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007999 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008000 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01008001 cfgerr++;
8002 }
8003 }
8004
Christopher Faulete4e830d2017-09-18 14:51:41 +02008005 /* check validity for 'http-request' layer 7 rules */
8006 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
8007 err = NULL;
8008 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008009 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008010 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008011 cfgerr++;
8012 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08008013 }
8014
Christopher Faulete4e830d2017-09-18 14:51:41 +02008015 /* check validity for 'http-response' layer 7 rules */
8016 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
8017 err = NULL;
8018 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008019 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02008020 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02008021 cfgerr++;
8022 }
Willy Tarreau09448f72014-06-25 18:12:15 +02008023 }
8024
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02008025 /* move any "block" rules at the beginning of the http-request rules */
8026 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
8027 /* insert block_rules into http_req_rules at the beginning */
8028 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
8029 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
8030 curproxy->block_rules.n->p = &curproxy->http_req_rules;
8031 curproxy->http_req_rules.n = curproxy->block_rules.n;
8032 LIST_INIT(&curproxy->block_rules);
8033 }
8034
Emeric Brun32da3c42010-09-23 18:39:19 +02008035 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008036 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008037
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02008038 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02008039 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
8040 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01008041 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02008042 break;
8043 }
8044 }
8045
8046 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008047 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
8048 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008049 free((void *)curproxy->table.peers.name);
8050 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008051 cfgerr++;
8052 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02008053 else if (curpeers->state == PR_STSTOPPED) {
8054 /* silently disable this peers section */
8055 curproxy->table.peers.p = NULL;
8056 }
Emeric Brun32da3c42010-09-23 18:39:19 +02008057 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008058 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
8059 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02008060 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02008061 cfgerr++;
8062 }
8063 }
8064
Simon Horman9dc49962015-01-30 11:22:59 +09008065
8066 if (curproxy->email_alert.mailers.name) {
8067 struct mailers *curmailers = mailers;
8068
8069 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02008070 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09008071 break;
Simon Horman9dc49962015-01-30 11:22:59 +09008072 }
Simon Horman9dc49962015-01-30 11:22:59 +09008073 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008074 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
8075 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09008076 free_email_alert(curproxy);
8077 cfgerr++;
8078 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02008079 else {
8080 err = NULL;
8081 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008082 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02008083 free(err);
8084 cfgerr++;
8085 }
8086 }
Simon Horman9dc49962015-01-30 11:22:59 +09008087 }
8088
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008089 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01008090 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008091 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008092 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
8093 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008094 cfgerr++;
8095 goto out_uri_auth_compat;
8096 }
8097
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008098 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008099 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02008100 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01008101 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008102
Willy Tarreau95fa4692010-02-01 13:05:50 +01008103 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
8104 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008105
8106 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008107 uri_auth_compat_req[i++] = "realm";
8108 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
8109 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008110
Willy Tarreau95fa4692010-02-01 13:05:50 +01008111 uri_auth_compat_req[i++] = "unless";
8112 uri_auth_compat_req[i++] = "{";
8113 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
8114 uri_auth_compat_req[i++] = "}";
8115 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008116
Willy Tarreauff011f22011-01-06 17:51:27 +01008117 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
8118 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01008119 cfgerr++;
8120 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008121 }
8122
Willy Tarreauff011f22011-01-06 17:51:27 +01008123 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01008124
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008125 if (curproxy->uri_auth->auth_realm) {
8126 free(curproxy->uri_auth->auth_realm);
8127 curproxy->uri_auth->auth_realm = NULL;
8128 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01008129
8130 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01008131 }
8132out_uri_auth_compat:
8133
Dragan Dosen43885c72015-10-01 13:18:13 +02008134 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02008135 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02008136 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
8137 if (!curproxy->conf.logformat_sd_string) {
8138 /* set the default logformat_sd_string */
8139 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
8140 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008141 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02008142 }
Dragan Dosen1322d092015-09-22 16:05:32 +02008143 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02008144
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008145 /* compile the log format */
8146 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02008147 if (curproxy->conf.logformat_string != default_http_log_format &&
8148 curproxy->conf.logformat_string != default_tcp_log_format &&
8149 curproxy->conf.logformat_string != clf_http_log_format)
8150 free(curproxy->conf.logformat_string);
8151 curproxy->conf.logformat_string = NULL;
8152 free(curproxy->conf.lfs_file);
8153 curproxy->conf.lfs_file = NULL;
8154 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008155
8156 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
8157 free(curproxy->conf.logformat_sd_string);
8158 curproxy->conf.logformat_sd_string = NULL;
8159 free(curproxy->conf.lfsd_file);
8160 curproxy->conf.lfsd_file = NULL;
8161 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008162 }
8163
Willy Tarreau62a61232013-04-12 18:13:46 +02008164 if (curproxy->conf.logformat_string) {
8165 curproxy->conf.args.ctx = ARGC_LOG;
8166 curproxy->conf.args.file = curproxy->conf.lfs_file;
8167 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008168 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008169 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008170 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008171 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
8172 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008173 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008174 cfgerr++;
8175 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008176 curproxy->conf.args.file = NULL;
8177 curproxy->conf.args.line = 0;
8178 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008179
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008180 if (curproxy->conf.logformat_sd_string) {
8181 curproxy->conf.args.ctx = ARGC_LOGSD;
8182 curproxy->conf.args.file = curproxy->conf.lfsd_file;
8183 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008184 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008185 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 +01008186 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008187 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8188 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008189 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008190 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008191 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008192 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
8193 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008194 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008195 cfgerr++;
8196 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008197 curproxy->conf.args.file = NULL;
8198 curproxy->conf.args.line = 0;
8199 }
8200
Willy Tarreau62a61232013-04-12 18:13:46 +02008201 if (curproxy->conf.uniqueid_format_string) {
8202 curproxy->conf.args.ctx = ARGC_UIF;
8203 curproxy->conf.args.file = curproxy->conf.uif_file;
8204 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008205 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008206 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 +01008207 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008208 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
8209 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01008210 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01008211 cfgerr++;
8212 }
Willy Tarreau62a61232013-04-12 18:13:46 +02008213 curproxy->conf.args.file = NULL;
8214 curproxy->conf.args.line = 0;
8215 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008216
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01008217 /* only now we can check if some args remain unresolved.
8218 * This must be done after the users and groups resolution.
8219 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02008220 cfgerr += smp_resolve_args(curproxy);
8221 if (!cfgerr)
8222 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01008223
Willy Tarreau2738a142006-07-08 17:28:09 +02008224 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008225 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02008226 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02008227 (!curproxy->timeout.connect ||
8228 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008229 ha_warning("config : missing timeouts for %s '%s'.\n"
8230 " | While not properly invalid, you will certainly encounter various problems\n"
8231 " | with such a configuration. To fix this, please ensure that all following\n"
8232 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
8233 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008234 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02008235 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02008236
Willy Tarreau1fa31262007-12-03 00:36:16 +01008237 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
8238 * We must still support older configurations, so let's find out whether those
8239 * parameters have been set or must be copied from contimeouts.
8240 */
8241 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008242 if (!curproxy->timeout.tarpit ||
8243 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008244 /* tarpit timeout not set. We search in the following order:
8245 * default.tarpit, curr.connect, default.connect.
8246 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008247 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008248 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008249 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008250 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008251 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008252 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008253 }
8254 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008255 (!curproxy->timeout.queue ||
8256 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01008257 /* queue timeout not set. We search in the following order:
8258 * default.queue, curr.connect, default.connect.
8259 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008260 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01008261 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008262 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008263 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02008264 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01008265 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01008266 }
8267 }
8268
Willy Tarreau1620ec32011-08-06 17:05:02 +02008269 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01008270 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02008271 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01008272 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02008273 }
8274
Willy Tarreau215663d2014-06-13 18:30:23 +02008275 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
8276 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008277 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
8278 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02008279 err_code |= ERR_WARN;
8280 }
8281
Willy Tarreau193b8c62012-11-22 00:17:38 +01008282 /* ensure that cookie capture length is not too large */
8283 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008284 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
8285 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01008286 err_code |= ERR_WARN;
8287 curproxy->capture_len = global.tune.cookie_len - 1;
8288 }
8289
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008290 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01008291 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008292 curproxy->req_cap_pool = create_pool("ptrcap",
8293 curproxy->nb_req_cap * sizeof(char *),
8294 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008295 }
8296
8297 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02008298 curproxy->rsp_cap_pool = create_pool("ptrcap",
8299 curproxy->nb_rsp_cap * sizeof(char *),
8300 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01008301 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02008302
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008303 switch (curproxy->load_server_state_from_file) {
8304 case PR_SRV_STATE_FILE_UNSPEC:
8305 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
8306 break;
8307 case PR_SRV_STATE_FILE_GLOBAL:
8308 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008309 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",
8310 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008311 err_code |= ERR_WARN;
8312 }
8313 break;
8314 }
8315
Willy Tarreaubaaee002006-06-26 02:48:02 +02008316 /* first, we will invert the servers list order */
8317 newsrv = NULL;
8318 while (curproxy->srv) {
8319 struct server *next;
8320
8321 next = curproxy->srv->next;
8322 curproxy->srv->next = newsrv;
8323 newsrv = curproxy->srv;
8324 if (!next)
8325 break;
8326 curproxy->srv = next;
8327 }
8328
Willy Tarreau17edc812014-01-03 12:14:34 +01008329 /* Check that no server name conflicts. This causes trouble in the stats.
8330 * We only emit a warning for the first conflict affecting each server,
8331 * in order to avoid combinatory explosion if all servers have the same
8332 * name. We do that only for servers which do not have an explicit ID,
8333 * because these IDs were made also for distinguishing them and we don't
8334 * want to annoy people who correctly manage them.
8335 */
8336 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8337 struct server *other_srv;
8338
8339 if (newsrv->puid)
8340 continue;
8341
8342 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
8343 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008344 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",
8345 newsrv->conf.file, newsrv->conf.line,
8346 proxy_type_str(curproxy), curproxy->id,
8347 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01008348 break;
8349 }
8350 }
8351 }
8352
Willy Tarreaudd701652010-05-25 23:03:02 +02008353 /* assign automatic UIDs to servers which don't have one yet */
8354 next_id = 1;
8355 newsrv = curproxy->srv;
8356 while (newsrv != NULL) {
8357 if (!newsrv->puid) {
8358 /* server ID not set, use automatic numbering with first
8359 * spare entry starting with next_svid.
8360 */
8361 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
8362 newsrv->conf.id.key = newsrv->puid = next_id;
8363 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
8364 }
8365 next_id++;
8366 newsrv = newsrv->next;
8367 }
8368
Willy Tarreau20697042007-11-15 23:26:18 +01008369 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01008370 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02008371
Willy Tarreau62c3be22012-01-20 13:12:32 +01008372 /*
8373 * If this server supports a maxconn parameter, it needs a dedicated
8374 * tasks to fill the emptied slots when a connection leaves.
8375 * Also, resolve deferred tracking dependency if needed.
8376 */
8377 newsrv = curproxy->srv;
8378 while (newsrv != NULL) {
8379 if (newsrv->minconn > newsrv->maxconn) {
8380 /* Only 'minconn' was specified, or it was higher than or equal
8381 * to 'maxconn'. Let's turn this into maxconn and clean it, as
8382 * this will avoid further useless expensive computations.
8383 */
8384 newsrv->maxconn = newsrv->minconn;
8385 } else if (newsrv->maxconn && !newsrv->minconn) {
8386 /* minconn was not specified, so we set it to maxconn */
8387 newsrv->minconn = newsrv->maxconn;
8388 }
8389
Willy Tarreau17d45382016-12-22 21:16:08 +01008390 /* this will also properly set the transport layer for prod and checks */
8391 if (newsrv->use_ssl || newsrv->check.use_ssl) {
8392 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
8393 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
8394 }
Emeric Brun94324a42012-10-11 14:00:19 +02008395
Willy Tarreau2f075e92013-12-03 11:11:34 +01008396 /* set the check type on the server */
8397 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
8398
Willy Tarreau62c3be22012-01-20 13:12:32 +01008399 if (newsrv->trackit) {
8400 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02008401 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008402 char *pname, *sname;
8403
8404 pname = newsrv->trackit;
8405 sname = strrchr(pname, '/');
8406
8407 if (sname)
8408 *sname++ = '\0';
8409 else {
8410 sname = pname;
8411 pname = NULL;
8412 }
8413
8414 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02008415 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008416 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008417 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
8418 proxy_type_str(curproxy), curproxy->id,
8419 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008420 cfgerr++;
8421 goto next_srv;
8422 }
8423 } else
8424 px = curproxy;
8425
8426 srv = findserver(px, sname);
8427 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008428 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
8429 proxy_type_str(curproxy), curproxy->id,
8430 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008431 cfgerr++;
8432 goto next_srv;
8433 }
8434
Willy Tarreau32091232014-05-16 13:52:00 +02008435 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
8436 !(srv->agent.state & CHK_ST_CONFIGURED) &&
8437 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008438 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
8439 "tracking as it does not have any check nor agent enabled.\n",
8440 proxy_type_str(curproxy), curproxy->id,
8441 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02008442 cfgerr++;
8443 goto next_srv;
8444 }
8445
8446 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
8447
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01008448 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008449 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
8450 "belongs to a tracking chain looping back to %s/%s.\n",
8451 proxy_type_str(curproxy), curproxy->id,
8452 newsrv->id, px->id, srv->id, px->id,
8453 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008454 cfgerr++;
8455 goto next_srv;
8456 }
8457
8458 if (curproxy != px &&
8459 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008460 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
8461 "tracking: disable-on-404 option inconsistency.\n",
8462 proxy_type_str(curproxy), curproxy->id,
8463 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01008464 cfgerr++;
8465 goto next_srv;
8466 }
8467
Willy Tarreau62c3be22012-01-20 13:12:32 +01008468 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01008469 newsrv->tracknext = srv->trackers;
8470 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01008471
8472 free(newsrv->trackit);
8473 newsrv->trackit = NULL;
8474 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02008475
Willy Tarreau62c3be22012-01-20 13:12:32 +01008476 next_srv:
8477 newsrv = newsrv->next;
8478 }
8479
Olivier Houchard4e694042017-03-14 20:01:29 +01008480 /*
8481 * Try to generate dynamic cookies for servers now.
8482 * It couldn't be done earlier, since at the time we parsed
8483 * the server line, we may not have known yet that we
8484 * should use dynamic cookies, or the secret key may not
8485 * have been provided yet.
8486 */
8487 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
8488 newsrv = curproxy->srv;
8489 while (newsrv != NULL) {
8490 srv_set_dyncookie(newsrv);
8491 newsrv = newsrv->next;
8492 }
8493
8494 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008495 /* We have to initialize the server lookup mechanism depending
8496 * on what LB algorithm was choosen.
8497 */
8498
8499 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
8500 switch (curproxy->lbprm.algo & BE_LB_KIND) {
8501 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02008502 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
8503 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8504 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02008505 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
8506 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8507 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02008508 } else {
8509 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
8510 fwrr_init_server_groups(curproxy);
8511 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008512 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008513
Willy Tarreau3ebb1162012-02-13 16:57:44 +01008514 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01008515 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
8516 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
8517 fwlc_init_server_tree(curproxy);
8518 } else {
8519 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
8520 fas_init_server_tree(curproxy);
8521 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008522 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008523
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008524 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02008525 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
8526 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
8527 chash_init_server_tree(curproxy);
8528 } else {
8529 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
8530 init_server_map(curproxy);
8531 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02008532 break;
8533 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01008534 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02008535
8536 if (curproxy->options & PR_O_LOGASAP)
8537 curproxy->to_log &= ~LW_BYTES;
8538
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008539 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02008540 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
8541 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008542 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
8543 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02008544 err_code |= ERR_WARN;
8545 }
8546
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008547 if (curproxy->mode != PR_MODE_HTTP) {
8548 int optnum;
8549
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008550 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008551 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
8552 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008553 err_code |= ERR_WARN;
8554 curproxy->uri_auth = NULL;
8555 }
8556
Willy Tarreaude7dc882017-03-10 11:49:21 +01008557 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008558 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
8559 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008560 err_code |= ERR_WARN;
8561 }
8562
8563 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008564 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
8565 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008566 err_code |= ERR_WARN;
8567 }
8568
8569 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008570 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
8571 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008572 err_code |= ERR_WARN;
8573 }
8574
8575 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008576 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
8577 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008578 err_code |= ERR_WARN;
8579 }
8580
8581 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008582 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
8583 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01008584 err_code |= ERR_WARN;
8585 }
8586
Willy Tarreau87cf5142011-08-19 22:57:24 +02008587 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008588 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8589 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008590 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02008591 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008592 }
8593
8594 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008595 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8596 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008597 err_code |= ERR_WARN;
8598 curproxy->options &= ~PR_O_ORGTO;
8599 }
8600
8601 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
8602 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
8603 (curproxy->cap & cfg_opts[optnum].cap) &&
8604 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008605 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8606 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008607 err_code |= ERR_WARN;
8608 curproxy->options &= ~cfg_opts[optnum].val;
8609 }
8610 }
8611
8612 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
8613 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
8614 (curproxy->cap & cfg_opts2[optnum].cap) &&
8615 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008616 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
8617 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008618 err_code |= ERR_WARN;
8619 curproxy->options2 &= ~cfg_opts2[optnum].val;
8620 }
8621 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008622
Willy Tarreau29fbe512015-08-20 19:35:14 +02008623#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008624 if (curproxy->conn_src.bind_hdr_occ) {
8625 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008626 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
8627 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008628 err_code |= ERR_WARN;
8629 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008630#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01008631 }
8632
Willy Tarreaubaaee002006-06-26 02:48:02 +02008633 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01008634 * ensure that we're not cross-dressing a TCP server into HTTP.
8635 */
8636 newsrv = curproxy->srv;
8637 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01008638 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008639 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
8640 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02008641 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01008642 }
Willy Tarreaubce70882009-09-07 11:51:47 +02008643
Willy Tarreau0cec3312011-10-31 13:49:26 +01008644 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008645 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
8646 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01008647 err_code |= ERR_WARN;
8648 }
8649
Willy Tarreauc93cd162014-05-13 15:54:22 +02008650 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008651 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
8652 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02008653 err_code |= ERR_WARN;
8654 }
8655
Willy Tarreau29fbe512015-08-20 19:35:14 +02008656#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01008657 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
8658 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01008659 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
8660 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02008661 err_code |= ERR_WARN;
8662 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02008663#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01008664
Willy Tarreau46deab62018-04-28 07:18:15 +02008665 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
8666 curproxy->options &= ~PR_O_REUSE_MASK;
8667
Willy Tarreau4c183462017-01-06 12:21:38 +01008668 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
8669 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8670 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
8671 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
8672 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008673 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",
8674 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008675 err_code |= ERR_WARN;
8676 }
8677
8678
8679 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008680 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",
8681 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01008682 err_code |= ERR_WARN;
8683 }
8684 }
8685
Willy Tarreau21d2af32008-02-14 20:25:24 +01008686 newsrv = newsrv->next;
8687 }
8688
Willy Tarreaue42bd962014-09-16 16:21:19 +02008689 /* check if we have a frontend with "tcp-request content" looking at L7
8690 * with no inspect-delay
8691 */
8692 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02008693 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
8694 if (arule->action == ACT_TCP_CAPTURE &&
8695 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008696 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02008697 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
8698 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02008699 break;
8700 }
8701
Christopher Faulete4e830d2017-09-18 14:51:41 +02008702 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008703 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
8704 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
8705 " This means that these rules will randomly find their contents. This can be fixed by"
8706 " setting the tcp-request inspect-delay.\n",
8707 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02008708 err_code |= ERR_WARN;
8709 }
8710 }
8711
Christopher Fauletd7c91962015-04-30 11:48:27 +02008712 /* Check filter configuration, if any */
8713 cfgerr += flt_check(curproxy);
8714
Willy Tarreauc1a21672009-08-16 22:37:44 +02008715 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02008716 if (!curproxy->accept)
8717 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02008718
Willy Tarreauc1a21672009-08-16 22:37:44 +02008719 if (curproxy->tcp_req.inspect_delay ||
8720 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02008721 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008722
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008723 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008724 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008725 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008726 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008727
8728 /* both TCP and HTTP must check switching rules */
8729 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008730
8731 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008732 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008733 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8734 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 +01008735 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008736 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8737 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008738 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008739 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008740 }
8741
8742 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02008743 if (curproxy->tcp_req.inspect_delay ||
8744 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
8745 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
8746
Emeric Brun97679e72010-09-23 17:56:44 +02008747 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
8748 curproxy->be_rsp_ana |= AN_RES_INSPECT;
8749
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008750 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02008751 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02008752 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02008753 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008754
8755 /* If the backend does requires RDP cookie persistence, we have to
8756 * enable the corresponding analyser.
8757 */
8758 if (curproxy->options2 & PR_O2_RDPC_PRST)
8759 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02008760
8761 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01008762 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008763 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
8764 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 +01008765 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01008766 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
8767 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01008768 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02008769 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02008770 }
Christopher Fauleta717b992018-04-10 14:43:00 +02008771
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008772 /* Check the mux protocols, if any, for each listener and server
Christopher Fauleta717b992018-04-10 14:43:00 +02008773 * attached to the current proxy */
8774 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8775 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8776
8777 if (!bind_conf->mux_proto)
8778 continue;
8779 if (!(bind_conf->mux_proto->mode & mode)) {
8780 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n",
8781 proxy_type_str(curproxy), curproxy->id,
8782 (int)bind_conf->mux_proto->token.len,
8783 bind_conf->mux_proto->token.ptr,
8784 bind_conf->arg, bind_conf->file, bind_conf->line);
8785 cfgerr++;
8786 }
8787 }
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02008788 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
8789 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
8790
8791 if (!newsrv->mux_proto)
8792 continue;
8793 if (!(newsrv->mux_proto->mode & mode)) {
8794 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n",
8795 proxy_type_str(curproxy), curproxy->id,
8796 (int)newsrv->mux_proto->token.len,
8797 newsrv->mux_proto->token.ptr,
8798 newsrv->id, newsrv->conf.file, newsrv->conf.line);
8799 cfgerr++;
8800 }
8801 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008802 }
8803
8804 /***********************************************************/
8805 /* At this point, target names have already been resolved. */
8806 /***********************************************************/
8807
8808 /* Check multi-process mode compatibility */
8809
8810 if (global.nbproc > 1 && global.stats_fe) {
8811 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8812 unsigned long mask;
8813
8814 mask = nbits(global.nbproc);
8815 if (global.stats_fe->bind_proc)
8816 mask &= global.stats_fe->bind_proc;
8817
8818 if (bind_conf->bind_proc)
8819 mask &= bind_conf->bind_proc;
8820
8821 /* stop here if more than one process is used */
David Carliere6c39412015-07-02 07:00:17 +00008822 if (my_popcountl(mask) > 1)
Willy Tarreau419ead82014-09-16 13:41:21 +02008823 break;
8824 }
8825 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008826 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 +02008827 }
8828 }
8829
8830 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008831 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008832 if (curproxy->bind_proc)
8833 continue;
8834
8835 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
8836 unsigned long mask;
8837
Willy Tarreaue428b082015-05-04 21:57:58 +02008838 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008839 curproxy->bind_proc |= mask;
8840 }
8841
8842 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008843 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008844 }
8845
8846 if (global.stats_fe) {
8847 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
8848 unsigned long mask;
8849
Cyril Bonté06181952016-02-24 00:14:54 +01008850 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02008851 global.stats_fe->bind_proc |= mask;
8852 }
8853 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02008854 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008855 }
8856
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008857 /* propagate bindings from frontends to backends. Don't do it if there
8858 * are any fatal errors as we must not call it with unresolved proxies.
8859 */
8860 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008861 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02008862 if (curproxy->cap & PR_CAP_FE)
8863 propagate_processes(curproxy, NULL);
8864 }
Willy Tarreau419ead82014-09-16 13:41:21 +02008865 }
8866
8867 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008868 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008869 if (curproxy->bind_proc)
8870 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02008871 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02008872 }
8873
8874 /*******************************************************/
8875 /* At this step, all proxies have a non-null bind_proc */
8876 /*******************************************************/
8877
8878 /* perform the final checks before creating tasks */
8879
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008880 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02008881 struct listener *listener;
8882 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008883
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008884 /* Configure SSL for each bind line.
8885 * Note: if configuration fails at some point, the ->ctx member
8886 * remains NULL so that listeners can later detach.
8887 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008888 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01008889 if (bind_conf->xprt->prepare_bind_conf &&
8890 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008891 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008892 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008893
Willy Tarreaue6b98942007-10-29 01:09:36 +01008894 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008895 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02008896 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008897 int nbproc;
8898
8899 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02008900 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008901 nbits(global.nbproc));
8902
8903 if (!nbproc) /* no intersection between listener and frontend */
8904 nbproc = 1;
8905
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008906 if (!listener->luid) {
8907 /* listener ID not set, use automatic numbering with first
8908 * spare entry starting with next_luid.
8909 */
8910 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
8911 listener->conf.id.key = listener->luid = next_id;
8912 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008913 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01008914 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02008915
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008916 /* enable separate counters */
8917 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01008918 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01008919 if (!listener->name)
8920 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02008921 }
Willy Tarreau81796be2012-09-22 19:11:47 +02008922
Willy Tarreaue6b98942007-10-29 01:09:36 +01008923 if (curproxy->options & PR_O_TCP_NOLING)
8924 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02008925 if (!listener->maxconn)
8926 listener->maxconn = curproxy->maxconn;
8927 if (!listener->backlog)
8928 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01008929 if (!listener->maxaccept)
8930 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
8931
8932 /* we want to have an optimal behaviour on single process mode to
8933 * maximize the work at once, but in multi-process we want to keep
8934 * some fairness between processes, so we target half of the max
8935 * number of events to be balanced over all the processes the proxy
8936 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
8937 * used to disable the limit.
8938 */
8939 if (listener->maxaccept > 0) {
8940 if (nbproc > 1)
8941 listener->maxaccept = (listener->maxaccept + 1) / 2;
8942 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
8943 }
8944
Willy Tarreau9903f0e2015-04-04 18:50:31 +02008945 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02008946 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01008947 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01008948
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008949 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02008950 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02008951
Willy Tarreau620408f2016-10-21 16:37:51 +02008952 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
8953 listener->options |= LI_O_TCP_L5_RULES;
8954
Willy Tarreaude3041d2010-05-31 10:56:17 +02008955 if (curproxy->mon_mask.s_addr)
8956 listener->options |= LI_O_CHK_MONNET;
8957
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008958 /* smart accept mode is automatic in HTTP mode */
8959 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008960 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02008961 !(curproxy->no_options2 & PR_O2_SMARTACC)))
8962 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01008963 }
8964
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008965 /* Release unused SSL configs */
8966 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01008967 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
8968 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02008969 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02008970
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02008971 if (my_popcountl(curproxy->bind_proc & nbits(global.nbproc)) > 1) {
Willy Tarreau102df612014-05-07 23:56:38 +02008972 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02008973 int count, maxproc = 0;
8974
8975 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00008976 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008977 if (count > maxproc)
8978 maxproc = count;
8979 }
8980 /* backends have 0, frontends have 1 or more */
8981 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01008982 ha_warning("Proxy '%s': in multi-process mode, stats will be"
8983 " limited to process assigned to the current request.\n",
8984 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02008985
Willy Tarreau102df612014-05-07 23:56:38 +02008986 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008987 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
8988 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008989 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008990 }
Willy Tarreau102df612014-05-07 23:56:38 +02008991 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008992 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
8993 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01008994 }
8995 }
Willy Tarreau918ff602011-07-25 16:33:49 +02008996
8997 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02008998 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02008999 if (curproxy->task) {
9000 curproxy->task->context = curproxy;
9001 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02009002 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009003 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
9004 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02009005 cfgerr++;
9006 }
Willy Tarreaub369a042014-09-16 13:21:03 +02009007 }
9008
Willy Tarreaufbb78422011-06-05 15:38:35 +02009009 /* automatically compute fullconn if not set. We must not do it in the
9010 * loop above because cross-references are not yet fully resolved.
9011 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009012 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009013 /* If <fullconn> is not set, let's set it to 10% of the sum of
9014 * the possible incoming frontend's maxconns.
9015 */
9016 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02009017 /* we have the sum of the maxconns in <total>. We only
9018 * keep 10% of that sum to set the default fullconn, with
9019 * a hard minimum of 1 (to avoid a divide by zero).
9020 */
Emeric Brun3f783572017-01-12 11:21:28 +01009021 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02009022 if (!curproxy->fullconn)
9023 curproxy->fullconn = 1;
9024 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01009025 }
9026
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009027 /*
9028 * Recount currently required checks.
9029 */
9030
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009031 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009032 int optnum;
9033
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009034 for (optnum = 0; cfg_opts[optnum].name; optnum++)
9035 if (curproxy->options & cfg_opts[optnum].val)
9036 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009037
Willy Tarreau66aa61f2009-01-18 21:44:07 +01009038 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
9039 if (curproxy->options2 & cfg_opts2[optnum].val)
9040 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01009041 }
9042
Willy Tarreau0fca4832015-05-01 19:12:05 +02009043 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009044 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02009045 if (curproxy->table.peers.p)
9046 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
9047
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009048 if (cfg_peers) {
9049 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02009050 struct peer *p, *pb;
9051
Willy Tarreau1e273012015-05-01 19:15:17 +02009052 /* Remove all peers sections which don't have a valid listener,
9053 * which are not used by any table, or which are bound to more
9054 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02009055 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02009056 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02009057 while (*last) {
9058 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009059
9060 if (curpeers->state == PR_STSTOPPED) {
9061 /* the "disabled" keyword was present */
9062 if (curpeers->peers_fe)
9063 stop_proxy(curpeers->peers_fe);
9064 curpeers->peers_fe = NULL;
9065 }
9066 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009067 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
9068 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009069 }
David Carliere6c39412015-07-02 07:00:17 +00009070 else if (my_popcountl(curpeers->peers_fe->bind_proc) != 1) {
Willy Tarreau1e273012015-05-01 19:15:17 +02009071 /* either it's totally stopped or too much used */
9072 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009073 ha_alert("Peers section '%s': peers referenced by sections "
9074 "running in different processes (%d different ones). "
9075 "Check global.nbproc and all tables' bind-process "
9076 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02009077 cfgerr++;
9078 }
9079 stop_proxy(curpeers->peers_fe);
9080 curpeers->peers_fe = NULL;
9081 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009082 else {
Emeric Brunb3971ab2015-05-12 18:49:09 +02009083 peers_init_sync(curpeers);
Willy Tarreau122541c2011-09-07 21:24:49 +02009084 last = &curpeers->next;
9085 continue;
9086 }
9087
Willy Tarreau77e4bd12015-05-01 20:02:17 +02009088 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02009089 p = curpeers->remote;
9090 while (p) {
9091 pb = p->next;
9092 free(p->id);
9093 free(p);
9094 p = pb;
9095 }
9096
9097 /* Destroy and unlink this curpeers section.
9098 * Note: curpeers is backed up into *last.
9099 */
9100 free(curpeers->id);
9101 curpeers = curpeers->next;
9102 free(*last);
9103 *last = curpeers;
9104 }
9105 }
9106
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009107 /* initialize stick-tables on backend capable proxies. This must not
9108 * be done earlier because the data size may be discovered while parsing
9109 * other proxies.
9110 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009111 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009112 if (curproxy->state == PR_STSTOPPED)
9113 continue;
9114
9115 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009116 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02009117 cfgerr++;
9118 }
9119 }
9120
Simon Horman0d16a402015-01-30 11:22:58 +09009121 if (mailers) {
9122 struct mailers *curmailers = mailers, **last;
9123 struct mailer *m, *mb;
9124
9125 /* Remove all mailers sections which don't have a valid listener.
9126 * This can happen when a mailers section is never referenced.
9127 */
9128 last = &mailers;
9129 while (*last) {
9130 curmailers = *last;
9131 if (curmailers->users) {
9132 last = &curmailers->next;
9133 continue;
9134 }
9135
Christopher Faulet767a84b2017-11-24 16:50:31 +01009136 ha_warning("Removing incomplete section 'mailers %s'.\n",
9137 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09009138
9139 m = curmailers->mailer_list;
9140 while (m) {
9141 mb = m->next;
9142 free(m->id);
9143 free(m);
9144 m = mb;
9145 }
9146
9147 /* Destroy and unlink this curmailers section.
9148 * Note: curmailers is backed up into *last.
9149 */
9150 free(curmailers->id);
9151 curmailers = curmailers->next;
9152 free(*last);
9153 *last = curmailers;
9154 }
9155 }
9156
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009157 /* Update server_state_file_name to backend name if backend is supposed to use
9158 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01009159 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02009160 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
9161 curproxy->server_state_file_name == NULL)
9162 curproxy->server_state_file_name = strdup(curproxy->id);
9163 }
9164
Willy Tarreaubafbe012017-11-24 17:34:44 +01009165 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02009166 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02009167 MEM_F_SHARED);
9168
Ben Draut054fbee2018-04-13 15:43:04 -06009169 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
9170 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
9171 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
9172 curr_resolvers->id, curr_resolvers->conf.file,
9173 curr_resolvers->conf.line);
9174 err_code |= ERR_WARN;
9175 }
9176 }
9177
William Lallemand48b4bb42017-10-23 14:36:34 +02009178 list_for_each_entry(postparser, &postparsers, list) {
9179 if (postparser->func)
9180 cfgerr += postparser->func();
9181 }
9182
Willy Tarreaubb925012009-07-23 13:36:36 +02009183 if (cfgerr > 0)
9184 err_code |= ERR_ALERT | ERR_FATAL;
9185 out:
9186 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02009187}
9188
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009189/*
9190 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
9191 * parsing sessions.
9192 */
9193void cfg_register_keywords(struct cfg_kw_list *kwl)
9194{
9195 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
9196}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009197
Willy Tarreau5b2c3362008-07-09 19:39:06 +02009198/*
9199 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
9200 */
9201void cfg_unregister_keywords(struct cfg_kw_list *kwl)
9202{
9203 LIST_DEL(&kwl->list);
9204 LIST_INIT(&kwl->list);
9205}
Willy Tarreaubaaee002006-06-26 02:48:02 +02009206
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009207/* this function register new section in the haproxy configuration file.
9208 * <section_name> is the name of this new section and <section_parser>
9209 * is the called parser. If two section declaration have the same name,
9210 * only the first declared is used.
9211 */
9212int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02009213 int (*section_parser)(const char *, int, char **, int),
9214 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009215{
9216 struct cfg_section *cs;
9217
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009218 list_for_each_entry(cs, &sections, list) {
9219 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009220 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02009221 return 0;
9222 }
9223 }
9224
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009225 cs = calloc(1, sizeof(*cs));
9226 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009227 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009228 return 0;
9229 }
9230
9231 cs->section_name = section_name;
9232 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02009233 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01009234
9235 LIST_ADDQ(&sections, &cs->list);
9236
9237 return 1;
9238}
9239
William Lallemand48b4bb42017-10-23 14:36:34 +02009240/* this function register a new function which will be called once the haproxy
9241 * configuration file has been parsed. It's useful to check dependencies
9242 * between sections or to resolve items once everything is parsed.
9243 */
9244int cfg_register_postparser(char *name, int (*func)())
9245{
9246 struct cfg_postparser *cp;
9247
9248 cp = calloc(1, sizeof(*cp));
9249 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01009250 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02009251 return 0;
9252 }
9253 cp->name = name;
9254 cp->func = func;
9255
9256 LIST_ADDQ(&postparsers, &cp->list);
9257
9258 return 1;
9259}
9260
Willy Tarreaubaaee002006-06-26 02:48:02 +02009261/*
David Carlier845efb52015-09-25 11:49:18 +01009262 * free all config section entries
9263 */
9264void cfg_unregister_sections(void)
9265{
9266 struct cfg_section *cs, *ics;
9267
9268 list_for_each_entry_safe(cs, ics, &sections, list) {
9269 LIST_DEL(&cs->list);
9270 free(cs);
9271 }
9272}
9273
Christopher Faulet7110b402016-10-26 11:09:44 +02009274void cfg_backup_sections(struct list *backup_sections)
9275{
9276 struct cfg_section *cs, *ics;
9277
9278 list_for_each_entry_safe(cs, ics, &sections, list) {
9279 LIST_DEL(&cs->list);
9280 LIST_ADDQ(backup_sections, &cs->list);
9281 }
9282}
9283
9284void cfg_restore_sections(struct list *backup_sections)
9285{
9286 struct cfg_section *cs, *ics;
9287
9288 list_for_each_entry_safe(cs, ics, backup_sections, list) {
9289 LIST_DEL(&cs->list);
9290 LIST_ADDQ(&sections, &cs->list);
9291 }
9292}
9293
Willy Tarreau659fbf02016-05-26 17:55:28 +02009294__attribute__((constructor))
9295static void cfgparse_init(void)
9296{
9297 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02009298 cfg_register_section("listen", cfg_parse_listen, NULL);
9299 cfg_register_section("frontend", cfg_parse_listen, NULL);
9300 cfg_register_section("backend", cfg_parse_listen, NULL);
9301 cfg_register_section("defaults", cfg_parse_listen, NULL);
9302 cfg_register_section("global", cfg_parse_global, NULL);
9303 cfg_register_section("userlist", cfg_parse_users, NULL);
9304 cfg_register_section("peers", cfg_parse_peers, NULL);
9305 cfg_register_section("mailers", cfg_parse_mailers, NULL);
9306 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
9307 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02009308}
9309
David Carlier845efb52015-09-25 11:49:18 +01009310/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02009311 * Local variables:
9312 * c-indent-level: 8
9313 * c-basic-offset: 8
9314 * End:
9315 */