blob: 05bd951a2e6bba7391cdb08bd61c8619d024305a [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>
Baptiste Assmann201c07f2017-05-22 15:17:15 +020063#include <proto/dns.h>
William Lallemand9ed62032016-11-21 17:49:11 +010064#include <proto/stats.h>
Christopher Fauletd7c91962015-04-30 11:48:27 +020065#include <proto/filters.h>
Willy Tarreaueb472682010-05-28 18:46:57 +020066#include <proto/frontend.h>
Willy Tarreau34eb6712011-10-24 18:15:04 +020067#include <proto/hdr_idx.h>
Willy Tarreau61c112a2018-10-02 16:43:32 +020068#include <proto/http_rules.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
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +0100120/* Used to chain configuration sections definitions. This list
121 * stores struct cfg_section
122 */
123struct list sections = LIST_HEAD_INIT(sections);
124
William Lallemand48b4bb42017-10-23 14:36:34 +0200125struct list postparsers = LIST_HEAD_INIT(postparsers);
126
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100127/* proxy->options */
128static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100129{
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100130 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0, 0 },
131 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0, 0 },
132 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0, PR_MODE_HTTP },
133 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0, 0 },
134 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
135 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100136 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau9fbe18e2015-05-01 22:42:08 +0200137 { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau0f228a02015-05-01 15:37:53 +0200138 { "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
Willy Tarreau9420b122013-12-15 18:58:25 +0100139 { "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100140 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
141 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
142 { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100143 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100144#ifdef TPROXY
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100145 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100146#else
147 { "transparent", 0, 0, 0, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100148#endif
149
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100150 { NULL, 0, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100151};
152
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100153/* proxy->options2 */
154static const struct cfg_opt cfg_opts2[] =
155{
156#ifdef CONFIG_HAP_LINUX_SPLICE
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100157 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0, 0 },
158 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
159 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Cyril Bonté62846b22010-11-01 19:26:00 +0100160#else
161 { "splice-request", 0, 0, 0, 0 },
162 { "splice-response", 0, 0, 0, 0 },
163 { "splice-auto", 0, 0, 0, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100164#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100165 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0, PR_MODE_HTTP },
166 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0, PR_MODE_HTTP },
167 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0, 0 },
168 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0, 0 },
169 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0, 0 },
170 { "socket-stats", PR_O2_SOCKSTAT, PR_CAP_FE, 0, 0 },
171 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0, 0 },
172 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0, 0 },
173 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Jamie Gloudon801a0a32012-08-25 00:18:33 -0400174 { "independent-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0, 0 },
Willy Tarreaue24fdfb2010-03-25 07:22:56 +0100175 { "http-use-proxy-header", PR_O2_USE_PXHDR, PR_CAP_FE, 0, PR_MODE_HTTP },
Christopher Faulet98db9762018-09-21 10:25:19 +0200176 { "http-pretend-keepalive", PR_O2_FAKE_KA, PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau96e31212011-05-30 18:10:30 +0200177 { "http-no-delay", PR_O2_NODELAY, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau68ad3a42018-10-22 11:49:15 +0200178 { "http-use-htx", PR_O2_USE_HTX, PR_CAP_FE|PR_CAP_BE, 0, PR_MODE_HTTP },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100179 { NULL, 0, 0, 0 }
180};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200181
Willy Tarreau6daf3432008-01-22 16:44:08 +0100182static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200183static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
184int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100185int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Christopher Faulet79bdef32016-11-04 22:36:15 +0100186char *cfg_scope = NULL; /* the current scope during the configuration parsing */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200187
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200188/* List head of all known configuration keywords */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100189struct cfg_kw_list cfg_keywords = {
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200190 .list = LIST_HEAD_INIT(cfg_keywords.list)
191};
192
Willy Tarreaubaaee002006-06-26 02:48:02 +0200193/*
194 * converts <str> to a list of listeners which are dynamically allocated.
195 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
196 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
197 * - <port> is a numerical port from 1 to 65535 ;
198 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
199 * This can be repeated as many times as necessary, separated by a coma.
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200200 * Function returns 1 for success or 0 if error. In case of errors, if <err> is
201 * not NULL, it must be a valid pointer to either NULL or a freeable area that
202 * will be replaced with an error message.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200203 */
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200204int 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 +0200205{
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100206 char *next, *dupstr;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200207 int port, end;
208
209 next = dupstr = strdup(str);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200210
Willy Tarreaubaaee002006-06-26 02:48:02 +0200211 while (next && *next) {
William Lallemand75ea0a02017-11-15 19:02:58 +0100212 int inherited = 0;
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200213 struct sockaddr_storage *ss2;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100214 int fd = -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200215
216 str = next;
217 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100218 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200219 *next++ = 0;
220 }
221
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100222 ss2 = str2sa_range(str, NULL, &port, &end, err,
Willy Tarreau72b8c1f2015-09-08 15:50:19 +0200223 curproxy == global.stats_fe ? NULL : global.unix_bind.prefix,
Thierry FOURNIER7fe3be72015-09-26 20:03:36 +0200224 NULL, 1);
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100225 if (!ss2)
226 goto fail;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200227
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100228 if (ss2->ss_family == AF_INET || ss2->ss_family == AF_INET6) {
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100229 if (!port && !end) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200230 memprintf(err, "missing port number: '%s'\n", str);
Willy Tarreau2dff0c22011-03-04 15:43:13 +0100231 goto fail;
Emeric Bruned760922010-10-22 17:59:25 +0200232 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200233
Willy Tarreau6d03cc32013-02-20 17:26:02 +0100234 if (!port || !end) {
235 memprintf(err, "port offsets are not allowed in 'bind': '%s'\n", str);
236 goto fail;
237 }
238
Emeric Bruned760922010-10-22 17:59:25 +0200239 if (port < 1 || port > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200240 memprintf(err, "invalid port '%d' specified for address '%s'.\n", port, str);
Emeric Bruned760922010-10-22 17:59:25 +0200241 goto fail;
242 }
243
244 if (end < 1 || end > 65535) {
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200245 memprintf(err, "invalid port '%d' specified for address '%s'.\n", end, str);
Emeric Bruned760922010-10-22 17:59:25 +0200246 goto fail;
247 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200248 }
Willy Tarreau40aa0702013-03-10 23:51:38 +0100249 else if (ss2->ss_family == AF_UNSPEC) {
250 socklen_t addr_len;
William Lallemand75ea0a02017-11-15 19:02:58 +0100251 inherited = 1;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100252
253 /* We want to attach to an already bound fd whose number
254 * is in the addr part of ss2 when cast to sockaddr_in.
255 * Note that by definition there is a single listener.
256 * We still have to determine the address family to
257 * register the correct protocol.
258 */
259 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
260 addr_len = sizeof(*ss2);
261 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
262 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
263 goto fail;
264 }
265
266 port = end = get_host_port(ss2);
William Lallemand2fe7dd02018-09-11 16:51:29 +0200267
268 } else if (ss2->ss_family == AF_CUST_SOCKPAIR) {
269 socklen_t addr_len;
270 inherited = 1;
271
272 fd = ((struct sockaddr_in *)ss2)->sin_addr.s_addr;
273 addr_len = sizeof(*ss2);
274 if (getsockname(fd, (struct sockaddr *)ss2, &addr_len) == -1) {
275 memprintf(err, "cannot use file descriptor '%d' : %s.\n", fd, strerror(errno));
276 goto fail;
277 }
278
279 ss2->ss_family = AF_CUST_SOCKPAIR; /* reassign AF_CUST_SOCKPAIR because of getsockname */
280 port = end = 0;
Willy Tarreau40aa0702013-03-10 23:51:38 +0100281 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200282
Willy Tarreau12eb2a62013-03-06 15:45:03 +0100283 /* OK the address looks correct */
William Lallemand75ea0a02017-11-15 19:02:58 +0100284 if (!create_listeners(bind_conf, ss2, port, end, fd, inherited, err)) {
Willy Tarreau0de59fd2017-09-15 08:10:44 +0200285 memprintf(err, "%s for address '%s'.\n", *err, str);
286 goto fail;
287 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200288 } /* end while(next) */
289 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200290 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200291 fail:
292 free(dupstr);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200293 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200294}
295
William Lallemand6e62fb62015-04-28 16:55:23 +0200296/*
Willy Tarreauece9b072016-12-21 22:41:44 +0100297 * Report an error in <msg> when there are too many arguments. This version is
298 * intended to be used by keyword parsers so that the message will be included
299 * into the general error message. The index is the current keyword in args.
300 * Return 0 if the number of argument is correct, otherwise build a message and
301 * return 1. Fill err_code with an ERR_ALERT and an ERR_FATAL if not null. The
302 * message may also be null, it will simply not be produced (useful to check only).
303 * <msg> and <err_code> are only affected on error.
304 */
305int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code)
306{
307 int i;
308
309 if (!*args[index + maxarg + 1])
310 return 0;
311
312 if (msg) {
313 *msg = NULL;
314 memprintf(msg, "%s", args[0]);
315 for (i = 1; i <= index; i++)
316 memprintf(msg, "%s %s", *msg, args[i]);
317
318 memprintf(msg, "'%s' cannot handle unexpected argument '%s'.", *msg, args[index + maxarg + 1]);
319 }
320 if (err_code)
321 *err_code |= ERR_ALERT | ERR_FATAL;
322
323 return 1;
324}
325
326/*
327 * same as too_many_args_idx with a 0 index
328 */
329int too_many_args(int maxarg, char **args, char **msg, int *err_code)
330{
331 return too_many_args_idx(maxarg, 0, args, msg, err_code);
332}
333
334/*
William Lallemand6e62fb62015-04-28 16:55:23 +0200335 * Report a fatal Alert when there is too much arguments
336 * The index is the current keyword in args
337 * Return 0 if the number of argument is correct, otherwise emit an alert and return 1
338 * Fill err_code with an ERR_ALERT and an ERR_FATAL
339 */
340int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code)
341{
342 char *kw = NULL;
343 int i;
344
345 if (!*args[index + maxarg + 1])
346 return 0;
347
348 memprintf(&kw, "%s", args[0]);
349 for (i = 1; i <= index; i++) {
350 memprintf(&kw, "%s %s", kw, args[i]);
351 }
352
Christopher Faulet767a84b2017-11-24 16:50:31 +0100353 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 +0200354 free(kw);
355 *err_code |= ERR_ALERT | ERR_FATAL;
356 return 1;
357}
358
359/*
360 * same as alertif_too_many_args_idx with a 0 index
361 */
362int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code)
363{
364 return alertif_too_many_args_idx(maxarg, 0, file, linenum, args, err_code);
365}
366
Willy Tarreau620408f2016-10-21 16:37:51 +0200367/* Report a warning if a rule is placed after a 'tcp-request session' rule.
368 * Return 1 if the warning has been emitted, otherwise 0.
369 */
370int warnif_rule_after_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
371{
372 if (!LIST_ISEMPTY(&proxy->tcp_req.l5_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100373 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request session' rule will still be processed before.\n",
374 file, line, arg);
Willy Tarreau620408f2016-10-21 16:37:51 +0200375 return 1;
376 }
377 return 0;
378}
379
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200380/* Report a warning if a rule is placed after a 'tcp-request content' rule.
381 * Return 1 if the warning has been emitted, otherwise 0.
382 */
383int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
384{
385 if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100386 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
387 file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200388 return 1;
389 }
390 return 0;
391}
392
Willy Tarreau721d8e02017-12-01 18:25:08 +0100393/* Report a warning if a rule is placed after a 'monitor fail' rule.
394 * Return 1 if the warning has been emitted, otherwise 0.
395 */
396int warnif_rule_after_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
397{
398 if (!LIST_ISEMPTY(&proxy->mon_fail_cond)) {
399 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'monitor fail' rule will still be processed before.\n",
400 file, line, arg);
401 return 1;
402 }
403 return 0;
404}
405
Willy Tarreau61d18892009-03-31 10:49:21 +0200406/* Report a warning if a rule is placed after a 'block' rule.
407 * Return 1 if the warning has been emitted, otherwise 0.
408 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100409int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200410{
Willy Tarreau353bc9f2014-04-28 22:05:31 +0200411 if (!LIST_ISEMPTY(&proxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100412 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
413 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200414 return 1;
415 }
416 return 0;
417}
418
Willy Tarreau5002f572014-04-23 01:32:02 +0200419/* Report a warning if a rule is placed after an 'http_request' rule.
420 * Return 1 if the warning has been emitted, otherwise 0.
421 */
422int warnif_rule_after_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
423{
424 if (!LIST_ISEMPTY(&proxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100425 ha_warning("parsing [%s:%d] : a '%s' rule placed after an 'http-request' rule will still be processed before.\n",
426 file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200427 return 1;
428 }
429 return 0;
430}
431
Willy Tarreau61d18892009-03-31 10:49:21 +0200432/* Report a warning if a rule is placed after a reqrewrite rule.
433 * Return 1 if the warning has been emitted, otherwise 0.
434 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100435int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200436{
437 if (proxy->req_exp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100438 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
439 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200440 return 1;
441 }
442 return 0;
443}
444
445/* Report a warning if a rule is placed after a reqadd rule.
446 * Return 1 if the warning has been emitted, otherwise 0.
447 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100448int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200449{
Willy Tarreaudeb9ed82010-01-03 21:03:22 +0100450 if (!LIST_ISEMPTY(&proxy->req_add)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100451 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
452 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200453 return 1;
454 }
455 return 0;
456}
457
458/* Report a warning if a rule is placed after a redirect rule.
459 * Return 1 if the warning has been emitted, otherwise 0.
460 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100461int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200462{
463 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100464 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
465 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200466 return 1;
467 }
468 return 0;
469}
470
471/* Report a warning if a rule is placed after a 'use_backend' rule.
472 * Return 1 if the warning has been emitted, otherwise 0.
473 */
Willy Tarreau3ec18a02010-01-28 19:01:34 +0100474int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200475{
476 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100477 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
478 file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200479 return 1;
480 }
481 return 0;
482}
483
Willy Tarreauee445d92014-04-23 01:39:04 +0200484/* Report a warning if a rule is placed after a 'use-server' rule.
485 * Return 1 if the warning has been emitted, otherwise 0.
486 */
487int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line, const char *arg)
488{
489 if (!LIST_ISEMPTY(&proxy->server_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100490 ha_warning("parsing [%s:%d] : a '%s' rule placed after a 'use-server' rule will still be processed before.\n",
491 file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200492 return 1;
493 }
494 return 0;
495}
496
Willy Tarreaud39ad442016-11-25 15:16:12 +0100497/* report a warning if a redirect rule is dangerously placed */
498int warnif_misplaced_redirect(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau620408f2016-10-21 16:37:51 +0200499{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100500 return warnif_rule_after_use_backend(proxy, file, line, arg) ||
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200501 warnif_rule_after_use_server(proxy, file, line, arg);
502}
503
Willy Tarreaud39ad442016-11-25 15:16:12 +0100504/* report a warning if a reqadd rule is dangerously placed */
505int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200506{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100507 return warnif_rule_after_redirect(proxy, file, line, arg) ||
508 warnif_misplaced_redirect(proxy, file, line, arg);
Willy Tarreau3986b9c2014-09-16 15:39:51 +0200509}
510
Willy Tarreaud39ad442016-11-25 15:16:12 +0100511/* report a warning if a reqxxx rule is dangerously placed */
512int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200513{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100514 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
515 warnif_misplaced_reqadd(proxy, file, line, arg);
Willy Tarreau5002f572014-04-23 01:32:02 +0200516}
517
518/* report a warning if an http-request rule is dangerously placed */
519int warnif_misplaced_http_req(struct proxy *proxy, const char *file, int line, const char *arg)
520{
Willy Tarreau61d18892009-03-31 10:49:21 +0200521 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
Willy Tarreaud39ad442016-11-25 15:16:12 +0100522 warnif_misplaced_reqxxx(proxy, file, line, arg);;
Willy Tarreau61d18892009-03-31 10:49:21 +0200523}
524
Willy Tarreaud39ad442016-11-25 15:16:12 +0100525/* report a warning if a block rule is dangerously placed */
526int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200527{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100528 return warnif_rule_after_http_req(proxy, file, line, arg) ||
529 warnif_misplaced_http_req(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200530}
531
Willy Tarreau721d8e02017-12-01 18:25:08 +0100532/* report a warning if a block rule is dangerously placed */
533int warnif_misplaced_monitor(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreau61d18892009-03-31 10:49:21 +0200534{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100535 return warnif_rule_after_block(proxy, file, line, arg) ||
536 warnif_misplaced_block(proxy, file, line, arg);
Willy Tarreauee445d92014-04-23 01:39:04 +0200537}
538
Willy Tarreau721d8e02017-12-01 18:25:08 +0100539/* report a warning if a "tcp request content" rule is dangerously placed */
540int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
541{
542 return warnif_rule_after_monitor(proxy, file, line, arg) ||
543 warnif_misplaced_monitor(proxy, file, line, arg);
544}
545
Willy Tarreaud39ad442016-11-25 15:16:12 +0100546/* report a warning if a "tcp request session" rule is dangerously placed */
547int warnif_misplaced_tcp_sess(struct proxy *proxy, const char *file, int line, const char *arg)
Willy Tarreauee445d92014-04-23 01:39:04 +0200548{
Willy Tarreaud39ad442016-11-25 15:16:12 +0100549 return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
550 warnif_misplaced_tcp_cont(proxy, file, line, arg);
551}
552
553/* report a warning if a "tcp request connection" rule is dangerously placed */
554int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
555{
556 return warnif_rule_after_tcp_sess(proxy, file, line, arg) ||
557 warnif_misplaced_tcp_sess(proxy, file, line, arg);
Willy Tarreau61d18892009-03-31 10:49:21 +0200558}
559
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100560/* Report it if a request ACL condition uses some keywords that are incompatible
561 * with the place where the ACL is used. It returns either 0 or ERR_WARN so that
562 * its result can be or'ed with err_code. Note that <cond> may be NULL and then
563 * will be ignored.
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100564 */
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100565static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100566{
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100567 const struct acl *acl;
Willy Tarreau93fddf12013-03-31 22:59:32 +0200568 const char *kw;
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100569
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100570 if (!cond)
Willy Tarreauf1e98b82010-01-28 17:59:39 +0100571 return 0;
572
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100573 acl = acl_cond_conflicts(cond, where);
574 if (acl) {
575 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100576 ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n",
577 file, line, acl->name, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100578 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100579 ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
580 file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100581 return ERR_WARN;
582 }
583 if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100584 return 0;
585
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100586 if (acl->name && *acl->name)
Christopher Faulet767a84b2017-11-24 16:50:31 +0100587 ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
588 file, line, acl->name, kw, sample_ckp_names(where));
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100589 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100590 ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
591 file, line, kw, sample_ckp_names(where));
Willy Tarreaufdb563c2010-01-31 15:43:27 +0100592 return ERR_WARN;
593}
594
Christopher Faulet62519022017-10-16 15:49:32 +0200595/* Parse a string representing a process number or a set of processes. It must
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100596 * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
Christopher Faulet5ab51772017-11-22 11:21:58 +0100597 * two such numbers delimited by a dash ('-'). On success, it returns
598 * 0. otherwise it returns 1 with an error message in <err>.
Christopher Faulet62519022017-10-16 15:49:32 +0200599 *
600 * Note: this function can also be used to parse a thread number or a set of
601 * threads.
602 */
Christopher Faulet26028f62017-11-22 15:01:51 +0100603int parse_process_number(const char *arg, unsigned long *proc, int *autoinc, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200604{
Christopher Faulet26028f62017-11-22 15:01:51 +0100605 if (autoinc) {
606 *autoinc = 0;
607 if (strncmp(arg, "auto:", 5) == 0) {
608 arg += 5;
609 *autoinc = 1;
610 }
611 }
612
Christopher Faulet62519022017-10-16 15:49:32 +0200613 if (strcmp(arg, "all") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100614 *proc |= ~0UL;
Christopher Faulet62519022017-10-16 15:49:32 +0200615 else if (strcmp(arg, "odd") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100616 *proc |= ~0UL/3UL; /* 0x555....555 */
Christopher Faulet62519022017-10-16 15:49:32 +0200617 else if (strcmp(arg, "even") == 0)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100618 *proc |= (~0UL/3UL) << 1; /* 0xAAA...AAA */
Christopher Faulet62519022017-10-16 15:49:32 +0200619 else {
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100620 char *dash;
621 unsigned int low, high;
622
Christopher Faulet5ab51772017-11-22 11:21:58 +0100623 if (!isdigit((int)*arg)) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100624 memprintf(err, "'%s' is not a valid number.\n", arg);
Christopher Faulet5ab51772017-11-22 11:21:58 +0100625 return -1;
626 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100627
628 low = high = str2uic(arg);
629 if ((dash = strchr(arg, '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100630 high = ((!*(dash+1)) ? LONGBITS : str2uic(dash + 1));
631
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100632 if (high < low) {
633 unsigned int swap = low;
634 low = high;
635 high = swap;
636 }
637
Christopher Faulet5ab51772017-11-22 11:21:58 +0100638 if (low < 1 || low > LONGBITS || high > LONGBITS) {
Christopher Fauletcb6a9452017-11-22 16:50:41 +0100639 memprintf(err, "'%s' is not a valid number/range."
640 " It supports numbers from 1 to %d.\n",
Christopher Faulet5ab51772017-11-22 11:21:58 +0100641 arg, LONGBITS);
642 return 1;
643 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100644
645 for (;low <= high; low++)
Christopher Faulet5ab51772017-11-22 11:21:58 +0100646 *proc |= 1UL << (low-1);
Christopher Faulet62519022017-10-16 15:49:32 +0200647 }
Christopher Faulet1dcb9cb2017-11-22 10:24:40 +0100648
Christopher Faulet5ab51772017-11-22 11:21:58 +0100649 return 0;
Christopher Faulet62519022017-10-16 15:49:32 +0200650}
651
David Carlier7e351ee2017-12-01 09:14:02 +0000652#ifdef USE_CPU_AFFINITY
Christopher Faulet62519022017-10-16 15:49:32 +0200653/* Parse cpu sets. Each CPU set is either a unique number between 0 and
654 * <LONGBITS> or a range with two such numbers delimited by a dash
655 * ('-'). Multiple CPU numbers or ranges may be specified. On success, it
656 * returns 0. otherwise it returns 1 with an error message in <err>.
657 */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100658unsigned long parse_cpu_set(const char **args, unsigned long *cpu_set, char **err)
Christopher Faulet62519022017-10-16 15:49:32 +0200659{
660 int cur_arg = 0;
661
662 *cpu_set = 0;
663 while (*args[cur_arg]) {
664 char *dash;
665 unsigned int low, high;
666
667 if (!isdigit((int)*args[cur_arg])) {
668 memprintf(err, "'%s' is not a CPU range.\n", args[cur_arg]);
669 return -1;
670 }
671
672 low = high = str2uic(args[cur_arg]);
673 if ((dash = strchr(args[cur_arg], '-')) != NULL)
Christopher Fauletff4121f2017-11-22 16:38:49 +0100674 high = ((!*(dash+1)) ? LONGBITS-1 : str2uic(dash + 1));
Christopher Faulet62519022017-10-16 15:49:32 +0200675
676 if (high < low) {
677 unsigned int swap = low;
678 low = high;
679 high = swap;
680 }
681
682 if (high >= LONGBITS) {
683 memprintf(err, "supports CPU numbers from 0 to %d.\n", LONGBITS - 1);
684 return 1;
685 }
686
687 while (low <= high)
688 *cpu_set |= 1UL << low++;
689
690 cur_arg++;
691 }
692 return 0;
693}
David Carlier7e351ee2017-12-01 09:14:02 +0000694#endif
695
Willy Tarreau915e1eb2009-06-22 15:48:36 +0200696void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +0200697{
Willy Tarreau97cb7802010-01-03 20:23:58 +0100698 init_new_proxy(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200699 defproxy.mode = PR_MODE_TCP;
700 defproxy.state = PR_STNEW;
701 defproxy.maxconn = cfg_maxpconn;
702 defproxy.conn_retries = CONN_RETRIES;
Joseph Lynch726ab712015-05-11 23:25:34 -0700703 defproxy.redispatch_after = 0;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -0400704 defproxy.lbprm.chash.balance_factor = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +0100705
Simon Horman66183002013-02-23 10:16:43 +0900706 defproxy.defsrv.check.inter = DEF_CHKINTR;
707 defproxy.defsrv.check.fastinter = 0;
708 defproxy.defsrv.check.downinter = 0;
Simon Hormand60d6912013-11-25 10:46:36 +0900709 defproxy.defsrv.agent.inter = DEF_CHKINTR;
710 defproxy.defsrv.agent.fastinter = 0;
711 defproxy.defsrv.agent.downinter = 0;
Simon Horman58c32972013-11-25 10:46:38 +0900712 defproxy.defsrv.check.rise = DEF_RISETIME;
713 defproxy.defsrv.check.fall = DEF_FALLTIME;
714 defproxy.defsrv.agent.rise = DEF_AGENT_RISETIME;
715 defproxy.defsrv.agent.fall = DEF_AGENT_FALLTIME;
Willy Tarreau5b3a2022012-09-28 15:01:02 +0200716 defproxy.defsrv.check.port = 0;
Simon Hormand60d6912013-11-25 10:46:36 +0900717 defproxy.defsrv.agent.port = 0;
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +0100718 defproxy.defsrv.maxqueue = 0;
719 defproxy.defsrv.minconn = 0;
720 defproxy.defsrv.maxconn = 0;
721 defproxy.defsrv.slowstart = 0;
722 defproxy.defsrv.onerror = DEF_HANA_ONERR;
723 defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
724 defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
Simon Horman64e34162015-02-06 11:11:57 +0900725
726 defproxy.email_alert.level = LOG_ALERT;
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +0200727 defproxy.load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200728}
729
Willy Tarreauade5ec42010-01-28 19:33:49 +0100730
Willy Tarreau63af98d2014-05-18 08:11:41 +0200731/* This function createss a new req* or rsp* rule to the proxy. It compiles the
732 * regex and may return the ERR_WARN bit, and error bits such as ERR_ALERT and
733 * ERR_FATAL in case of error.
734 */
Willy Tarreauade5ec42010-01-28 19:33:49 +0100735static int create_cond_regex_rule(const char *file, int line,
736 struct proxy *px, int dir, int action, int flags,
737 const char *cmd, const char *reg, const char *repl,
738 const char **cond_start)
739{
Thierry FOURNIER09af0d62014-06-18 11:35:54 +0200740 struct my_regex *preg = NULL;
Willy Tarreaub7451bb2012-04-27 12:38:15 +0200741 char *errmsg = NULL;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100742 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +0200743 char *error;
Willy Tarreau63af98d2014-05-18 08:11:41 +0200744 int ret_code = 0;
Willy Tarreau5321c422010-01-28 20:35:13 +0100745 struct acl_cond *cond = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +0200746 int cs;
747 int cap;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100748
749 if (px == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100750 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200751 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100752 goto err;
753 }
754
755 if (*reg == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100756 ha_alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200757 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100758 goto err;
759 }
760
Christopher Faulet898566e2016-10-26 11:06:28 +0200761 if (warnifnotcap(px, PR_CAP_FE | PR_CAP_BE, file, line, cmd, NULL))
Willy Tarreau63af98d2014-05-18 08:11:41 +0200762 ret_code |= ERR_WARN;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100763
Willy Tarreau5321c422010-01-28 20:35:13 +0100764 if (cond_start &&
765 (strcmp(*cond_start, "if") == 0 || strcmp(*cond_start, "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +0200766 if ((cond = build_acl_cond(file, line, &px->acl, px, cond_start, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100767 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
768 file, line, cmd, errmsg);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200769 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +0100770 goto err;
771 }
772 }
773 else if (cond_start && **cond_start) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100774 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
775 file, line, cmd, *cond_start);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200776 ret_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5321c422010-01-28 20:35:13 +0100777 goto err;
778 }
779
Willy Tarreau63af98d2014-05-18 08:11:41 +0200780 ret_code |= warnif_cond_conflicts(cond,
Willy Tarreaua91d0a52013-03-25 08:12:18 +0100781 (dir == SMP_OPT_DIR_REQ) ?
782 ((px->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR) :
783 ((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
784 file, line);
Willy Tarreau5321c422010-01-28 20:35:13 +0100785
Thierry FOURNIER09af0d62014-06-18 11:35:54 +0200786 preg = calloc(1, sizeof(*preg));
Willy Tarreauade5ec42010-01-28 19:33:49 +0100787 if (!preg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100788 ha_alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200789 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100790 goto err;
791 }
792
Thierry FOURNIER09af0d62014-06-18 11:35:54 +0200793 cs = !(flags & REG_ICASE);
794 cap = !(flags & REG_NOSUB);
795 error = NULL;
796 if (!regex_comp(reg, preg, cs, cap, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100797 ha_alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +0200798 free(error);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200799 ret_code = ERR_ALERT | ERR_FATAL;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100800 goto err;
801 }
802
Willy Tarreau32a6f2e2012-04-25 10:13:36 +0200803 err = chain_regex((dir == SMP_OPT_DIR_REQ) ? &px->req_exp : &px->rsp_exp,
Willy Tarreau5321c422010-01-28 20:35:13 +0100804 preg, action, repl ? strdup(repl) : NULL, cond);
Willy Tarreauade5ec42010-01-28 19:33:49 +0100805 if (repl && err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100806 ha_alert("parsing [%s:%d] : '%s' : invalid character or unterminated sequence in replacement string near '%c'.\n",
807 file, line, cmd, *err);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200808 ret_code |= ERR_ALERT | ERR_FATAL;
809 goto err_free;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100810 }
811
Willy Tarreau32a6f2e2012-04-25 10:13:36 +0200812 if (dir == SMP_OPT_DIR_REQ && warnif_misplaced_reqxxx(px, file, line, cmd))
Willy Tarreau63af98d2014-05-18 08:11:41 +0200813 ret_code |= ERR_WARN;
814
815 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100816
Willy Tarreau63af98d2014-05-18 08:11:41 +0200817 err_free:
Thierry FOURNIER09af0d62014-06-18 11:35:54 +0200818 regex_free(preg);
Willy Tarreauade5ec42010-01-28 19:33:49 +0100819 err:
820 free(preg);
Willy Tarreau63af98d2014-05-18 08:11:41 +0200821 free(errmsg);
822 return ret_code;
Willy Tarreauade5ec42010-01-28 19:33:49 +0100823}
824
Willy Tarreaubaaee002006-06-26 02:48:02 +0200825/*
William Lallemand51097192015-04-14 16:35:22 +0200826 * Parse a line in a <listen>, <frontend> or <backend> section.
Willy Tarreau93893792009-07-23 13:19:11 +0200827 * Returns the error code, 0 if OK, or any combination of :
828 * - ERR_ABORT: must abort ASAP
829 * - ERR_FATAL: we can continue parsing but not start the service
830 * - ERR_WARN: a warning has been emitted
831 * - ERR_ALERT: an alert has been emitted
832 * Only the two first ones can stop processing, the two others are just
833 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200834 */
Emeric Brun32da3c42010-09-23 18:39:19 +0200835int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
836{
837 static struct peers *curpeers = NULL;
838 struct peer *newpeer = NULL;
839 const char *err;
Willy Tarreau4348fad2012-09-20 16:48:07 +0200840 struct bind_conf *bind_conf;
841 struct listener *l;
Emeric Brun32da3c42010-09-23 18:39:19 +0200842 int err_code = 0;
Willy Tarreau902636f2013-03-10 19:44:48 +0100843 char *errmsg = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +0200844
845 if (strcmp(args[0], "peers") == 0) { /* new peers section */
Willy Tarreau0dbbf312013-03-05 11:31:55 +0100846 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100847 ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
Willy Tarreau54984722014-02-16 08:20:13 +0100848 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +0100849 goto out;
850 }
Emeric Brun32da3c42010-09-23 18:39:19 +0200851
William Lallemand6e62fb62015-04-28 16:55:23 +0200852 if (alertif_too_many_args(1, file, linenum, args, &err_code))
853 goto out;
854
Emeric Brun32da3c42010-09-23 18:39:19 +0200855 err = invalid_char(args[1]);
856 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100857 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
858 file, linenum, *err, args[0], args[1]);
Willy Tarreau54984722014-02-16 08:20:13 +0100859 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau0dbbf312013-03-05 11:31:55 +0100860 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +0200861 }
862
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +0200863 for (curpeers = cfg_peers; curpeers != NULL; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +0200864 /*
865 * If there are two proxies with the same name only following
866 * combinations are allowed:
867 */
868 if (strcmp(curpeers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100869 ha_alert("Parsing [%s:%d]: peers section '%s' has the same name as another peers section declared at %s:%d.\n",
870 file, linenum, args[1], curpeers->conf.file, curpeers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +0200871 err_code |= ERR_ALERT | ERR_FATAL;
Emeric Brun32da3c42010-09-23 18:39:19 +0200872 }
873 }
874
Vincent Bernat02779b62016-04-03 13:48:43 +0200875 if ((curpeers = calloc(1, sizeof(*curpeers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100876 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +0200877 err_code |= ERR_ALERT | ERR_ABORT;
878 goto out;
879 }
880
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +0200881 curpeers->next = cfg_peers;
882 cfg_peers = curpeers;
Willy Tarreau8113a5d2012-10-04 08:01:43 +0200883 curpeers->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +0200884 curpeers->conf.line = linenum;
885 curpeers->last_change = now.tv_sec;
886 curpeers->id = strdup(args[1]);
Willy Tarreau77e4bd12015-05-01 20:02:17 +0200887 curpeers->state = PR_STNEW;
Emeric Brun32da3c42010-09-23 18:39:19 +0200888 }
889 else if (strcmp(args[0], "peer") == 0) { /* peer definition */
David du Colombier6f5ccb12011-03-10 22:26:24 +0100890 struct sockaddr_storage *sk;
Willy Tarreau2aa38802013-02-20 19:20:59 +0100891 int port1, port2;
Willy Tarreaub36487e2013-03-10 18:37:42 +0100892 struct protocol *proto;
Emeric Brun32da3c42010-09-23 18:39:19 +0200893
894 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100895 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
896 file, linenum, args[0]);
Emeric Brun32da3c42010-09-23 18:39:19 +0200897 err_code |= ERR_ALERT | ERR_FATAL;
898 goto out;
899 }
900
901 err = invalid_char(args[1]);
902 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100903 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
904 file, linenum, *err, args[1]);
Emeric Brun32da3c42010-09-23 18:39:19 +0200905 err_code |= ERR_ALERT | ERR_FATAL;
906 goto out;
907 }
908
Vincent Bernat02779b62016-04-03 13:48:43 +0200909 if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100910 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +0200911 err_code |= ERR_ALERT | ERR_ABORT;
912 goto out;
913 }
914
915 /* the peers are linked backwards first */
916 curpeers->count++;
917 newpeer->next = curpeers->remote;
918 curpeers->remote = newpeer;
Willy Tarreau8113a5d2012-10-04 08:01:43 +0200919 newpeer->conf.file = strdup(file);
Emeric Brun32da3c42010-09-23 18:39:19 +0200920 newpeer->conf.line = linenum;
921
922 newpeer->last_change = now.tv_sec;
923 newpeer->id = strdup(args[1]);
924
Willy Tarreau48ef4c92017-01-06 18:32:38 +0100925 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau2aa38802013-02-20 19:20:59 +0100926 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100927 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau2aa38802013-02-20 19:20:59 +0100928 err_code |= ERR_ALERT | ERR_FATAL;
929 goto out;
Emeric Brun32da3c42010-09-23 18:39:19 +0200930 }
Willy Tarreaub36487e2013-03-10 18:37:42 +0100931
932 proto = protocol_by_family(sk->ss_family);
933 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100934 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
935 file, linenum, args[0], args[1]);
Willy Tarreaub36487e2013-03-10 18:37:42 +0100936 err_code |= ERR_ALERT | ERR_FATAL;
937 goto out;
938 }
Willy Tarreau2aa38802013-02-20 19:20:59 +0100939
940 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100941 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
942 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +0200943 err_code |= ERR_ALERT | ERR_FATAL;
944 goto out;
945 }
946
Willy Tarreau2aa38802013-02-20 19:20:59 +0100947 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100948 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
949 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +0200950 err_code |= ERR_ALERT | ERR_FATAL;
951 goto out;
952 }
Willy Tarreau2aa38802013-02-20 19:20:59 +0100953
Emeric Brun32da3c42010-09-23 18:39:19 +0200954 newpeer->addr = *sk;
Willy Tarreaub36487e2013-03-10 18:37:42 +0100955 newpeer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +0100956 newpeer->xprt = xprt_get(XPRT_RAW);
Willy Tarreaud02394b2012-05-11 18:32:18 +0200957 newpeer->sock_init_arg = NULL;
Christopher Faulet2a944ee2017-11-07 10:42:54 +0100958 HA_SPIN_INIT(&newpeer->lock);
Willy Tarreau26d8c592012-05-07 18:12:14 +0200959
Emeric Brun32da3c42010-09-23 18:39:19 +0200960 if (strcmp(newpeer->id, localpeer) == 0) {
961 /* Current is local peer, it define a frontend */
962 newpeer->local = 1;
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +0200963 cfg_peers->local = newpeer;
Emeric Brun32da3c42010-09-23 18:39:19 +0200964
965 if (!curpeers->peers_fe) {
966 if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +0100967 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Emeric Brun32da3c42010-09-23 18:39:19 +0200968 err_code |= ERR_ALERT | ERR_ABORT;
969 goto out;
970 }
Emeric Brun32da3c42010-09-23 18:39:19 +0200971
Willy Tarreau237250c2011-07-29 01:49:03 +0200972 init_new_proxy(curpeers->peers_fe);
973 curpeers->peers_fe->parent = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +0200974 curpeers->peers_fe->id = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +0200975 curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
976 curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
Willy Tarreau91d96282015-03-13 15:47:26 +0100977 peers_setup_frontend(curpeers->peers_fe);
Willy Tarreau4348fad2012-09-20 16:48:07 +0200978
Willy Tarreaua261e9b2016-12-22 20:44:00 +0100979 bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
Willy Tarreau4348fad2012-09-20 16:48:07 +0200980
Willy Tarreau902636f2013-03-10 19:44:48 +0100981 if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
982 if (errmsg && *errmsg) {
983 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +0100984 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +0200985 }
986 else
Christopher Faulet767a84b2017-11-24 16:50:31 +0100987 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
988 file, linenum, args[0], args[1], args[2]);
Emeric Brun32da3c42010-09-23 18:39:19 +0200989 err_code |= ERR_FATAL;
990 goto out;
991 }
Willy Tarreau4348fad2012-09-20 16:48:07 +0200992
993 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
Willy Tarreauacf3bf92013-01-18 10:51:07 +0100994 l->maxaccept = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200995 l->maxconn = curpeers->peers_fe->maxconn;
996 l->backlog = curpeers->peers_fe->backlog;
Willy Tarreau9903f0e2015-04-04 18:50:31 +0200997 l->accept = session_accept_fd;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200998 l->analysers |= curpeers->peers_fe->fe_req_ana;
999 l->default_target = curpeers->peers_fe->default_target;
Willy Tarreau4348fad2012-09-20 16:48:07 +02001000 l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
1001 global.maxsock += l->maxconn;
1002 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001003 }
Willy Tarreau8b8fd562013-01-18 11:12:27 +01001004 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001005 ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
1006 file, linenum, args[0], args[1],
1007 curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
Willy Tarreau8b8fd562013-01-18 11:12:27 +01001008 err_code |= ERR_FATAL;
1009 goto out;
1010 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001011 }
1012 } /* neither "peer" nor "peers" */
Willy Tarreau77e4bd12015-05-01 20:02:17 +02001013 else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
1014 curpeers->state = PR_STSTOPPED;
1015 }
1016 else if (!strcmp(args[0], "enabled")) { /* enables this peers section (used to revert a disabled default) */
1017 curpeers->state = PR_STNEW;
1018 }
Emeric Brun32da3c42010-09-23 18:39:19 +02001019 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001020 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Emeric Brun32da3c42010-09-23 18:39:19 +02001021 err_code |= ERR_ALERT | ERR_FATAL;
1022 goto out;
1023 }
1024
1025out:
Willy Tarreau902636f2013-03-10 19:44:48 +01001026 free(errmsg);
Emeric Brun32da3c42010-09-23 18:39:19 +02001027 return err_code;
1028}
1029
Baptiste Assmann325137d2015-04-13 23:40:55 +02001030/*
1031 * Parse a <resolvers> section.
1032 * Returns the error code, 0 if OK, or any combination of :
1033 * - ERR_ABORT: must abort ASAP
1034 * - ERR_FATAL: we can continue parsing but not start the service
1035 * - ERR_WARN: a warning has been emitted
1036 * - ERR_ALERT: an alert has been emitted
1037 * Only the two first ones can stop processing, the two others are just
1038 * indicators.
1039 */
1040int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
1041{
1042 static struct dns_resolvers *curr_resolvers = NULL;
1043 struct dns_nameserver *newnameserver = NULL;
1044 const char *err;
1045 int err_code = 0;
1046 char *errmsg = NULL;
1047
1048 if (strcmp(args[0], "resolvers") == 0) { /* new resolvers section */
1049 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001050 ha_alert("parsing [%s:%d] : missing name for resolvers section.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001051 err_code |= ERR_ALERT | ERR_ABORT;
1052 goto out;
1053 }
1054
1055 err = invalid_char(args[1]);
1056 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001057 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1058 file, linenum, *err, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001059 err_code |= ERR_ALERT | ERR_ABORT;
1060 goto out;
1061 }
1062
1063 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
1064 /* Error if two resolvers owns the same name */
1065 if (strcmp(curr_resolvers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001066 ha_alert("Parsing [%s:%d]: resolvers '%s' has same name as another resolvers (declared at %s:%d).\n",
1067 file, linenum, args[1], curr_resolvers->conf.file, curr_resolvers->conf.line);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001068 err_code |= ERR_ALERT | ERR_ABORT;
1069 }
1070 }
1071
Vincent Bernat02779b62016-04-03 13:48:43 +02001072 if ((curr_resolvers = calloc(1, sizeof(*curr_resolvers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001073 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001074 err_code |= ERR_ALERT | ERR_ABORT;
1075 goto out;
1076 }
1077
1078 /* default values */
1079 LIST_ADDQ(&dns_resolvers, &curr_resolvers->list);
1080 curr_resolvers->conf.file = strdup(file);
1081 curr_resolvers->conf.line = linenum;
1082 curr_resolvers->id = strdup(args[1]);
1083 curr_resolvers->query_ids = EB_ROOT;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02001084 /* default maximum response size */
1085 curr_resolvers->accepted_payload_size = 512;
Baptiste Assmann987e16d2016-11-02 22:23:31 +01001086 /* default hold period for nx, other, refuse and timeout is 30s */
1087 curr_resolvers->hold.nx = 30000;
1088 curr_resolvers->hold.other = 30000;
1089 curr_resolvers->hold.refused = 30000;
1090 curr_resolvers->hold.timeout = 30000;
Baptiste Assmann686408b2017-08-18 10:15:42 +02001091 curr_resolvers->hold.obsolete = 0;
Baptiste Assmann325137d2015-04-13 23:40:55 +02001092 /* default hold period for valid is 10s */
Baptiste Assmann4c5490a2015-07-14 21:42:49 +02001093 curr_resolvers->hold.valid = 10000;
Christopher Faulet67957bd2017-09-27 11:00:59 +02001094 curr_resolvers->timeout.resolve = 1000;
1095 curr_resolvers->timeout.retry = 1000;
Baptiste Assmann325137d2015-04-13 23:40:55 +02001096 curr_resolvers->resolve_retries = 3;
Christopher Faulet67957bd2017-09-27 11:00:59 +02001097 curr_resolvers->nb_nameservers = 0;
1098 LIST_INIT(&curr_resolvers->nameservers);
1099 LIST_INIT(&curr_resolvers->resolutions.curr);
1100 LIST_INIT(&curr_resolvers->resolutions.wait);
Christopher Faulet2a944ee2017-11-07 10:42:54 +01001101 HA_SPIN_INIT(&curr_resolvers->lock);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001102 }
1103 else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
1104 struct sockaddr_storage *sk;
1105 int port1, port2;
1106 struct protocol *proto;
1107
1108 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001109 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
1110 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001111 err_code |= ERR_ALERT | ERR_FATAL;
1112 goto out;
1113 }
1114
1115 err = invalid_char(args[1]);
1116 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001117 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
1118 file, linenum, *err, args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001119 err_code |= ERR_ALERT | ERR_FATAL;
1120 goto out;
1121 }
1122
Christopher Faulet67957bd2017-09-27 11:00:59 +02001123 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
Baptiste Assmanna315c552015-11-02 22:55:49 +01001124 /* Error if two resolvers owns the same name */
1125 if (strcmp(newnameserver->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001126 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 -06001127 file, linenum, args[1], newnameserver->conf.file, newnameserver->conf.line);
Baptiste Assmanna315c552015-11-02 22:55:49 +01001128 err_code |= ERR_ALERT | ERR_FATAL;
1129 }
1130 }
1131
Vincent Bernat02779b62016-04-03 13:48:43 +02001132 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001133 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001134 err_code |= ERR_ALERT | ERR_ABORT;
1135 goto out;
1136 }
1137
1138 /* the nameservers are linked backward first */
Christopher Faulet67957bd2017-09-27 11:00:59 +02001139 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001140 newnameserver->resolvers = curr_resolvers;
1141 newnameserver->conf.file = strdup(file);
1142 newnameserver->conf.line = linenum;
1143 newnameserver->id = strdup(args[1]);
1144
Willy Tarreau48ef4c92017-01-06 18:32:38 +01001145 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001146 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001147 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001148 err_code |= ERR_ALERT | ERR_FATAL;
1149 goto out;
1150 }
1151
1152 proto = protocol_by_family(sk->ss_family);
1153 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001154 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
Baptiste Assmann325137d2015-04-13 23:40:55 +02001155 file, linenum, args[0], args[1]);
1156 err_code |= ERR_ALERT | ERR_FATAL;
1157 goto out;
1158 }
1159
1160 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001161 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
1162 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001163 err_code |= ERR_ALERT | ERR_FATAL;
1164 goto out;
1165 }
1166
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01001167 if (!port1 && !port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001168 ha_alert("parsing [%s:%d] : '%s %s' : no UDP port specified\n",
1169 file, linenum, args[0], args[1]);
Baptiste Assmann7f43fa92016-01-21 00:59:46 +01001170 err_code |= ERR_ALERT | ERR_FATAL;
1171 goto out;
1172 }
1173
Baptiste Assmann325137d2015-04-13 23:40:55 +02001174 newnameserver->addr = *sk;
1175 }
Ben Draut44e609b2018-05-29 15:40:08 -06001176 else if (strcmp(args[0], "parse-resolv-conf") == 0) {
1177 const char *whitespace = "\r\n\t ";
1178 char *resolv_line = NULL;
1179 int resolv_linenum = 0;
1180 FILE *f = NULL;
1181 char *address = NULL;
1182 struct sockaddr_storage *sk = NULL;
1183 struct protocol *proto;
1184 int duplicate_name = 0;
1185
1186 if ((resolv_line = malloc(sizeof(*resolv_line) * LINESIZE)) == NULL) {
1187 ha_alert("parsing [%s:%d] : out of memory.\n",
1188 file, linenum);
1189 err_code |= ERR_ALERT | ERR_FATAL;
1190 goto resolv_out;
1191 }
1192
1193 if ((f = fopen("/etc/resolv.conf", "r")) == NULL) {
1194 ha_alert("parsing [%s:%d] : failed to open /etc/resolv.conf.\n",
1195 file, linenum);
1196 err_code |= ERR_ALERT | ERR_FATAL;
1197 goto resolv_out;
1198 }
1199
1200 sk = calloc(1, sizeof(*sk));
1201 if (sk == NULL) {
1202 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n",
1203 resolv_linenum);
1204 err_code |= ERR_ALERT | ERR_FATAL;
1205 goto resolv_out;
1206 }
1207
1208 while (fgets(resolv_line, LINESIZE, f) != NULL) {
1209 resolv_linenum++;
1210 if (strncmp(resolv_line, "nameserver", 10) != 0)
1211 continue;
1212
1213 address = strtok(resolv_line + 10, whitespace);
1214 if (address == resolv_line + 10)
1215 continue;
1216
1217 if (address == NULL) {
1218 ha_warning("parsing [/etc/resolv.conf:%d] : nameserver line is missing address.\n",
1219 resolv_linenum);
1220 err_code |= ERR_WARN;
1221 continue;
1222 }
1223
1224 duplicate_name = 0;
1225 list_for_each_entry(newnameserver, &curr_resolvers->nameservers, list) {
1226 if (strcmp(newnameserver->id, address) == 0) {
1227 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",
1228 resolv_linenum, address, newnameserver->conf.file, newnameserver->conf.line);
1229 err_code |= ERR_WARN;
1230 duplicate_name = 1;
1231 }
1232 }
1233
1234 if (duplicate_name)
1235 continue;
1236
1237 memset(sk, 0, sizeof(*sk));
1238 sk = str2ip2(address, sk, 1);
1239 if (!sk) {
1240 ha_warning("parsing [/etc/resolv.conf:%d] : address '%s' could not be recognized, namerserver will be excluded.\n",
1241 resolv_linenum, address);
1242 err_code |= ERR_WARN;
1243 continue;
1244 }
1245
1246 set_host_port(sk, 53);
1247
1248 proto = protocol_by_family(sk->ss_family);
1249 if (!proto || !proto->connect) {
1250 ha_warning("parsing [/etc/resolv.conf:%d] : '%s' : connect() not supported for this address family.\n",
1251 resolv_linenum, address);
1252 err_code |= ERR_WARN;
1253 continue;
1254 }
1255
1256 if ((newnameserver = calloc(1, sizeof(*newnameserver))) == NULL) {
1257 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
1258 err_code |= ERR_ALERT | ERR_FATAL;
1259 goto resolv_out;
1260 }
1261
1262 newnameserver->conf.file = strdup("/etc/resolv.conf");
1263 if (newnameserver->conf.file == NULL) {
1264 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
1265 err_code |= ERR_ALERT | ERR_FATAL;
1266 goto resolv_out;
1267 }
1268
1269 newnameserver->id = strdup(address);
1270 if (newnameserver->id == NULL) {
1271 ha_alert("parsing [/etc/resolv.conf:%d] : out of memory.\n", resolv_linenum);
1272 err_code |= ERR_ALERT | ERR_FATAL;
1273 goto resolv_out;
1274 }
1275
1276 newnameserver->resolvers = curr_resolvers;
1277 newnameserver->conf.line = resolv_linenum;
1278 newnameserver->addr = *sk;
1279
1280 LIST_ADDQ(&curr_resolvers->nameservers, &newnameserver->list);
1281 }
1282
1283resolv_out:
1284 free(sk);
1285 free(resolv_line);
1286 if (f != NULL)
1287 fclose(f);
1288 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02001289 else if (strcmp(args[0], "hold") == 0) { /* hold periods */
1290 const char *res;
1291 unsigned int time;
1292
1293 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001294 ha_alert("parsing [%s:%d] : '%s' expects an <event> and a <time> as arguments.\n",
1295 file, linenum, args[0]);
1296 ha_alert("<event> can be either 'valid', 'nx', 'refused', 'timeout', or 'other'\n");
Baptiste Assmann325137d2015-04-13 23:40:55 +02001297 err_code |= ERR_ALERT | ERR_FATAL;
1298 goto out;
1299 }
1300 res = parse_time_err(args[2], &time, TIME_UNIT_MS);
1301 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001302 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
1303 file, linenum, *res, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001304 err_code |= ERR_ALERT | ERR_FATAL;
1305 goto out;
1306 }
Baptiste Assmann987e16d2016-11-02 22:23:31 +01001307 if (strcmp(args[1], "nx") == 0)
1308 curr_resolvers->hold.nx = time;
1309 else if (strcmp(args[1], "other") == 0)
1310 curr_resolvers->hold.other = time;
1311 else if (strcmp(args[1], "refused") == 0)
1312 curr_resolvers->hold.refused = time;
1313 else if (strcmp(args[1], "timeout") == 0)
1314 curr_resolvers->hold.timeout = time;
1315 else if (strcmp(args[1], "valid") == 0)
Baptiste Assmann325137d2015-04-13 23:40:55 +02001316 curr_resolvers->hold.valid = time;
Olivier Houcharda8c6db82017-07-06 18:46:47 +02001317 else if (strcmp(args[1], "obsolete") == 0)
1318 curr_resolvers->hold.obsolete = time;
Baptiste Assmann325137d2015-04-13 23:40:55 +02001319 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001320 ha_alert("parsing [%s:%d] : '%s' unknown <event>: '%s', expects either 'nx', 'timeout', 'valid', 'obsolete' or 'other'.\n",
1321 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001322 err_code |= ERR_ALERT | ERR_FATAL;
1323 goto out;
1324 }
1325
1326 }
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02001327 else if (strcmp(args[0], "accepted_payload_size") == 0) {
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02001328 int i = 0;
1329
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02001330 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001331 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
1332 file, linenum, args[0]);
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02001333 err_code |= ERR_ALERT | ERR_FATAL;
1334 goto out;
1335 }
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02001336
1337 i = atoi(args[1]);
Willy Tarreau0c219be2017-08-22 12:01:26 +02001338 if (i < DNS_HEADER_SIZE || i > DNS_MAX_UDP_MESSAGE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001339 ha_alert("parsing [%s:%d] : '%s' must be between %d and %d inclusive (was %s).\n",
1340 file, linenum, args[0], DNS_HEADER_SIZE, DNS_MAX_UDP_MESSAGE, args[1]);
Baptiste Assmann9d8dbbc2017-08-18 23:35:08 +02001341 err_code |= ERR_ALERT | ERR_FATAL;
1342 goto out;
1343 }
1344
1345 curr_resolvers->accepted_payload_size = i;
Baptiste Assmann2af08fe2017-08-14 00:13:01 +02001346 }
Baptiste Assmann201c07f2017-05-22 15:17:15 +02001347 else if (strcmp(args[0], "resolution_pool_size") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001348 ha_warning("parsing [%s:%d] : '%s' directive is now deprecated and ignored.\n",
1349 file, linenum, args[0]);
Christopher Faulet67957bd2017-09-27 11:00:59 +02001350 err_code |= ERR_WARN;
1351 goto out;
Baptiste Assmann201c07f2017-05-22 15:17:15 +02001352 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02001353 else if (strcmp(args[0], "resolve_retries") == 0) {
1354 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001355 ha_alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
1356 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001357 err_code |= ERR_ALERT | ERR_FATAL;
1358 goto out;
1359 }
1360 curr_resolvers->resolve_retries = atoi(args[1]);
1361 }
1362 else if (strcmp(args[0], "timeout") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01001363 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001364 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments.\n",
1365 file, linenum, args[0]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001366 err_code |= ERR_ALERT | ERR_FATAL;
1367 goto out;
1368 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02001369 else if (strcmp(args[1], "retry") == 0 ||
1370 strcmp(args[1], "resolve") == 0) {
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01001371 const char *res;
Christopher Faulet67957bd2017-09-27 11:00:59 +02001372 unsigned int tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01001373
1374 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001375 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
1376 file, linenum, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01001377 err_code |= ERR_ALERT | ERR_FATAL;
1378 goto out;
1379 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02001380 res = parse_time_err(args[2], &tout, TIME_UNIT_MS);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01001381 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001382 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s %s>.\n",
1383 file, linenum, *res, args[0], args[1]);
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01001384 err_code |= ERR_ALERT | ERR_FATAL;
1385 goto out;
1386 }
Christopher Faulet67957bd2017-09-27 11:00:59 +02001387 if (args[1][2] == 't')
1388 curr_resolvers->timeout.retry = tout;
1389 else
1390 curr_resolvers->timeout.resolve = tout;
Pieter Baauw7a91a0e2016-02-13 15:51:58 +01001391 }
1392 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001393 ha_alert("parsing [%s:%d] : '%s' expects 'retry' or 'resolve' and <time> as arguments got '%s'.\n",
1394 file, linenum, args[0], args[1]);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001395 err_code |= ERR_ALERT | ERR_FATAL;
1396 goto out;
1397 }
Baptiste Assmann325137d2015-04-13 23:40:55 +02001398 } /* neither "nameserver" nor "resolvers" */
1399 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001400 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Baptiste Assmann325137d2015-04-13 23:40:55 +02001401 err_code |= ERR_ALERT | ERR_FATAL;
1402 goto out;
1403 }
1404
1405 out:
1406 free(errmsg);
1407 return err_code;
1408}
Simon Horman0d16a402015-01-30 11:22:58 +09001409
1410/*
William Lallemand51097192015-04-14 16:35:22 +02001411 * Parse a line in a <listen>, <frontend> or <backend> section.
Simon Horman0d16a402015-01-30 11:22:58 +09001412 * Returns the error code, 0 if OK, or any combination of :
1413 * - ERR_ABORT: must abort ASAP
1414 * - ERR_FATAL: we can continue parsing but not start the service
1415 * - ERR_WARN: a warning has been emitted
1416 * - ERR_ALERT: an alert has been emitted
1417 * Only the two first ones can stop processing, the two others are just
1418 * indicators.
1419 */
1420int cfg_parse_mailers(const char *file, int linenum, char **args, int kwm)
1421{
1422 static struct mailers *curmailers = NULL;
1423 struct mailer *newmailer = NULL;
1424 const char *err;
1425 int err_code = 0;
1426 char *errmsg = NULL;
1427
1428 if (strcmp(args[0], "mailers") == 0) { /* new mailers section */
1429 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001430 ha_alert("parsing [%s:%d] : missing name for mailers section.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09001431 err_code |= ERR_ALERT | ERR_ABORT;
1432 goto out;
1433 }
1434
1435 err = invalid_char(args[1]);
1436 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001437 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1438 file, linenum, *err, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09001439 err_code |= ERR_ALERT | ERR_ABORT;
1440 goto out;
1441 }
1442
1443 for (curmailers = mailers; curmailers != NULL; curmailers = curmailers->next) {
1444 /*
1445 * If there are two proxies with the same name only following
1446 * combinations are allowed:
1447 */
1448 if (strcmp(curmailers->id, args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001449 ha_alert("Parsing [%s:%d]: mailers section '%s' has the same name as another mailers section declared at %s:%d.\n",
1450 file, linenum, args[1], curmailers->conf.file, curmailers->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02001451 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman0d16a402015-01-30 11:22:58 +09001452 }
1453 }
1454
Vincent Bernat02779b62016-04-03 13:48:43 +02001455 if ((curmailers = calloc(1, sizeof(*curmailers))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001456 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09001457 err_code |= ERR_ALERT | ERR_ABORT;
1458 goto out;
1459 }
1460
1461 curmailers->next = mailers;
1462 mailers = curmailers;
1463 curmailers->conf.file = strdup(file);
1464 curmailers->conf.line = linenum;
1465 curmailers->id = strdup(args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01001466 curmailers->timeout.mail = DEF_MAILALERTTIME;/* XXX: Would like to Skip to the next alert, if any, ASAP.
1467 * But need enough time so that timeouts don't occur
1468 * during tcp procssing. For now just us an arbitrary default. */
Simon Horman0d16a402015-01-30 11:22:58 +09001469 }
1470 else if (strcmp(args[0], "mailer") == 0) { /* mailer definition */
1471 struct sockaddr_storage *sk;
1472 int port1, port2;
1473 struct protocol *proto;
1474
1475 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001476 ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
1477 file, linenum, args[0]);
Simon Horman0d16a402015-01-30 11:22:58 +09001478 err_code |= ERR_ALERT | ERR_FATAL;
1479 goto out;
1480 }
1481
1482 err = invalid_char(args[1]);
1483 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001484 ha_alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
1485 file, linenum, *err, args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09001486 err_code |= ERR_ALERT | ERR_FATAL;
1487 goto out;
1488 }
1489
Vincent Bernat02779b62016-04-03 13:48:43 +02001490 if ((newmailer = calloc(1, sizeof(*newmailer))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001491 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Simon Horman0d16a402015-01-30 11:22:58 +09001492 err_code |= ERR_ALERT | ERR_ABORT;
1493 goto out;
1494 }
1495
1496 /* the mailers are linked backwards first */
1497 curmailers->count++;
1498 newmailer->next = curmailers->mailer_list;
1499 curmailers->mailer_list = newmailer;
1500 newmailer->mailers = curmailers;
1501 newmailer->conf.file = strdup(file);
1502 newmailer->conf.line = linenum;
1503
1504 newmailer->id = strdup(args[1]);
1505
Willy Tarreau48ef4c92017-01-06 18:32:38 +01001506 sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Simon Horman0d16a402015-01-30 11:22:58 +09001507 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001508 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
Simon Horman0d16a402015-01-30 11:22:58 +09001509 err_code |= ERR_ALERT | ERR_FATAL;
1510 goto out;
1511 }
1512
1513 proto = protocol_by_family(sk->ss_family);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09001514 if (!proto || !proto->connect || proto->sock_prot != IPPROTO_TCP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001515 ha_alert("parsing [%s:%d] : '%s %s' : TCP not supported for this address family.\n",
1516 file, linenum, args[0], args[1]);
Simon Horman0d16a402015-01-30 11:22:58 +09001517 err_code |= ERR_ALERT | ERR_FATAL;
1518 goto out;
1519 }
1520
1521 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001522 ha_alert("parsing [%s:%d] : '%s %s' : port ranges and offsets are not allowed in '%s'\n",
1523 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09001524 err_code |= ERR_ALERT | ERR_FATAL;
1525 goto out;
1526 }
1527
1528 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001529 ha_alert("parsing [%s:%d] : '%s %s' : missing or invalid port in '%s'\n",
1530 file, linenum, args[0], args[1], args[2]);
Simon Horman0d16a402015-01-30 11:22:58 +09001531 err_code |= ERR_ALERT | ERR_FATAL;
1532 goto out;
1533 }
1534
1535 newmailer->addr = *sk;
1536 newmailer->proto = proto;
Willy Tarreaua261e9b2016-12-22 20:44:00 +01001537 newmailer->xprt = xprt_get(XPRT_RAW);
Simon Horman0d16a402015-01-30 11:22:58 +09001538 newmailer->sock_init_arg = NULL;
Pieter Baauw235fcfc2016-02-13 15:33:40 +01001539 }
1540 else if (strcmp(args[0], "timeout") == 0) {
1541 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001542 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments.\n",
1543 file, linenum, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01001544 err_code |= ERR_ALERT | ERR_FATAL;
1545 goto out;
1546 }
1547 else if (strcmp(args[1], "mail") == 0) {
1548 const char *res;
1549 unsigned int timeout_mail;
1550 if (!*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001551 ha_alert("parsing [%s:%d] : '%s %s' expects <time> as argument.\n",
1552 file, linenum, args[0], args[1]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01001553 err_code |= ERR_ALERT | ERR_FATAL;
1554 goto out;
1555 }
1556 res = parse_time_err(args[2], &timeout_mail, TIME_UNIT_MS);
1557 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001558 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
1559 file, linenum, *res, args[0]);
Pieter Baauw235fcfc2016-02-13 15:33:40 +01001560 err_code |= ERR_ALERT | ERR_FATAL;
1561 goto out;
1562 }
1563 if (timeout_mail <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001564 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 +01001565 err_code |= ERR_ALERT | ERR_FATAL;
1566 goto out;
1567 }
1568 curmailers->timeout.mail = timeout_mail;
1569 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001570 ha_alert("parsing [%s:%d] : '%s' expects 'mail' and <time> as arguments got '%s'.\n",
Pieter Baauw235fcfc2016-02-13 15:33:40 +01001571 file, linenum, args[0], args[1]);
1572 err_code |= ERR_ALERT | ERR_FATAL;
1573 goto out;
1574 }
1575 }
Simon Horman0d16a402015-01-30 11:22:58 +09001576 else if (*args[0] != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001577 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Simon Horman0d16a402015-01-30 11:22:58 +09001578 err_code |= ERR_ALERT | ERR_FATAL;
1579 goto out;
1580 }
1581
1582out:
1583 free(errmsg);
1584 return err_code;
1585}
1586
Simon Horman9dc49962015-01-30 11:22:59 +09001587static void free_email_alert(struct proxy *p)
1588{
1589 free(p->email_alert.mailers.name);
1590 p->email_alert.mailers.name = NULL;
1591 free(p->email_alert.from);
1592 p->email_alert.from = NULL;
1593 free(p->email_alert.to);
1594 p->email_alert.to = NULL;
1595 free(p->email_alert.myhostname);
1596 p->email_alert.myhostname = NULL;
1597}
1598
Willy Tarreau3842f002009-06-14 11:39:52 +02001599int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +02001600{
1601 static struct proxy *curproxy = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +02001602 const char *err;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001603 char *error;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01001604 int rc;
1605 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +02001606 int err_code = 0;
Willy Tarreau3ec18a02010-01-28 19:01:34 +01001607 struct acl_cond *cond = NULL;
William Lallemand723b73a2012-02-08 16:37:49 +01001608 struct logsrv *tmplogsrv;
Willy Tarreauf4068b62012-05-08 17:37:49 +02001609 char *errmsg = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001610 struct bind_conf *bind_conf;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001611
Willy Tarreau977b8e42006-12-29 14:19:17 +01001612 if (!strcmp(args[0], "listen"))
1613 rc = PR_CAP_LISTEN;
1614 else if (!strcmp(args[0], "frontend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02001615 rc = PR_CAP_FE;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02001616 else if (!strcmp(args[0], "backend"))
Christopher Faulet898566e2016-10-26 11:06:28 +02001617 rc = PR_CAP_BE;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001618 else
1619 rc = PR_CAP_NONE;
1620
1621 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02001622 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001623 ha_alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
1624 " optionally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
1625 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001626 err_code |= ERR_ALERT | ERR_ABORT;
1627 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001628 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02001629
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01001630 err = invalid_char(args[1]);
1631 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001632 ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
1633 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001634 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01001635 }
1636
Willy Tarreau8f50b682015-05-26 11:45:02 +02001637 curproxy = (rc & PR_CAP_FE) ? proxy_fe_by_name(args[1]) : proxy_be_by_name(args[1]);
1638 if (curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001639 ha_alert("Parsing [%s:%d]: %s '%s' has the same name as %s '%s' declared at %s:%d.\n",
1640 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy),
1641 curproxy->id, curproxy->conf.file, curproxy->conf.line);
Willy Tarreau911fa2e2015-05-26 10:35:50 +02001642 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +02001643 }
1644
Vincent Bernat02779b62016-04-03 13:48:43 +02001645 if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001646 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001647 err_code |= ERR_ALERT | ERR_ABORT;
1648 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001649 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +01001650
Willy Tarreau97cb7802010-01-03 20:23:58 +01001651 init_new_proxy(curproxy);
Olivier Houchardfbc74e82017-11-24 16:54:05 +01001652 curproxy->next = proxies_list;
1653 proxies_list = curproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02001654 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
1655 curproxy->conf.args.line = curproxy->conf.line = linenum;
Krzysztof Oledzki85130942007-10-22 16:21:10 +02001656 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001657 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +01001658 curproxy->cap = rc;
Willy Tarreauf79d9502014-03-15 07:22:35 +01001659 proxy_store_name(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001660
William Lallemand6e62fb62015-04-28 16:55:23 +02001661 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
1662 if (curproxy->cap & PR_CAP_FE)
Christopher Faulet767a84b2017-11-24 16:50:31 +01001663 ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum);
William Lallemand6e62fb62015-04-28 16:55:23 +02001664 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001665 }
1666
1667 /* set default values */
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001668 memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
Willy Tarreau70160202010-04-07 16:06:40 +02001669 curproxy->defsrv.id = "default-server";
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01001670
Willy Tarreaubaaee002006-06-26 02:48:02 +02001671 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001672 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01001673 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +02001674 curproxy->no_options = defproxy.no_options;
1675 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01001676 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02001677 curproxy->except_net = defproxy.except_net;
1678 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +02001679 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +02001680 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001681
Willy Tarreau79f5fe82008-08-23 08:18:21 +02001682 if (defproxy.fwdfor_hdr_len) {
1683 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
1684 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
1685 }
1686
Willy Tarreaub86db342009-11-30 11:50:16 +01001687 if (defproxy.orgto_hdr_len) {
1688 curproxy->orgto_hdr_len = defproxy.orgto_hdr_len;
1689 curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name);
1690 }
1691
Mark Lamourinec2247f02012-01-04 13:02:01 -05001692 if (defproxy.server_id_hdr_len) {
1693 curproxy->server_id_hdr_len = defproxy.server_id_hdr_len;
1694 curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name);
1695 }
1696
Christopher Faulet6b449752018-11-12 11:57:31 +01001697 /* initialize error relocations */
1698 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
1699 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
1700
Willy Tarreau977b8e42006-12-29 14:19:17 +01001701 if (curproxy->cap & PR_CAP_FE) {
1702 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01001703 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +02001704 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001705
Willy Tarreau977b8e42006-12-29 14:19:17 +01001706 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
1707 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001708
Willy Tarreau977b8e42006-12-29 14:19:17 +01001709 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau743c1282014-11-18 15:04:29 +01001710 curproxy->lbprm.algo = defproxy.lbprm.algo;
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04001711 curproxy->lbprm.chash.balance_factor = defproxy.lbprm.chash.balance_factor;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001712 curproxy->fullconn = defproxy.fullconn;
1713 curproxy->conn_retries = defproxy.conn_retries;
Joseph Lynch726ab712015-05-11 23:25:34 -07001714 curproxy->redispatch_after = defproxy.redispatch_after;
Willy Tarreauc35362a2014-04-25 13:58:37 +02001715 curproxy->max_ka_queue = defproxy.max_ka_queue;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001716
Willy Tarreauaa2f3892010-10-22 16:15:31 +02001717 if (defproxy.check_req) {
1718 curproxy->check_req = calloc(1, defproxy.check_len);
1719 memcpy(curproxy->check_req, defproxy.check_req, defproxy.check_len);
1720 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01001721 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001722
Willy Tarreau1ee51a62011-08-19 20:04:17 +02001723 if (defproxy.expect_str) {
1724 curproxy->expect_str = strdup(defproxy.expect_str);
1725 if (defproxy.expect_regex) {
1726 /* note: this regex is known to be valid */
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001727 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
1728 regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
Willy Tarreau1ee51a62011-08-19 20:04:17 +02001729 }
1730 }
1731
Willy Tarreau67402132012-05-31 20:40:20 +02001732 curproxy->ck_opts = defproxy.ck_opts;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001733 if (defproxy.cookie_name)
1734 curproxy->cookie_name = strdup(defproxy.cookie_name);
1735 curproxy->cookie_len = defproxy.cookie_len;
Olivier Houchard4e694042017-03-14 20:01:29 +01001736
1737 if (defproxy.dyncookie_key)
1738 curproxy->dyncookie_key = strdup(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01001739 if (defproxy.cookie_domain)
1740 curproxy->cookie_domain = strdup(defproxy.cookie_domain);
Willy Tarreau01732802007-11-01 22:48:15 +01001741
Willy Tarreau31936852010-10-06 16:59:56 +02001742 if (defproxy.cookie_maxidle)
1743 curproxy->cookie_maxidle = defproxy.cookie_maxidle;
1744
1745 if (defproxy.cookie_maxlife)
1746 curproxy->cookie_maxlife = defproxy.cookie_maxlife;
1747
Emeric Brun647caf12009-06-30 17:57:00 +02001748 if (defproxy.rdp_cookie_name)
1749 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
1750 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
1751
Willy Tarreau01732802007-11-01 22:48:15 +01001752 if (defproxy.url_param_name)
1753 curproxy->url_param_name = strdup(defproxy.url_param_name);
1754 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01001755
Benoitaffb4812009-03-25 13:02:10 +01001756 if (defproxy.hh_name)
1757 curproxy->hh_name = strdup(defproxy.hh_name);
1758 curproxy->hh_len = defproxy.hh_len;
1759 curproxy->hh_match_domain = defproxy.hh_match_domain;
1760
Willy Tarreauef9a3602012-12-08 22:29:20 +01001761 if (defproxy.conn_src.iface_name)
1762 curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name);
1763 curproxy->conn_src.iface_len = defproxy.conn_src.iface_len;
Godbach9f048532013-04-23 15:27:57 +08001764 curproxy->conn_src.opts = defproxy.conn_src.opts;
Willy Tarreau29fbe512015-08-20 19:35:14 +02001765#if defined(CONFIG_HAP_TRANSPARENT)
Godbach9f048532013-04-23 15:27:57 +08001766 curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr;
Willy Tarreauc621d362013-04-25 17:35:22 +02001767#endif
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02001768 curproxy->load_server_state_from_file = defproxy.load_server_state_from_file;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001769 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001770
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02001771 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01001772 if (defproxy.capture_name)
1773 curproxy->capture_name = strdup(defproxy.capture_name);
1774 curproxy->capture_namelen = defproxy.capture_namelen;
1775 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +01001776 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001777
Willy Tarreau977b8e42006-12-29 14:19:17 +01001778 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01001779 curproxy->timeout.client = defproxy.timeout.client;
Simone Gotti1b48cc92014-06-11 12:25:28 +02001780 curproxy->timeout.clientfin = defproxy.timeout.clientfin;
Willy Tarreau1fa31262007-12-03 00:36:16 +01001781 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +01001782 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01001783 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001784 curproxy->mon_net = defproxy.mon_net;
1785 curproxy->mon_mask = defproxy.mon_mask;
1786 if (defproxy.monitor_uri)
1787 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
1788 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01001789 if (defproxy.defbe.name)
1790 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau99a7ca22012-05-31 19:39:23 +02001791
1792 /* get either a pointer to the logformat string or a copy of it */
Willy Tarreau62a61232013-04-12 18:13:46 +02001793 curproxy->conf.logformat_string = defproxy.conf.logformat_string;
1794 if (curproxy->conf.logformat_string &&
1795 curproxy->conf.logformat_string != default_http_log_format &&
1796 curproxy->conf.logformat_string != default_tcp_log_format &&
1797 curproxy->conf.logformat_string != clf_http_log_format)
1798 curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string);
1799
1800 if (defproxy.conf.lfs_file) {
1801 curproxy->conf.lfs_file = strdup(defproxy.conf.lfs_file);
1802 curproxy->conf.lfs_line = defproxy.conf.lfs_line;
1803 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02001804
1805 /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */
1806 curproxy->conf.logformat_sd_string = defproxy.conf.logformat_sd_string;
1807 if (curproxy->conf.logformat_sd_string &&
1808 curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
1809 curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string);
1810
1811 if (defproxy.conf.lfsd_file) {
1812 curproxy->conf.lfsd_file = strdup(defproxy.conf.lfsd_file);
1813 curproxy->conf.lfsd_line = defproxy.conf.lfsd_line;
1814 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01001815 }
1816
1817 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +01001818 curproxy->timeout.connect = defproxy.timeout.connect;
1819 curproxy->timeout.server = defproxy.timeout.server;
Simone Gotti1b48cc92014-06-11 12:25:28 +02001820 curproxy->timeout.serverfin = defproxy.timeout.serverfin;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01001821 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +01001822 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +01001823 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +02001824 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreaub16a5742010-01-10 14:46:16 +01001825 curproxy->timeout.httpka = defproxy.timeout.httpka;
Willy Tarreauce887fd2012-05-12 12:50:00 +02001826 curproxy->timeout.tunnel = defproxy.timeout.tunnel;
Willy Tarreauef9a3602012-12-08 22:29:20 +01001827 curproxy->conn_src.source_addr = defproxy.conn_src.source_addr;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001828 }
1829
Willy Tarreaubaaee002006-06-26 02:48:02 +02001830 curproxy->mode = defproxy.mode;
Willy Tarreaued2119c2014-04-24 22:10:39 +02001831 curproxy->uri_auth = defproxy.uri_auth; /* for stats */
William Lallemand0f99e342011-10-12 17:50:54 +02001832
1833 /* copy default logsrvs to curproxy */
William Lallemand723b73a2012-02-08 16:37:49 +01001834 list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) {
Vincent Bernat02779b62016-04-03 13:48:43 +02001835 struct logsrv *node = malloc(sizeof(*node));
William Lallemand723b73a2012-02-08 16:37:49 +01001836 memcpy(node, tmplogsrv, sizeof(struct logsrv));
Christopher Faulet28ac0992018-03-26 16:09:19 +02001837 node->ref = tmplogsrv->ref;
William Lallemand0f99e342011-10-12 17:50:54 +02001838 LIST_INIT(&node->list);
1839 LIST_ADDQ(&curproxy->logsrvs, &node->list);
1840 }
1841
Willy Tarreau62a61232013-04-12 18:13:46 +02001842 curproxy->conf.uniqueid_format_string = defproxy.conf.uniqueid_format_string;
1843 if (curproxy->conf.uniqueid_format_string)
1844 curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string);
1845
Dragan Dosen43885c72015-10-01 13:18:13 +02001846 chunk_dup(&curproxy->log_tag, &defproxy.log_tag);
Willy Tarreau094af4e2015-01-07 15:03:42 +01001847
Willy Tarreau62a61232013-04-12 18:13:46 +02001848 if (defproxy.conf.uif_file) {
1849 curproxy->conf.uif_file = strdup(defproxy.conf.uif_file);
1850 curproxy->conf.uif_line = defproxy.conf.uif_line;
1851 }
William Lallemanda73203e2012-03-12 12:48:57 +01001852
1853 /* copy default header unique id */
1854 if (defproxy.header_unique_id)
1855 curproxy->header_unique_id = strdup(defproxy.header_unique_id);
1856
William Lallemand82fe75c2012-10-23 10:25:10 +02001857 /* default compression options */
1858 if (defproxy.comp != NULL) {
1859 curproxy->comp = calloc(1, sizeof(struct comp));
1860 curproxy->comp->algos = defproxy.comp->algos;
1861 curproxy->comp->types = defproxy.comp->types;
1862 }
1863
Willy Tarreaubaaee002006-06-26 02:48:02 +02001864 curproxy->grace = defproxy.grace;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02001865 curproxy->conf.used_listener_id = EB_ROOT;
1866 curproxy->conf.used_server_id = EB_ROOT;
Willy Tarreau1c47f852006-07-09 08:22:27 +02001867
Simon Horman98637e52014-06-20 12:30:16 +09001868 if (defproxy.check_path)
1869 curproxy->check_path = strdup(defproxy.check_path);
1870 if (defproxy.check_command)
1871 curproxy->check_command = strdup(defproxy.check_command);
1872
Simon Horman9dc49962015-01-30 11:22:59 +09001873 if (defproxy.email_alert.mailers.name)
1874 curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name);
1875 if (defproxy.email_alert.from)
1876 curproxy->email_alert.from = strdup(defproxy.email_alert.from);
1877 if (defproxy.email_alert.to)
1878 curproxy->email_alert.to = strdup(defproxy.email_alert.to);
1879 if (defproxy.email_alert.myhostname)
1880 curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname);
Simon Horman64e34162015-02-06 11:11:57 +09001881 curproxy->email_alert.level = defproxy.email_alert.level;
Cyril Bonté7e084702015-12-04 03:07:06 +01001882 curproxy->email_alert.set = defproxy.email_alert.set;
Simon Horman9dc49962015-01-30 11:22:59 +09001883
Willy Tarreau93893792009-07-23 13:19:11 +02001884 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001885 }
1886 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
1887 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01001888 /* FIXME-20070101: we should do this too at the end of the
1889 * config parsing to free all default values.
1890 */
William Lallemand6e62fb62015-04-28 16:55:23 +02001891 if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
1892 err_code |= ERR_ABORT;
1893 goto out;
1894 }
1895
Willy Tarreaua534fea2008-08-03 12:19:50 +02001896 free(defproxy.check_req);
Simon Horman98637e52014-06-20 12:30:16 +09001897 free(defproxy.check_command);
1898 free(defproxy.check_path);
Willy Tarreaua534fea2008-08-03 12:19:50 +02001899 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02001900 free(defproxy.rdp_cookie_name);
Olivier Houchard4e694042017-03-14 20:01:29 +01001901 free(defproxy.dyncookie_key);
Willy Tarreau4d187ac2009-12-03 23:13:06 +01001902 free(defproxy.cookie_domain);
Willy Tarreaua534fea2008-08-03 12:19:50 +02001903 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01001904 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02001905 free(defproxy.capture_name);
1906 free(defproxy.monitor_uri);
1907 free(defproxy.defbe.name);
Willy Tarreauef9a3602012-12-08 22:29:20 +01001908 free(defproxy.conn_src.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02001909 free(defproxy.fwdfor_hdr_name);
1910 defproxy.fwdfor_hdr_len = 0;
Willy Tarreaub86db342009-11-30 11:50:16 +01001911 free(defproxy.orgto_hdr_name);
1912 defproxy.orgto_hdr_len = 0;
Mark Lamourinec2247f02012-01-04 13:02:01 -05001913 free(defproxy.server_id_hdr_name);
1914 defproxy.server_id_hdr_len = 0;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02001915 free(defproxy.expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02001916 if (defproxy.expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02001917 regex_free(defproxy.expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02001918 free(defproxy.expect_regex);
1919 defproxy.expect_regex = NULL;
1920 }
Willy Tarreau0f772532006-12-23 20:51:41 +01001921
Willy Tarreau62a61232013-04-12 18:13:46 +02001922 if (defproxy.conf.logformat_string != default_http_log_format &&
1923 defproxy.conf.logformat_string != default_tcp_log_format &&
1924 defproxy.conf.logformat_string != clf_http_log_format)
1925 free(defproxy.conf.logformat_string);
Willy Tarreau196729e2012-05-31 19:30:26 +02001926
Willy Tarreau62a61232013-04-12 18:13:46 +02001927 free(defproxy.conf.uniqueid_format_string);
1928 free(defproxy.conf.lfs_file);
1929 free(defproxy.conf.uif_file);
Dragan Dosen43885c72015-10-01 13:18:13 +02001930 chunk_destroy(&defproxy.log_tag);
Simon Horman9dc49962015-01-30 11:22:59 +09001931 free_email_alert(&defproxy);
Willy Tarreau196729e2012-05-31 19:30:26 +02001932
Dragan Dosen0b85ece2015-09-25 19:17:44 +02001933 if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format)
1934 free(defproxy.conf.logformat_sd_string);
1935 free(defproxy.conf.lfsd_file);
1936
Willy Tarreaua534fea2008-08-03 12:19:50 +02001937 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02001938 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01001939
Willy Tarreaubaaee002006-06-26 02:48:02 +02001940 /* we cannot free uri_auth because it might already be used */
1941 init_default_instance();
1942 curproxy = &defproxy;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02001943 curproxy->conf.args.file = curproxy->conf.file = strdup(file);
1944 curproxy->conf.args.line = curproxy->conf.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001945 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02001946 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001947 }
1948 else if (curproxy == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001949 ha_alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001950 err_code |= ERR_ALERT | ERR_FATAL;
1951 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001952 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02001953
1954 /* update the current file and line being parsed */
1955 curproxy->conf.args.file = curproxy->conf.file;
1956 curproxy->conf.args.line = linenum;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001957
1958 /* Now let's parse the proxy-specific keywords */
Frédéric Lécailleb82f7422017-04-13 18:24:23 +02001959 if (!strcmp(args[0], "server") ||
1960 !strcmp(args[0], "default-server") ||
1961 !strcmp(args[0], "server-template")) {
Willy Tarreau272adea2014-03-31 10:39:59 +02001962 err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
1963 if (err_code & ERR_FATAL)
1964 goto out;
1965 }
1966 else if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreau4348fad2012-09-20 16:48:07 +02001967 struct listener *l;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001968 int cur_arg;
1969
Willy Tarreaubaaee002006-06-26 02:48:02 +02001970 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001971 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001972 err_code |= ERR_ALERT | ERR_FATAL;
1973 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001974 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01001975 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001976 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001977
Willy Tarreau24709282013-03-10 21:32:12 +01001978 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01001979 ha_alert("parsing [%s:%d] : '%s' expects {<path>|[addr1]:port1[-end1]}{,[addr]:port[-end]}... as arguments.\n",
1980 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001981 err_code |= ERR_ALERT | ERR_FATAL;
1982 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001983 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001984
Willy Tarreaua261e9b2016-12-22 20:44:00 +01001985 bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], xprt_get(XPRT_RAW));
Willy Tarreau8dc21fa2013-01-24 15:17:20 +01001986
1987 /* use default settings for unix sockets */
1988 bind_conf->ux.uid = global.unix_bind.ux.uid;
1989 bind_conf->ux.gid = global.unix_bind.ux.gid;
1990 bind_conf->ux.mode = global.unix_bind.ux.mode;
Willy Tarreau8a956912010-10-15 14:27:08 +02001991
1992 /* NOTE: the following line might create several listeners if there
1993 * are comma-separated IPs or port ranges. So all further processing
1994 * will have to be applied to all listeners created after last_listen.
1995 */
Willy Tarreau902636f2013-03-10 19:44:48 +01001996 if (!str2listener(args[1], curproxy, bind_conf, file, linenum, &errmsg)) {
1997 if (errmsg && *errmsg) {
1998 indent_msg(&errmsg, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01001999 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau4fbb2282012-09-20 20:01:39 +02002000 }
2001 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002002 ha_alert("parsing [%s:%d] : '%s' : error encountered while parsing listening address '%s'.\n",
2003 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002004 err_code |= ERR_ALERT | ERR_FATAL;
2005 goto out;
2006 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01002007
Willy Tarreau4348fad2012-09-20 16:48:07 +02002008 list_for_each_entry(l, &bind_conf->listeners, by_bind) {
2009 /* Set default global rights and owner for unix bind */
Willy Tarreauc8b11092011-02-16 11:08:57 +01002010 global.maxsock++;
Willy Tarreau90a570f2009-10-04 20:54:54 +02002011 }
2012
Willy Tarreau5e6e2042009-02-04 17:19:29 +01002013 cur_arg = 2;
2014 while (*(args[cur_arg])) {
Willy Tarreau8638f482012-09-18 18:01:17 +02002015 static int bind_dumped;
Willy Tarreau26982662012-09-12 23:17:10 +02002016 struct bind_kw *kw;
Willy Tarreau8638f482012-09-18 18:01:17 +02002017 char *err;
2018
Willy Tarreau26982662012-09-12 23:17:10 +02002019 kw = bind_find_kw(args[cur_arg]);
2020 if (kw) {
2021 char *err = NULL;
2022 int code;
2023
2024 if (!kw->parse) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002025 ha_alert("parsing [%s:%d] : '%s %s' : '%s' option is not implemented in this version (check build options).\n",
2026 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02002027 cur_arg += 1 + kw->skip ;
2028 err_code |= ERR_ALERT | ERR_FATAL;
2029 goto out;
2030 }
2031
Willy Tarreau4348fad2012-09-20 16:48:07 +02002032 code = kw->parse(args, cur_arg, curproxy, bind_conf, &err);
Willy Tarreau26982662012-09-12 23:17:10 +02002033 err_code |= code;
2034
2035 if (code) {
2036 if (err && *err) {
2037 indent_msg(&err, 2);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002038 ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
Willy Tarreau26982662012-09-12 23:17:10 +02002039 }
2040 else
Christopher Faulet767a84b2017-11-24 16:50:31 +01002041 ha_alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
2042 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau26982662012-09-12 23:17:10 +02002043 if (code & ERR_FATAL) {
2044 free(err);
2045 cur_arg += 1 + kw->skip;
2046 goto out;
2047 }
2048 }
2049 free(err);
2050 cur_arg += 1 + kw->skip;
2051 continue;
2052 }
2053
Willy Tarreau8638f482012-09-18 18:01:17 +02002054 err = NULL;
2055 if (!bind_dumped) {
2056 bind_dump_kws(&err);
2057 indent_msg(&err, 4);
2058 bind_dumped = 1;
2059 }
2060
Christopher Faulet767a84b2017-11-24 16:50:31 +01002061 ha_alert("parsing [%s:%d] : '%s %s' unknown keyword '%s'.%s%s\n",
2062 file, linenum, args[0], args[1], args[cur_arg],
2063 err ? " Registered keywords :" : "", err ? err : "");
Willy Tarreau8638f482012-09-18 18:01:17 +02002064 free(err);
2065
Willy Tarreau93893792009-07-23 13:19:11 +02002066 err_code |= ERR_ALERT | ERR_FATAL;
2067 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01002068 }
Willy Tarreau93893792009-07-23 13:19:11 +02002069 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002070 }
2071 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01002072 if (!*args[1] || !str2net(args[1], 1, &curproxy->mon_net, &curproxy->mon_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002073 ha_alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
2074 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002075 err_code |= ERR_ALERT | ERR_FATAL;
2076 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002077 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002078 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002079 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002080
Willy Tarreaubaaee002006-06-26 02:48:02 +02002081 /* flush useless bits */
2082 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02002083 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002084 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02002085 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01002086 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002087 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002088
William Lallemanddf1425a2015-04-28 20:17:49 +02002089 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2090 goto out;
2091
Willy Tarreau1c47f852006-07-09 08:22:27 +02002092 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002093 ha_alert("parsing [%s:%d] : '%s' expects an URI.\n",
2094 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002095 err_code |= ERR_ALERT | ERR_FATAL;
2096 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002097 }
2098
Willy Tarreaua534fea2008-08-03 12:19:50 +02002099 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01002100 curproxy->monitor_uri_len = strlen(args[1]);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002101 curproxy->monitor_uri = calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01002102 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02002103 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
2104
Willy Tarreau93893792009-07-23 13:19:11 +02002105 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02002106 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002107 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
William Lallemanddf1425a2015-04-28 20:17:49 +02002108 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2109 goto out;
2110
Willy Tarreaubaaee002006-06-26 02:48:02 +02002111 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
2112 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
2113 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
2114 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002115 ha_alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002116 err_code |= ERR_ALERT | ERR_FATAL;
2117 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002118 }
2119 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002120 else if (!strcmp(args[0], "id")) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002121 struct eb32_node *node;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002122
2123 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002124 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002125 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002126 err_code |= ERR_ALERT | ERR_FATAL;
2127 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002128 }
2129
William Lallemanddf1425a2015-04-28 20:17:49 +02002130 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2131 goto out;
2132
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002133 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002134 ha_alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
2135 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002136 err_code |= ERR_ALERT | ERR_FATAL;
2137 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002138 }
2139
2140 curproxy->uuid = atol(args[1]);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002141 curproxy->conf.id.key = curproxy->uuid;
Willy Tarreau0d1fdf72015-05-27 16:44:02 +02002142 curproxy->options |= PR_O_FORCED_ID;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002143
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002144 if (curproxy->uuid <= 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002145 ha_alert("parsing [%s:%d]: custom id has to be > 0.\n",
2146 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002147 err_code |= ERR_ALERT | ERR_FATAL;
2148 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002149 }
2150
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002151 node = eb32_lookup(&used_proxy_id, curproxy->uuid);
2152 if (node) {
2153 struct proxy *target = container_of(node, struct proxy, conf.id);
Christopher Faulet767a84b2017-11-24 16:50:31 +01002154 ha_alert("parsing [%s:%d]: %s %s reuses same custom id as %s %s (declared at %s:%d).\n",
2155 file, linenum, proxy_type_str(curproxy), curproxy->id,
2156 proxy_type_str(target), target->id, target->conf.file, target->conf.line);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02002157 err_code |= ERR_ALERT | ERR_FATAL;
2158 goto out;
2159 }
2160 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002161 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02002162 else if (!strcmp(args[0], "description")) {
2163 int i, len=0;
2164 char *d;
2165
Cyril Bonté99ed3272010-01-24 23:29:44 +01002166 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002167 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
Cyril Bonté99ed3272010-01-24 23:29:44 +01002168 file, linenum, args[0]);
2169 err_code |= ERR_ALERT | ERR_FATAL;
2170 goto out;
2171 }
2172
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02002173 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002174 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
2175 file, linenum, args[0]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02002176 return -1;
2177 }
2178
Willy Tarreau348acfe2014-04-14 15:00:39 +02002179 for (i = 1; *args[i]; i++)
2180 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02002181
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002182 d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02002183 curproxy->desc = d;
2184
Willy Tarreau348acfe2014-04-14 15:00:39 +02002185 d += snprintf(d, curproxy->desc + len - d, "%s", args[1]);
2186 for (i = 2; *args[i]; i++)
2187 d += snprintf(d, curproxy->desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02002188
2189 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002190 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
William Lallemanddf1425a2015-04-28 20:17:49 +02002191 if (alertif_too_many_args(0, file, linenum, args, &err_code))
2192 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002193 curproxy->state = PR_STSTOPPED;
2194 }
2195 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
William Lallemanddf1425a2015-04-28 20:17:49 +02002196 if (alertif_too_many_args(0, file, linenum, args, &err_code))
2197 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002198 curproxy->state = PR_STNEW;
2199 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002200 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
2201 int cur_arg = 1;
Willy Tarreaua9db57e2013-01-18 11:29:29 +01002202 unsigned long set = 0;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002203
2204 while (*args[cur_arg]) {
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002205 if (strcmp(args[cur_arg], "all") == 0) {
2206 set = 0;
2207 break;
2208 }
Christopher Faulet26028f62017-11-22 15:01:51 +01002209 if (parse_process_number(args[cur_arg], &set, NULL, &errmsg)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002210 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau110ecc12012-11-15 17:50:01 +01002211 err_code |= ERR_ALERT | ERR_FATAL;
2212 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01002213 }
2214 cur_arg++;
2215 }
2216 curproxy->bind_proc = set;
2217 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02002218 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02002219 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002220 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002221 err_code |= ERR_ALERT | ERR_FATAL;
2222 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02002223 }
2224
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002225 err = invalid_char(args[1]);
2226 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002227 ha_alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
2228 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002229 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau1822e8c2017-04-12 18:54:00 +02002230 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002231 }
2232
Thierry FOURNIER0d6ba512014-02-11 03:31:34 +01002233 if (parse_acl((const char **)args + 1, &curproxy->acl, &errmsg, &curproxy->conf.args, file, linenum) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002234 ha_alert("parsing [%s:%d] : error detected while parsing ACL '%s' : %s.\n",
2235 file, linenum, args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02002236 err_code |= ERR_ALERT | ERR_FATAL;
2237 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02002238 }
Olivier Houchard4e694042017-03-14 20:01:29 +01002239 }
2240 else if (!strcmp(args[0], "dynamic-cookie-key")) { /* Dynamic cookies secret key */
2241
2242 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2243 err_code |= ERR_WARN;
2244
2245 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002246 ha_alert("parsing [%s:%d] : '%s' expects <secret_key> as argument.\n",
2247 file, linenum, args[0]);
Olivier Houchard4e694042017-03-14 20:01:29 +01002248 err_code |= ERR_ALERT | ERR_FATAL;
2249 goto out;
2250 }
2251 free(curproxy->dyncookie_key);
2252 curproxy->dyncookie_key = strdup(args[1]);
Willy Tarreaueb0c6142007-05-07 00:53:22 +02002253 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002254 else if (!strcmp(args[0], "cookie")) { /* cookie name */
2255 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002256
Willy Tarreau977b8e42006-12-29 14:19:17 +01002257 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002258 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002259
Willy Tarreaubaaee002006-06-26 02:48:02 +02002260 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002261 ha_alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
2262 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002263 err_code |= ERR_ALERT | ERR_FATAL;
2264 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002265 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02002266
Willy Tarreau67402132012-05-31 20:40:20 +02002267 curproxy->ck_opts = 0;
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02002268 curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
Willy Tarreau4d187ac2009-12-03 23:13:06 +01002269 free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02002270 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002271 curproxy->cookie_name = strdup(args[1]);
2272 curproxy->cookie_len = strlen(curproxy->cookie_name);
Willy Tarreauc63d4bb2010-10-23 11:37:27 +02002273
Willy Tarreaubaaee002006-06-26 02:48:02 +02002274 cur_arg = 2;
2275 while (*(args[cur_arg])) {
2276 if (!strcmp(args[cur_arg], "rewrite")) {
Willy Tarreau67402132012-05-31 20:40:20 +02002277 curproxy->ck_opts |= PR_CK_RW;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002278 }
2279 else if (!strcmp(args[cur_arg], "indirect")) {
Willy Tarreau67402132012-05-31 20:40:20 +02002280 curproxy->ck_opts |= PR_CK_IND;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002281 }
2282 else if (!strcmp(args[cur_arg], "insert")) {
Willy Tarreau67402132012-05-31 20:40:20 +02002283 curproxy->ck_opts |= PR_CK_INS;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002284 }
2285 else if (!strcmp(args[cur_arg], "nocache")) {
Willy Tarreau67402132012-05-31 20:40:20 +02002286 curproxy->ck_opts |= PR_CK_NOC;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002287 }
2288 else if (!strcmp(args[cur_arg], "postonly")) {
Willy Tarreau67402132012-05-31 20:40:20 +02002289 curproxy->ck_opts |= PR_CK_POST;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002290 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02002291 else if (!strcmp(args[cur_arg], "preserve")) {
Willy Tarreau67402132012-05-31 20:40:20 +02002292 curproxy->ck_opts |= PR_CK_PSV;
Willy Tarreauba4c5be2010-10-23 12:46:42 +02002293 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002294 else if (!strcmp(args[cur_arg], "prefix")) {
Willy Tarreau67402132012-05-31 20:40:20 +02002295 curproxy->ck_opts |= PR_CK_PFX;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002296 }
Willy Tarreau4992dd22012-05-31 21:02:17 +02002297 else if (!strcmp(args[cur_arg], "httponly")) {
2298 curproxy->ck_opts |= PR_CK_HTTPONLY;
2299 }
2300 else if (!strcmp(args[cur_arg], "secure")) {
2301 curproxy->ck_opts |= PR_CK_SECURE;
2302 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02002303 else if (!strcmp(args[cur_arg], "domain")) {
2304 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002305 ha_alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
2306 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002307 err_code |= ERR_ALERT | ERR_FATAL;
2308 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02002309 }
2310
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01002311 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02002312 /* rfc2109, 4.3.2 Rejecting Cookies */
Christopher Faulet767a84b2017-11-24 16:50:31 +01002313 ha_warning("parsing [%s:%d]: domain '%s' contains no embedded"
2314 " dots nor does not start with a dot."
2315 " RFC forbids it, this configuration may not work properly.\n",
2316 file, linenum, args[cur_arg + 1]);
Krzysztof Piotr Oledzki1a8bea92009-12-15 23:40:47 +01002317 err_code |= ERR_WARN;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02002318 }
2319
2320 err = invalid_domainchar(args[cur_arg + 1]);
2321 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002322 ha_alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
2323 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002324 err_code |= ERR_ALERT | ERR_FATAL;
2325 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02002326 }
2327
Willy Tarreau68a897b2009-12-03 23:28:34 +01002328 if (!curproxy->cookie_domain) {
2329 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
2330 } else {
2331 /* one domain was already specified, add another one by
2332 * building the string which will be returned along with
2333 * the cookie.
2334 */
2335 char *new_ptr;
2336 int new_len = strlen(curproxy->cookie_domain) +
2337 strlen("; domain=") + strlen(args[cur_arg + 1]) + 1;
2338 new_ptr = malloc(new_len);
2339 snprintf(new_ptr, new_len, "%s; domain=%s", curproxy->cookie_domain, args[cur_arg+1]);
2340 free(curproxy->cookie_domain);
2341 curproxy->cookie_domain = new_ptr;
2342 }
Willy Tarreau31936852010-10-06 16:59:56 +02002343 cur_arg++;
2344 }
2345 else if (!strcmp(args[cur_arg], "maxidle")) {
2346 unsigned int maxidle;
2347 const char *res;
2348
2349 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002350 ha_alert("parsing [%s:%d]: '%s' expects <idletime> in seconds as argument.\n",
2351 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02002352 err_code |= ERR_ALERT | ERR_FATAL;
2353 goto out;
2354 }
2355
2356 res = parse_time_err(args[cur_arg + 1], &maxidle, TIME_UNIT_S);
2357 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002358 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2359 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02002360 err_code |= ERR_ALERT | ERR_FATAL;
2361 goto out;
2362 }
2363 curproxy->cookie_maxidle = maxidle;
2364 cur_arg++;
2365 }
2366 else if (!strcmp(args[cur_arg], "maxlife")) {
2367 unsigned int maxlife;
2368 const char *res;
2369
2370 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002371 ha_alert("parsing [%s:%d]: '%s' expects <lifetime> in seconds as argument.\n",
2372 file, linenum, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02002373 err_code |= ERR_ALERT | ERR_FATAL;
2374 goto out;
2375 }
2376
2377 res = parse_time_err(args[cur_arg + 1], &maxlife, TIME_UNIT_S);
2378 if (res) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002379 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
2380 file, linenum, *res, args[cur_arg]);
Willy Tarreau31936852010-10-06 16:59:56 +02002381 err_code |= ERR_ALERT | ERR_FATAL;
2382 goto out;
2383 }
2384 curproxy->cookie_maxlife = maxlife;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02002385 cur_arg++;
2386 }
Olivier Houcharda5938f72017-03-15 15:12:06 +01002387 else if (!strcmp(args[cur_arg], "dynamic")) { /* Dynamic persistent cookies secret key */
Olivier Houchard4e694042017-03-14 20:01:29 +01002388
2389 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[cur_arg], NULL))
2390 err_code |= ERR_WARN;
2391 curproxy->ck_opts |= PR_CK_DYNAMIC;
2392 }
2393
Willy Tarreaubaaee002006-06-26 02:48:02 +02002394 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002395 ha_alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache', 'postonly', 'domain', 'maxidle', 'dynamic' and 'maxlife' options.\n",
2396 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002397 err_code |= ERR_ALERT | ERR_FATAL;
2398 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002399 }
2400 cur_arg++;
2401 }
Willy Tarreau67402132012-05-31 20:40:20 +02002402 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002403 ha_alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
2404 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002405 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002406 }
2407
Willy Tarreau67402132012-05-31 20:40:20 +02002408 if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002409 ha_alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
2410 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002411 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002412 }
Willy Tarreauba4c5be2010-10-23 12:46:42 +02002413
Willy Tarreau67402132012-05-31 20:40:20 +02002414 if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002415 ha_alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
2416 file, linenum);
Willy Tarreauba4c5be2010-10-23 12:46:42 +02002417 err_code |= ERR_ALERT | ERR_FATAL;
2418 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002419 }/* end else if (!strcmp(args[0], "cookie")) */
Simon Horman9dc49962015-01-30 11:22:59 +09002420 else if (!strcmp(args[0], "email-alert")) {
2421 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002422 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2423 file, linenum, args[0]);
Simon Horman9dc49962015-01-30 11:22:59 +09002424 err_code |= ERR_ALERT | ERR_FATAL;
2425 goto out;
2426 }
2427
2428 if (!strcmp(args[1], "from")) {
2429 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002430 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2431 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09002432 err_code |= ERR_ALERT | ERR_FATAL;
2433 goto out;
2434 }
2435 free(curproxy->email_alert.from);
2436 curproxy->email_alert.from = strdup(args[2]);
2437 }
2438 else if (!strcmp(args[1], "mailers")) {
2439 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002440 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2441 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09002442 err_code |= ERR_ALERT | ERR_FATAL;
2443 goto out;
2444 }
2445 free(curproxy->email_alert.mailers.name);
2446 curproxy->email_alert.mailers.name = strdup(args[2]);
2447 }
2448 else if (!strcmp(args[1], "myhostname")) {
2449 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002450 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2451 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09002452 err_code |= ERR_ALERT | ERR_FATAL;
2453 goto out;
2454 }
2455 free(curproxy->email_alert.myhostname);
2456 curproxy->email_alert.myhostname = strdup(args[2]);
2457 }
Simon Horman64e34162015-02-06 11:11:57 +09002458 else if (!strcmp(args[1], "level")) {
2459 curproxy->email_alert.level = get_log_level(args[2]);
2460 if (curproxy->email_alert.level < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002461 ha_alert("parsing [%s:%d] : unknown log level '%s' after '%s'\n",
2462 file, linenum, args[1], args[2]);
Simon Horman64e34162015-02-06 11:11:57 +09002463 err_code |= ERR_ALERT | ERR_FATAL;
2464 goto out;
2465 }
2466 }
Simon Horman9dc49962015-01-30 11:22:59 +09002467 else if (!strcmp(args[1], "to")) {
2468 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002469 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2470 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09002471 err_code |= ERR_ALERT | ERR_FATAL;
2472 goto out;
2473 }
2474 free(curproxy->email_alert.to);
2475 curproxy->email_alert.to = strdup(args[2]);
2476 }
2477 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002478 ha_alert("parsing [%s:%d] : email-alert: unknown argument '%s'.\n",
2479 file, linenum, args[1]);
Simon Horman9dc49962015-01-30 11:22:59 +09002480 err_code |= ERR_ALERT | ERR_FATAL;
2481 goto out;
2482 }
Simon Horman64e34162015-02-06 11:11:57 +09002483 /* Indicate that the email_alert is at least partially configured */
2484 curproxy->email_alert.set = 1;
Simon Horman9dc49962015-01-30 11:22:59 +09002485 }/* end else if (!strcmp(args[0], "email-alert")) */
Simon Horman98637e52014-06-20 12:30:16 +09002486 else if (!strcmp(args[0], "external-check")) {
2487 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002488 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2489 file, linenum, args[0]);
Simon Horman98637e52014-06-20 12:30:16 +09002490 err_code |= ERR_ALERT | ERR_FATAL;
2491 goto out;
2492 }
2493
2494 if (!strcmp(args[1], "command")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01002495 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02002496 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01002497 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002498 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2499 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09002500 err_code |= ERR_ALERT | ERR_FATAL;
2501 goto out;
2502 }
2503 free(curproxy->check_command);
2504 curproxy->check_command = strdup(args[2]);
2505 }
2506 else if (!strcmp(args[1], "path")) {
Ben Cabot49795eb2015-09-16 12:07:51 +01002507 if (alertif_too_many_args(2, file, linenum, args, &err_code))
William Lallemanddf1425a2015-04-28 20:17:49 +02002508 goto out;
Ben Cabot49795eb2015-09-16 12:07:51 +01002509 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002510 ha_alert("parsing [%s:%d] : missing argument after '%s'.\n",
2511 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09002512 err_code |= ERR_ALERT | ERR_FATAL;
2513 goto out;
2514 }
2515 free(curproxy->check_path);
2516 curproxy->check_path = strdup(args[2]);
2517 }
2518 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002519 ha_alert("parsing [%s:%d] : external-check: unknown argument '%s'.\n",
2520 file, linenum, args[1]);
Simon Horman98637e52014-06-20 12:30:16 +09002521 err_code |= ERR_ALERT | ERR_FATAL;
2522 goto out;
2523 }
2524 }/* end else if (!strcmp(args[0], "external-check")) */
Emeric Brun647caf12009-06-30 17:57:00 +02002525 else if (!strcmp(args[0], "persist")) { /* persist */
2526 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002527 ha_alert("parsing [%s:%d] : missing persist method.\n",
2528 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002529 err_code |= ERR_ALERT | ERR_FATAL;
2530 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02002531 }
2532
2533 if (!strncmp(args[1], "rdp-cookie", 10)) {
2534 curproxy->options2 |= PR_O2_RDPC_PRST;
2535
Emeric Brunb982a3d2010-01-04 15:45:53 +01002536 if (*(args[1] + 10) == '(') { /* cookie name */
Emeric Brun647caf12009-06-30 17:57:00 +02002537 const char *beg, *end;
2538
2539 beg = args[1] + 11;
2540 end = strchr(beg, ')');
2541
William Lallemanddf1425a2015-04-28 20:17:49 +02002542 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2543 goto out;
2544
Emeric Brun647caf12009-06-30 17:57:00 +02002545 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002546 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
2547 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002548 err_code |= ERR_ALERT | ERR_FATAL;
2549 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02002550 }
2551
2552 free(curproxy->rdp_cookie_name);
2553 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
2554 curproxy->rdp_cookie_len = end-beg;
2555 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01002556 else if (*(args[1] + 10) == '\0') { /* default cookie name 'msts' */
Emeric Brun647caf12009-06-30 17:57:00 +02002557 free(curproxy->rdp_cookie_name);
2558 curproxy->rdp_cookie_name = strdup("msts");
2559 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
2560 }
2561 else { /* syntax */
Christopher Faulet767a84b2017-11-24 16:50:31 +01002562 ha_alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
2563 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002564 err_code |= ERR_ALERT | ERR_FATAL;
2565 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02002566 }
2567 }
2568 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002569 ha_alert("parsing [%s:%d] : unknown persist method.\n",
2570 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002571 err_code |= ERR_ALERT | ERR_FATAL;
2572 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02002573 }
2574 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002575 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Christopher Faulet767a84b2017-11-24 16:50:31 +01002576 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 +02002577 err_code |= ERR_ALERT | ERR_FATAL;
2578 goto out;
2579 }
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002580 else if (!strcmp(args[0], "load-server-state-from-file")) {
2581 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2582 err_code |= ERR_WARN;
2583 if (!strcmp(args[1], "global")) { /* use the file pointed to by global server-state-file directive */
2584 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_GLOBAL;
2585 }
2586 else if (!strcmp(args[1], "local")) { /* use the server-state-file-name variable to locate the server-state file */
2587 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_LOCAL;
2588 }
2589 else if (!strcmp(args[1], "none")) { /* don't use server-state-file directive for this backend */
2590 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
2591 }
2592 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002593 ha_alert("parsing [%s:%d] : '%s' expects 'global', 'local' or 'none'. Got '%s'\n",
2594 file, linenum, args[0], args[1]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002595 err_code |= ERR_ALERT | ERR_FATAL;
2596 goto out;
2597 }
2598 }
2599 else if (!strcmp(args[0], "server-state-file-name")) {
2600 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2601 err_code |= ERR_WARN;
2602 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002603 ha_alert("parsing [%s:%d] : '%s' expects 'use-backend-name' or a string. Got no argument\n",
2604 file, linenum, args[0]);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02002605 err_code |= ERR_ALERT | ERR_FATAL;
2606 goto out;
2607 }
2608 else if (!strcmp(args[1], "use-backend-name"))
2609 curproxy->server_state_file_name = strdup(curproxy->id);
2610 else
2611 curproxy->server_state_file_name = strdup(args[1]);
2612 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002613 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02002614 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002615 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002616
Willy Tarreaubaaee002006-06-26 02:48:02 +02002617 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Cyril Bonté99ed3272010-01-24 23:29:44 +01002618 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002619 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 +01002620 err_code |= ERR_ALERT | ERR_FATAL;
2621 goto out;
2622 }
2623
William Lallemand1a748ae2015-05-19 16:37:23 +02002624 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
2625 goto out;
2626
Willy Tarreaubaaee002006-06-26 02:48:02 +02002627 if (*(args[4]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002628 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
2629 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002630 err_code |= ERR_ALERT | ERR_FATAL;
2631 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002632 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02002633 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002634 curproxy->capture_name = strdup(args[2]);
2635 curproxy->capture_namelen = strlen(curproxy->capture_name);
2636 curproxy->capture_len = atol(args[4]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002637 curproxy->to_log |= LW_COOKIE;
2638 }
2639 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
2640 struct cap_hdr *hdr;
2641
2642 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002643 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 +02002644 err_code |= ERR_ALERT | ERR_FATAL;
2645 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002646 }
2647
William Lallemand1a748ae2015-05-19 16:37:23 +02002648 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
2649 goto out;
2650
Willy Tarreaubaaee002006-06-26 02:48:02 +02002651 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002652 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
2653 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002654 err_code |= ERR_ALERT | ERR_FATAL;
2655 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002656 }
2657
Vincent Bernat02779b62016-04-03 13:48:43 +02002658 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02002659 hdr->next = curproxy->req_cap;
2660 hdr->name = strdup(args[3]);
2661 hdr->namelen = strlen(args[3]);
2662 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02002663 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002664 hdr->index = curproxy->nb_req_cap++;
2665 curproxy->req_cap = hdr;
2666 curproxy->to_log |= LW_REQHDR;
2667 }
2668 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
2669 struct cap_hdr *hdr;
2670
2671 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002672 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 +02002673 err_code |= ERR_ALERT | ERR_FATAL;
2674 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002675 }
2676
William Lallemand1a748ae2015-05-19 16:37:23 +02002677 if (alertif_too_many_args_idx(4, 1, file, linenum, args, &err_code))
2678 goto out;
2679
Willy Tarreaubaaee002006-06-26 02:48:02 +02002680 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002681 ha_alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
2682 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002683 err_code |= ERR_ALERT | ERR_FATAL;
2684 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002685 }
Vincent Bernat02779b62016-04-03 13:48:43 +02002686 hdr = calloc(1, sizeof(*hdr));
Willy Tarreaubaaee002006-06-26 02:48:02 +02002687 hdr->next = curproxy->rsp_cap;
2688 hdr->name = strdup(args[3]);
2689 hdr->namelen = strlen(args[3]);
2690 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02002691 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02002692 hdr->index = curproxy->nb_rsp_cap++;
2693 curproxy->rsp_cap = hdr;
2694 curproxy->to_log |= LW_RSPHDR;
2695 }
2696 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002697 ha_alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
2698 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002699 err_code |= ERR_ALERT | ERR_FATAL;
2700 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002701 }
2702 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002703 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01002704 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002705 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002706
William Lallemanddf1425a2015-04-28 20:17:49 +02002707 if (alertif_too_many_args(1, file, linenum, args, &err_code))
2708 goto out;
2709
Willy Tarreaubaaee002006-06-26 02:48:02 +02002710 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002711 ha_alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
2712 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002713 err_code |= ERR_ALERT | ERR_FATAL;
2714 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002715 }
2716 curproxy->conn_retries = atol(args[1]);
2717 }
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01002718 else if (!strcmp(args[0], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02002719 struct act_rule *rule;
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01002720
2721 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002722 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01002723 err_code |= ERR_ALERT | ERR_FATAL;
2724 goto out;
2725 }
2726
Willy Tarreau20b0de52012-12-24 15:45:22 +01002727 if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02002728 !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02002729 (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
2730 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
2731 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
2732 LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002733 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
2734 file, linenum, args[0]);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01002735 err_code |= ERR_WARN;
2736 }
2737
Willy Tarreauff011f22011-01-06 17:51:27 +01002738 rule = parse_http_req_cond((const char **)args + 1, file, linenum, curproxy);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01002739
Willy Tarreauff011f22011-01-06 17:51:27 +01002740 if (!rule) {
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01002741 err_code |= ERR_ALERT | ERR_ABORT;
2742 goto out;
2743 }
2744
Willy Tarreau5002f572014-04-23 01:32:02 +02002745 err_code |= warnif_misplaced_http_req(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01002746 err_code |= warnif_cond_conflicts(rule->cond,
2747 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
2748 file, linenum);
2749
Willy Tarreauff011f22011-01-06 17:51:27 +01002750 LIST_ADDQ(&curproxy->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki59bb2182010-01-29 17:58:21 +01002751 }
Willy Tarreaue365c0b2013-06-11 16:06:12 +02002752 else if (!strcmp(args[0], "http-response")) { /* response access control */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02002753 struct act_rule *rule;
Willy Tarreaue365c0b2013-06-11 16:06:12 +02002754
2755 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002756 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02002757 err_code |= ERR_ALERT | ERR_FATAL;
2758 goto out;
2759 }
2760
2761 if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02002762 !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
Thierry FOURNIER0ea5c7f2015-08-05 19:05:19 +02002763 (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
2764 LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002765 ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
2766 file, linenum, args[0]);
Willy Tarreaue365c0b2013-06-11 16:06:12 +02002767 err_code |= ERR_WARN;
2768 }
2769
2770 rule = parse_http_res_cond((const char **)args + 1, file, linenum, curproxy);
2771
2772 if (!rule) {
2773 err_code |= ERR_ALERT | ERR_ABORT;
2774 goto out;
2775 }
2776
2777 err_code |= warnif_cond_conflicts(rule->cond,
2778 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
2779 file, linenum);
2780
2781 LIST_ADDQ(&curproxy->http_res_rules, &rule->list);
2782 }
Mark Lamourinec2247f02012-01-04 13:02:01 -05002783 else if (!strcmp(args[0], "http-send-name-header")) { /* send server name in request header */
2784 /* set the header name and length into the proxy structure */
2785 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2786 err_code |= ERR_WARN;
2787
2788 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002789 ha_alert("parsing [%s:%d] : '%s' requires a header string.\n",
2790 file, linenum, args[0]);
Mark Lamourinec2247f02012-01-04 13:02:01 -05002791 err_code |= ERR_ALERT | ERR_FATAL;
2792 goto out;
2793 }
2794
2795 /* set the desired header name */
2796 free(curproxy->server_id_hdr_name);
2797 curproxy->server_id_hdr_name = strdup(args[1]);
2798 curproxy->server_id_hdr_len = strlen(curproxy->server_id_hdr_name);
2799 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02002800 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02002801 struct act_rule *rule;
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02002802
Willy Tarreaub099aca2008-10-12 17:26:37 +02002803 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002804 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002805 err_code |= ERR_ALERT | ERR_FATAL;
2806 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02002807 }
2808
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02002809 /* emulate "block" using "http-request block". Since these rules are supposed to
2810 * be processed before all http-request rules, we put them into their own list
2811 * and will insert them at the end.
2812 */
2813 rule = parse_http_req_cond((const char **)args, file, linenum, curproxy);
2814 if (!rule) {
2815 err_code |= ERR_ALERT | ERR_ABORT;
Willy Tarreau93893792009-07-23 13:19:11 +02002816 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02002817 }
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02002818 err_code |= warnif_misplaced_block(curproxy, file, linenum, args[0]);
2819 err_code |= warnif_cond_conflicts(rule->cond,
2820 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
2821 file, linenum);
2822 LIST_ADDQ(&curproxy->block_rules, &rule->list);
Willy Tarreaude9d2d72014-04-28 22:28:02 +02002823
2824 if (!already_warned(WARN_BLOCK_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01002825 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 +02002826
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02002827 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02002828 else if (!strcmp(args[0], "redirect")) {
Willy Tarreaub463dfb2008-06-07 23:08:56 +02002829 struct redirect_rule *rule;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02002830
Cyril Bonté99ed3272010-01-24 23:29:44 +01002831 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002832 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Cyril Bonté99ed3272010-01-24 23:29:44 +01002833 err_code |= ERR_ALERT | ERR_FATAL;
2834 goto out;
2835 }
2836
Willy Tarreaube4653b2015-05-28 15:26:58 +02002837 if ((rule = http_parse_redirect_rule(file, linenum, curproxy, (const char **)args + 1, &errmsg, 0, 0)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002838 ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing redirect rule : %s.\n",
2839 file, linenum, proxy_type_str(curproxy), curproxy->id, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02002840 err_code |= ERR_ALERT | ERR_FATAL;
2841 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02002842 }
2843
Willy Tarreaub463dfb2008-06-07 23:08:56 +02002844 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreauee445d92014-04-23 01:39:04 +02002845 err_code |= warnif_misplaced_redirect(curproxy, file, linenum, args[0]);
Willy Tarreaua91d0a52013-03-25 08:12:18 +01002846 err_code |= warnif_cond_conflicts(rule->cond,
2847 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
2848 file, linenum);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02002849 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01002850 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02002851 struct switching_rule *rule;
2852
Willy Tarreaub099aca2008-10-12 17:26:37 +02002853 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002854 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002855 err_code |= ERR_ALERT | ERR_FATAL;
2856 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02002857 }
2858
Willy Tarreau55ea7572007-06-17 19:56:27 +02002859 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002860 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02002861
2862 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002863 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002864 err_code |= ERR_ALERT | ERR_FATAL;
2865 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02002866 }
2867
Willy Tarreauf51658d2014-04-23 01:21:56 +02002868 if (strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02002869 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002870 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
2871 file, linenum, errmsg);
Willy Tarreauf51658d2014-04-23 01:21:56 +02002872 err_code |= ERR_ALERT | ERR_FATAL;
2873 goto out;
2874 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02002875
Willy Tarreauf51658d2014-04-23 01:21:56 +02002876 err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum);
Willy Tarreau55ea7572007-06-17 19:56:27 +02002877 }
Willy Tarreau4f862642017-02-28 09:34:39 +01002878 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002879 ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n",
2880 file, linenum, args[2]);
Willy Tarreau4f862642017-02-28 09:34:39 +01002881 err_code |= ERR_ALERT | ERR_FATAL;
2882 goto out;
2883 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02002884
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002885 rule = calloc(1, sizeof(*rule));
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01002886 if (!rule) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002887 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO5948b012016-11-24 23:58:32 +01002888 goto out;
2889 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02002890 rule->cond = cond;
2891 rule->be.name = strdup(args[1]);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01002892 rule->line = linenum;
2893 rule->file = strdup(file);
2894 if (!rule->file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002895 ha_alert("Out of memory error.\n");
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01002896 goto out;
2897 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02002898 LIST_INIT(&rule->list);
2899 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
2900 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02002901 else if (strcmp(args[0], "use-server") == 0) {
2902 struct server_rule *rule;
2903
2904 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002905 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02002906 err_code |= ERR_ALERT | ERR_FATAL;
2907 goto out;
2908 }
2909
2910 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2911 err_code |= ERR_WARN;
2912
2913 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002914 ha_alert("parsing [%s:%d] : '%s' expects a server name.\n", file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02002915 err_code |= ERR_ALERT | ERR_FATAL;
2916 goto out;
2917 }
2918
2919 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002920 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
2921 file, linenum, args[0]);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02002922 err_code |= ERR_ALERT | ERR_FATAL;
2923 goto out;
2924 }
2925
Christopher Faulet1b421ea2017-09-22 14:38:56 +02002926 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002927 ha_alert("parsing [%s:%d] : error detected while parsing switching rule : %s.\n",
2928 file, linenum, errmsg);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02002929 err_code |= ERR_ALERT | ERR_FATAL;
2930 goto out;
2931 }
2932
Willy Tarreaua91d0a52013-03-25 08:12:18 +01002933 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02002934
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002935 rule = calloc(1, sizeof(*rule));
Willy Tarreau4a5cade2012-04-05 21:09:48 +02002936 rule->cond = cond;
2937 rule->srv.name = strdup(args[1]);
2938 LIST_INIT(&rule->list);
2939 LIST_ADDQ(&curproxy->server_rules, &rule->list);
2940 curproxy->be_req_ana |= AN_REQ_SRV_RULES;
2941 }
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02002942 else if ((!strcmp(args[0], "force-persist")) ||
2943 (!strcmp(args[0], "ignore-persist"))) {
2944 struct persist_rule *rule;
Willy Tarreau4de91492010-01-22 19:10:05 +01002945
2946 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002947 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01002948 err_code |= ERR_ALERT | ERR_FATAL;
2949 goto out;
2950 }
2951
Cyril Bonté4288c5a2018-03-12 22:02:59 +01002952 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau4de91492010-01-22 19:10:05 +01002953 err_code |= ERR_WARN;
2954
Willy Tarreauef6494c2010-01-28 17:12:36 +01002955 if (strcmp(args[1], "if") != 0 && strcmp(args[1], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002956 ha_alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
2957 file, linenum, args[0]);
Willy Tarreau4de91492010-01-22 19:10:05 +01002958 err_code |= ERR_ALERT | ERR_FATAL;
2959 goto out;
2960 }
2961
Christopher Faulet1b421ea2017-09-22 14:38:56 +02002962 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 1, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002963 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' rule : %s.\n",
2964 file, linenum, args[0], errmsg);
Willy Tarreau4de91492010-01-22 19:10:05 +01002965 err_code |= ERR_ALERT | ERR_FATAL;
2966 goto out;
2967 }
2968
Willy Tarreaua91d0a52013-03-25 08:12:18 +01002969 /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is
2970 * where force-persist is applied.
2971 */
2972 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum);
Willy Tarreau4de91492010-01-22 19:10:05 +01002973
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002974 rule = calloc(1, sizeof(*rule));
Willy Tarreau4de91492010-01-22 19:10:05 +01002975 rule->cond = cond;
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02002976 if (!strcmp(args[0], "force-persist")) {
2977 rule->type = PERSIST_TYPE_FORCE;
2978 } else {
2979 rule->type = PERSIST_TYPE_IGNORE;
2980 }
Willy Tarreau4de91492010-01-22 19:10:05 +01002981 LIST_INIT(&rule->list);
Cyril Bonté47fdd8e2010-04-25 00:00:51 +02002982 LIST_ADDQ(&curproxy->persist_rules, &rule->list);
Willy Tarreau4de91492010-01-22 19:10:05 +01002983 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01002984 else if (!strcmp(args[0], "stick-table")) {
2985 int myidx = 1;
Willy Tarreaue45288c2015-05-26 10:49:46 +02002986 struct proxy *other;
2987
Willy Tarreauc7867682018-07-27 10:26:22 +02002988 if (curproxy == &defproxy) {
2989 ha_alert("parsing [%s:%d] : 'stick-table' is not supported in 'defaults' section.\n",
2990 file, linenum);
2991 err_code |= ERR_ALERT | ERR_FATAL;
2992 goto out;
2993 }
2994
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +02002995 other = proxy_tbl_by_name(curproxy->id);
Willy Tarreaue45288c2015-05-26 10:49:46 +02002996 if (other) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01002997 ha_alert("parsing [%s:%d] : stick-table name '%s' conflicts with table declared in %s '%s' at %s:%d.\n",
2998 file, linenum, curproxy->id, proxy_type_str(other), other->id, other->conf.file, other->conf.line);
Willy Tarreaue45288c2015-05-26 10:49:46 +02002999 err_code |= ERR_ALERT | ERR_FATAL;
3000 goto out;
3001 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003002
Emeric Brun32da3c42010-09-23 18:39:19 +02003003 curproxy->table.id = curproxy->id;
Emeric Brunb982a3d2010-01-04 15:45:53 +01003004 curproxy->table.type = (unsigned int)-1;
3005 while (*args[myidx]) {
3006 const char *err;
3007
3008 if (strcmp(args[myidx], "size") == 0) {
3009 myidx++;
3010 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003011 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
3012 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003013 err_code |= ERR_ALERT | ERR_FATAL;
3014 goto out;
3015 }
3016 if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003017 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
3018 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003019 err_code |= ERR_ALERT | ERR_FATAL;
3020 goto out;
3021 }
Willy Tarreau0c559312010-01-26 18:36:26 +01003022 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01003023 }
Emeric Brun32da3c42010-09-23 18:39:19 +02003024 else if (strcmp(args[myidx], "peers") == 0) {
3025 myidx++;
Godbach50523162013-12-11 19:48:57 +08003026 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003027 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
3028 file, linenum, args[myidx-1]);
Godbachff115542014-04-21 21:52:23 +08003029 err_code |= ERR_ALERT | ERR_FATAL;
3030 goto out;
Godbach50523162013-12-11 19:48:57 +08003031 }
Emeric Brun32da3c42010-09-23 18:39:19 +02003032 curproxy->table.peers.name = strdup(args[myidx++]);
3033 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003034 else if (strcmp(args[myidx], "expire") == 0) {
3035 myidx++;
3036 if (!*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003037 ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
3038 file, linenum, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003039 err_code |= ERR_ALERT | ERR_FATAL;
3040 goto out;
3041 }
3042 err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
3043 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003044 ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
3045 file, linenum, *err, args[myidx-1]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003046 err_code |= ERR_ALERT | ERR_FATAL;
3047 goto out;
3048 }
Ben Cabot3b90f0a2016-01-20 09:44:39 +00003049 if (val > INT_MAX) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003050 ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
3051 file, linenum, val);
Ben Cabot3b90f0a2016-01-20 09:44:39 +00003052 err_code |= ERR_ALERT | ERR_FATAL;
3053 goto out;
3054 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003055 curproxy->table.expire = val;
Willy Tarreau0c559312010-01-26 18:36:26 +01003056 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01003057 }
3058 else if (strcmp(args[myidx], "nopurge") == 0) {
3059 curproxy->table.nopurge = 1;
Willy Tarreau0c559312010-01-26 18:36:26 +01003060 myidx++;
Emeric Brunb982a3d2010-01-04 15:45:53 +01003061 }
3062 else if (strcmp(args[myidx], "type") == 0) {
3063 myidx++;
3064 if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003065 ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
3066 file, linenum, args[myidx]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003067 err_code |= ERR_ALERT | ERR_FATAL;
3068 goto out;
3069 }
Willy Tarreau0c559312010-01-26 18:36:26 +01003070 /* myidx already points to next arg */
3071 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02003072 else if (strcmp(args[myidx], "store") == 0) {
Willy Tarreauac782882010-06-20 10:41:54 +02003073 int type, err;
Willy Tarreau888617d2010-06-20 09:11:39 +02003074 char *cw, *nw, *sa;
Willy Tarreau08d5f982010-06-06 13:34:54 +02003075
3076 myidx++;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02003077 nw = args[myidx];
3078 while (*nw) {
3079 /* the "store" keyword supports a comma-separated list */
3080 cw = nw;
Willy Tarreau888617d2010-06-20 09:11:39 +02003081 sa = NULL; /* store arg */
3082 while (*nw && *nw != ',') {
3083 if (*nw == '(') {
3084 *nw = 0;
3085 sa = ++nw;
3086 while (*nw != ')') {
3087 if (!*nw) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003088 ha_alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
3089 file, linenum, args[0], cw);
Willy Tarreau888617d2010-06-20 09:11:39 +02003090 err_code |= ERR_ALERT | ERR_FATAL;
3091 goto out;
3092 }
3093 nw++;
3094 }
3095 *nw = '\0';
3096 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02003097 nw++;
Willy Tarreau888617d2010-06-20 09:11:39 +02003098 }
Willy Tarreaub084e9c2010-06-19 07:12:36 +02003099 if (*nw)
3100 *nw++ = '\0';
3101 type = stktable_get_data_type(cw);
3102 if (type < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003103 ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
3104 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02003105 err_code |= ERR_ALERT | ERR_FATAL;
3106 goto out;
3107 }
Willy Tarreauac782882010-06-20 10:41:54 +02003108
3109 err = stktable_alloc_data_type(&curproxy->table, type, sa);
3110 switch (err) {
3111 case PE_NONE: break;
3112 case PE_EXIST:
Christopher Faulet767a84b2017-11-24 16:50:31 +01003113 ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
3114 file, linenum, args[0], cw);
Willy Tarreaub084e9c2010-06-19 07:12:36 +02003115 err_code |= ERR_WARN;
Willy Tarreauac782882010-06-20 10:41:54 +02003116 break;
3117
3118 case PE_ARG_MISSING:
Christopher Faulet767a84b2017-11-24 16:50:31 +01003119 ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
3120 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02003121 err_code |= ERR_ALERT | ERR_FATAL;
3122 goto out;
3123
3124 case PE_ARG_NOT_USED:
Christopher Faulet767a84b2017-11-24 16:50:31 +01003125 ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
3126 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02003127 err_code |= ERR_ALERT | ERR_FATAL;
3128 goto out;
3129
3130 default:
Christopher Faulet767a84b2017-11-24 16:50:31 +01003131 ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
3132 file, linenum, args[0], cw);
Willy Tarreauac782882010-06-20 10:41:54 +02003133 err_code |= ERR_ALERT | ERR_FATAL;
3134 goto out;
Willy Tarreaub084e9c2010-06-19 07:12:36 +02003135 }
Willy Tarreau08d5f982010-06-06 13:34:54 +02003136 }
3137 myidx++;
3138 }
Willy Tarreau0c559312010-01-26 18:36:26 +01003139 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003140 ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
3141 file, linenum, args[myidx]);
Willy Tarreau0c559312010-01-26 18:36:26 +01003142 err_code |= ERR_ALERT | ERR_FATAL;
3143 goto out;
Emeric Brunb982a3d2010-01-04 15:45:53 +01003144 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003145 }
3146
3147 if (!curproxy->table.size) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003148 ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
3149 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003150 err_code |= ERR_ALERT | ERR_FATAL;
3151 goto out;
3152 }
3153
3154 if (curproxy->table.type == (unsigned int)-1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003155 ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
3156 file, linenum);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003157 err_code |= ERR_ALERT | ERR_FATAL;
3158 goto out;
3159 }
3160 }
3161 else if (!strcmp(args[0], "stick")) {
Emeric Brunb982a3d2010-01-04 15:45:53 +01003162 struct sticking_rule *rule;
Willy Tarreau12785782012-04-27 21:37:17 +02003163 struct sample_expr *expr;
Emeric Brunb982a3d2010-01-04 15:45:53 +01003164 int myidx = 0;
3165 const char *name = NULL;
3166 int flags;
3167
3168 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003169 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003170 err_code |= ERR_ALERT | ERR_FATAL;
3171 goto out;
3172 }
3173
3174 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
3175 err_code |= ERR_WARN;
3176 goto out;
3177 }
3178
3179 myidx++;
3180 if ((strcmp(args[myidx], "store") == 0) ||
3181 (strcmp(args[myidx], "store-request") == 0)) {
3182 myidx++;
3183 flags = STK_IS_STORE;
3184 }
3185 else if (strcmp(args[myidx], "store-response") == 0) {
3186 myidx++;
3187 flags = STK_IS_STORE | STK_ON_RSP;
3188 }
3189 else if (strcmp(args[myidx], "match") == 0) {
3190 myidx++;
3191 flags = STK_IS_MATCH;
3192 }
3193 else if (strcmp(args[myidx], "on") == 0) {
3194 myidx++;
3195 flags = STK_IS_MATCH | STK_IS_STORE;
3196 }
3197 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003198 ha_alert("parsing [%s:%d] : '%s' expects 'on', 'match', or 'store'.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003199 err_code |= ERR_ALERT | ERR_FATAL;
3200 goto out;
3201 }
3202
3203 if (*(args[myidx]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003204 ha_alert("parsing [%s:%d] : '%s' expects a fetch method.\n", file, linenum, args[0]);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003205 err_code |= ERR_ALERT | ERR_FATAL;
3206 goto out;
3207 }
3208
Willy Tarreaua4312fa2013-04-02 16:34:32 +02003209 curproxy->conf.args.ctx = ARGC_STK;
Thierry FOURNIEReeaa9512014-02-11 14:00:19 +01003210 expr = sample_parse_expr(args, &myidx, file, linenum, &errmsg, &curproxy->conf.args);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003211 if (!expr) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003212 ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003213 err_code |= ERR_ALERT | ERR_FATAL;
3214 goto out;
3215 }
3216
3217 if (flags & STK_ON_RSP) {
Willy Tarreau80aca902013-01-07 15:42:20 +01003218 if (!(expr->fetch->val & SMP_VAL_BE_STO_RUL)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003219 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available for 'store-response'.\n",
3220 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01003221 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09003222 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003223 goto out;
3224 }
3225 } else {
Willy Tarreau80aca902013-01-07 15:42:20 +01003226 if (!(expr->fetch->val & SMP_VAL_BE_SET_SRV)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003227 ha_alert("parsing [%s:%d] : '%s': fetch method '%s' extracts information from '%s', none of which is available during request.\n",
3228 file, linenum, args[0], expr->fetch->kw, sample_src_names(expr->fetch->use));
Emeric Brunb982a3d2010-01-04 15:45:53 +01003229 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09003230 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003231 goto out;
3232 }
3233 }
3234
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02003235 /* check if we need to allocate an hdr_idx struct for HTTP parsing */
Willy Tarreau25320b22013-03-24 07:22:08 +01003236 curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
Willy Tarreau1b6c00c2012-10-05 22:41:26 +02003237
Emeric Brunb982a3d2010-01-04 15:45:53 +01003238 if (strcmp(args[myidx], "table") == 0) {
3239 myidx++;
3240 name = args[myidx++];
3241 }
3242
Willy Tarreauef6494c2010-01-28 17:12:36 +01003243 if (strcmp(args[myidx], "if") == 0 || strcmp(args[myidx], "unless") == 0) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003244 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + myidx, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003245 ha_alert("parsing [%s:%d] : '%s': error detected while parsing sticking condition : %s.\n",
3246 file, linenum, args[0], errmsg);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003247 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09003248 free(expr);
Emeric Brunb982a3d2010-01-04 15:45:53 +01003249 goto out;
3250 }
Emeric Brunb982a3d2010-01-04 15:45:53 +01003251 }
Willy Tarreauef6494c2010-01-28 17:12:36 +01003252 else if (*(args[myidx])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003253 ha_alert("parsing [%s:%d] : '%s': unknown keyword '%s'.\n",
3254 file, linenum, args[0], args[myidx]);
Willy Tarreauef6494c2010-01-28 17:12:36 +01003255 err_code |= ERR_ALERT | ERR_FATAL;
Simon Horman5e55f5d2011-07-15 13:14:07 +09003256 free(expr);
Willy Tarreauef6494c2010-01-28 17:12:36 +01003257 goto out;
3258 }
Emeric Brun97679e72010-09-23 17:56:44 +02003259 if (flags & STK_ON_RSP)
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003260 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum);
Emeric Brun97679e72010-09-23 17:56:44 +02003261 else
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003262 err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum);
Willy Tarreauf1e98b82010-01-28 17:59:39 +01003263
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003264 rule = calloc(1, sizeof(*rule));
Emeric Brunb982a3d2010-01-04 15:45:53 +01003265 rule->cond = cond;
3266 rule->expr = expr;
3267 rule->flags = flags;
3268 rule->table.name = name ? strdup(name) : NULL;
3269 LIST_INIT(&rule->list);
3270 if (flags & STK_ON_RSP)
3271 LIST_ADDQ(&curproxy->storersp_rules, &rule->list);
3272 else
3273 LIST_ADDQ(&curproxy->sticking_rules, &rule->list);
3274 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003275 else if (!strcmp(args[0], "stats")) {
3276 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
3277 curproxy->uri_auth = NULL; /* we must detach from the default config */
3278
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01003279 if (!*args[1]) {
3280 goto stats_error_parsing;
Cyril Bonté474be412010-10-12 00:14:36 +02003281 } else if (!strcmp(args[1], "admin")) {
3282 struct stats_admin_rule *rule;
3283
3284 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003285 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 +02003286 err_code |= ERR_ALERT | ERR_FATAL;
3287 goto out;
3288 }
3289
3290 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003291 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02003292 err_code |= ERR_ALERT | ERR_ABORT;
3293 goto out;
3294 }
3295
3296 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003297 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
3298 file, linenum, args[0], args[1]);
Cyril Bonté474be412010-10-12 00:14:36 +02003299 err_code |= ERR_ALERT | ERR_FATAL;
3300 goto out;
3301 }
Christopher Faulet1b421ea2017-09-22 14:38:56 +02003302 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003303 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' rule : %s.\n",
3304 file, linenum, args[0], args[1], errmsg);
Cyril Bonté474be412010-10-12 00:14:36 +02003305 err_code |= ERR_ALERT | ERR_FATAL;
3306 goto out;
3307 }
3308
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003309 err_code |= warnif_cond_conflicts(cond,
3310 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3311 file, linenum);
Cyril Bonté474be412010-10-12 00:14:36 +02003312
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003313 rule = calloc(1, sizeof(*rule));
Cyril Bonté474be412010-10-12 00:14:36 +02003314 rule->cond = cond;
3315 LIST_INIT(&rule->list);
3316 LIST_ADDQ(&curproxy->uri_auth->admin_rules, &rule->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003317 } else if (!strcmp(args[1], "uri")) {
3318 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003319 ha_alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003320 err_code |= ERR_ALERT | ERR_FATAL;
3321 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003322 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003323 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003324 err_code |= ERR_ALERT | ERR_ABORT;
3325 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003326 }
3327 } else if (!strcmp(args[1], "realm")) {
3328 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003329 ha_alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003330 err_code |= ERR_ALERT | ERR_FATAL;
3331 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003332 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003333 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003334 err_code |= ERR_ALERT | ERR_ABORT;
3335 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003336 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02003337 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01003338 unsigned interval;
3339
3340 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
3341 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003342 ha_alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
3343 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003344 err_code |= ERR_ALERT | ERR_FATAL;
3345 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02003346 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003347 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003348 err_code |= ERR_ALERT | ERR_ABORT;
3349 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02003350 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003351 } else if (!strcmp(args[1], "http-request")) { /* request access control: allow/deny/auth */
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003352 struct act_rule *rule;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003353
3354 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003355 ha_alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003356 err_code |= ERR_ALERT | ERR_FATAL;
3357 goto out;
3358 }
3359
3360 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003361 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003362 err_code |= ERR_ALERT | ERR_ABORT;
3363 goto out;
3364 }
3365
Willy Tarreauff011f22011-01-06 17:51:27 +01003366 if (!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02003367 !LIST_PREV(&curproxy->uri_auth->http_req_rules, struct act_rule *, list)->cond) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003368 ha_warning("parsing [%s:%d]: previous '%s' action has no condition attached, further entries are NOOP.\n",
3369 file, linenum, args[0]);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003370 err_code |= ERR_WARN;
3371 }
3372
Willy Tarreauff011f22011-01-06 17:51:27 +01003373 rule = parse_http_req_cond((const char **)args + 2, file, linenum, curproxy);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003374
Willy Tarreauff011f22011-01-06 17:51:27 +01003375 if (!rule) {
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003376 err_code |= ERR_ALERT | ERR_ABORT;
3377 goto out;
3378 }
3379
Willy Tarreaua91d0a52013-03-25 08:12:18 +01003380 err_code |= warnif_cond_conflicts(rule->cond,
3381 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
3382 file, linenum);
Willy Tarreauff011f22011-01-06 17:51:27 +01003383 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01003384
Willy Tarreaubaaee002006-06-26 02:48:02 +02003385 } else if (!strcmp(args[1], "auth")) {
3386 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003387 ha_alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003388 err_code |= ERR_ALERT | ERR_FATAL;
3389 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003390 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003391 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003392 err_code |= ERR_ALERT | ERR_ABORT;
3393 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003394 }
3395 } else if (!strcmp(args[1], "scope")) {
3396 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003397 ha_alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003398 err_code |= ERR_ALERT | ERR_FATAL;
3399 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003400 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003401 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003402 err_code |= ERR_ALERT | ERR_ABORT;
3403 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003404 }
3405 } else if (!strcmp(args[1], "enable")) {
3406 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003407 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003408 err_code |= ERR_ALERT | ERR_ABORT;
3409 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003410 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02003411 } else if (!strcmp(args[1], "hide-version")) {
3412 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003413 ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02003414 err_code |= ERR_ALERT | ERR_ABORT;
3415 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02003416 }
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01003417 } else if (!strcmp(args[1], "show-legends")) {
3418 if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003419 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki15514c22010-01-04 16:03:09 +01003420 err_code |= ERR_ALERT | ERR_ABORT;
3421 goto out;
3422 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003423 } else if (!strcmp(args[1], "show-node")) {
3424
3425 if (*args[2]) {
3426 int i;
3427 char c;
3428
3429 for (i=0; args[2][i]; i++) {
3430 c = args[2][i];
Willy Tarreau88e05812010-03-03 00:16:00 +01003431 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
3432 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003433 break;
3434 }
3435
3436 if (!i || args[2][i]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003437 ha_alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
3438 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
3439 file, linenum, args[0], args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003440 err_code |= ERR_ALERT | ERR_FATAL;
3441 goto out;
3442 }
3443 }
3444
3445 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003446 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003447 err_code |= ERR_ALERT | ERR_ABORT;
3448 goto out;
3449 }
3450 } else if (!strcmp(args[1], "show-desc")) {
3451 char *desc = NULL;
3452
3453 if (*args[2]) {
3454 int i, len=0;
3455 char *d;
3456
Willy Tarreau348acfe2014-04-14 15:00:39 +02003457 for (i = 2; *args[i]; i++)
3458 len += strlen(args[i]) + 1;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003459
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003460 desc = d = calloc(1, len);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003461
Willy Tarreau348acfe2014-04-14 15:00:39 +02003462 d += snprintf(d, desc + len - d, "%s", args[2]);
3463 for (i = 3; *args[i]; i++)
3464 d += snprintf(d, desc + len - d, " %s", args[i]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003465 }
3466
3467 if (!*args[2] && !global.desc)
Christopher Faulet767a84b2017-11-24 16:50:31 +01003468 ha_warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
3469 file, linenum, args[1]);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003470 else {
3471 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
3472 free(desc);
Christopher Faulet767a84b2017-11-24 16:50:31 +01003473 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02003474 err_code |= ERR_ALERT | ERR_ABORT;
3475 goto out;
3476 }
3477 free(desc);
3478 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003479 } else {
Krzysztof Piotr Oledzki260a3bb2010-01-06 16:25:05 +01003480stats_error_parsing:
Christopher Faulet767a84b2017-11-24 16:50:31 +01003481 ha_alert("parsing [%s:%d]: %s '%s', expects 'admin', 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.\n",
3482 file, linenum, *args[1]?"unknown stats parameter":"missing keyword in", args[*args[1]?1:0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003483 err_code |= ERR_ALERT | ERR_FATAL;
3484 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003485 }
3486 }
3487 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01003488 int optnum;
3489
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003490 if (*(args[1]) == '\0') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003491 ha_alert("parsing [%s:%d]: '%s' expects an option name.\n",
3492 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003493 err_code |= ERR_ALERT | ERR_FATAL;
3494 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003495 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01003496
3497 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
3498 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01003499 if (cfg_opts[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003500 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
3501 file, linenum, cfg_opts[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01003502 err_code |= ERR_ALERT | ERR_FATAL;
3503 goto out;
3504 }
William Lallemanddf1425a2015-04-28 20:17:49 +02003505 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3506 goto out;
3507
Willy Tarreau93893792009-07-23 13:19:11 +02003508 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
3509 err_code |= ERR_WARN;
3510 goto out;
3511 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003512
Willy Tarreau3842f002009-06-14 11:39:52 +02003513 curproxy->no_options &= ~cfg_opts[optnum].val;
3514 curproxy->options &= ~cfg_opts[optnum].val;
3515
3516 switch (kwm) {
3517 case KWM_STD:
3518 curproxy->options |= cfg_opts[optnum].val;
3519 break;
3520 case KWM_NO:
3521 curproxy->no_options |= cfg_opts[optnum].val;
3522 break;
3523 case KWM_DEF: /* already cleared */
3524 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02003525 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003526
Willy Tarreau93893792009-07-23 13:19:11 +02003527 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01003528 }
3529 }
3530
Willy Tarreau66aa61f2009-01-18 21:44:07 +01003531 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
3532 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Cyril Bonté62846b22010-11-01 19:26:00 +01003533 if (cfg_opts2[optnum].cap == PR_CAP_NONE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003534 ha_alert("parsing [%s:%d]: option '%s' is not supported due to build options.\n",
3535 file, linenum, cfg_opts2[optnum].name);
Cyril Bonté62846b22010-11-01 19:26:00 +01003536 err_code |= ERR_ALERT | ERR_FATAL;
3537 goto out;
3538 }
William Lallemanddf1425a2015-04-28 20:17:49 +02003539 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3540 goto out;
Willy Tarreau93893792009-07-23 13:19:11 +02003541 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
3542 err_code |= ERR_WARN;
3543 goto out;
3544 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01003545
Willy Tarreau3842f002009-06-14 11:39:52 +02003546 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
3547 curproxy->options2 &= ~cfg_opts2[optnum].val;
3548
3549 switch (kwm) {
3550 case KWM_STD:
3551 curproxy->options2 |= cfg_opts2[optnum].val;
3552 break;
3553 case KWM_NO:
3554 curproxy->no_options2 |= cfg_opts2[optnum].val;
3555 break;
3556 case KWM_DEF: /* already cleared */
3557 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02003558 }
Willy Tarreau93893792009-07-23 13:19:11 +02003559 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01003560 }
3561 }
3562
Willy Tarreau02bce8b2014-01-30 00:15:28 +01003563 /* HTTP options override each other. They can be cancelled using
3564 * "no option xxx" which only switches to default mode if the mode
3565 * was this one (useful for cancelling options set in defaults
3566 * sections).
3567 */
Christopher Faulet315b39c2018-09-21 16:26:19 +02003568 if (strcmp(args[1], "httpclose") == 0 || strcmp(args[1], "forceclose") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02003569 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3570 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01003571 if (kwm == KWM_STD) {
3572 curproxy->options &= ~PR_O_HTTP_MODE;
Christopher Faulet315b39c2018-09-21 16:26:19 +02003573 curproxy->options |= PR_O_HTTP_CLO;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01003574 goto out;
3575 }
3576 else if (kwm == KWM_NO) {
Christopher Faulet315b39c2018-09-21 16:26:19 +02003577 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_CLO)
Willy Tarreau02bce8b2014-01-30 00:15:28 +01003578 curproxy->options &= ~PR_O_HTTP_MODE;
3579 goto out;
3580 }
3581 }
3582 else if (strcmp(args[1], "http-server-close") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02003583 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3584 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01003585 if (kwm == KWM_STD) {
3586 curproxy->options &= ~PR_O_HTTP_MODE;
3587 curproxy->options |= PR_O_HTTP_SCL;
3588 goto out;
3589 }
3590 else if (kwm == KWM_NO) {
3591 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL)
3592 curproxy->options &= ~PR_O_HTTP_MODE;
3593 goto out;
3594 }
3595 }
3596 else if (strcmp(args[1], "http-keep-alive") == 0) {
William Lallemanddf1425a2015-04-28 20:17:49 +02003597 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3598 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01003599 if (kwm == KWM_STD) {
3600 curproxy->options &= ~PR_O_HTTP_MODE;
3601 curproxy->options |= PR_O_HTTP_KAL;
3602 goto out;
3603 }
3604 else if (kwm == KWM_NO) {
3605 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_KAL)
3606 curproxy->options &= ~PR_O_HTTP_MODE;
3607 goto out;
3608 }
3609 }
3610 else if (strcmp(args[1], "http-tunnel") == 0) {
Christopher Faulet4212a302018-09-21 10:42:19 +02003611 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[1], NULL)) {
3612 err_code |= ERR_WARN;
3613 goto out;
3614 }
William Lallemanddf1425a2015-04-28 20:17:49 +02003615 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3616 goto out;
Willy Tarreau02bce8b2014-01-30 00:15:28 +01003617 if (kwm == KWM_STD) {
3618 curproxy->options &= ~PR_O_HTTP_MODE;
3619 curproxy->options |= PR_O_HTTP_TUN;
3620 goto out;
3621 }
3622 else if (kwm == KWM_NO) {
3623 if ((curproxy->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN)
3624 curproxy->options &= ~PR_O_HTTP_MODE;
3625 goto out;
3626 }
3627 }
3628
Joseph Lynch726ab712015-05-11 23:25:34 -07003629 /* Redispatch can take an integer argument that control when the
3630 * resispatch occurs. All values are relative to the retries option.
3631 * This can be cancelled using "no option xxx".
3632 */
3633 if (strcmp(args[1], "redispatch") == 0) {
3634 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL)) {
3635 err_code |= ERR_WARN;
3636 goto out;
3637 }
3638
3639 curproxy->no_options &= ~PR_O_REDISP;
3640 curproxy->options &= ~PR_O_REDISP;
3641
3642 switch (kwm) {
3643 case KWM_STD:
3644 curproxy->options |= PR_O_REDISP;
3645 curproxy->redispatch_after = -1;
3646 if(*args[2]) {
3647 curproxy->redispatch_after = atol(args[2]);
3648 }
3649 break;
3650 case KWM_NO:
3651 curproxy->no_options |= PR_O_REDISP;
3652 curproxy->redispatch_after = 0;
3653 break;
3654 case KWM_DEF: /* already cleared */
3655 break;
3656 }
3657 goto out;
3658 }
3659
Willy Tarreau3842f002009-06-14 11:39:52 +02003660 if (kwm != KWM_STD) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003661 ha_alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
3662 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003663 err_code |= ERR_ALERT | ERR_FATAL;
3664 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003665 }
3666
Emeric Brun3a058f32009-06-30 18:26:00 +02003667 if (!strcmp(args[1], "httplog")) {
William Lallemand723b73a2012-02-08 16:37:49 +01003668 char *logformat;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003669 /* generate a complete HTTP log */
William Lallemand723b73a2012-02-08 16:37:49 +01003670 logformat = default_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02003671 if (*(args[2]) != '\0') {
3672 if (!strcmp(args[2], "clf")) {
3673 curproxy->options2 |= PR_O2_CLFLOG;
William Lallemand723b73a2012-02-08 16:37:49 +01003674 logformat = clf_http_log_format;
Emeric Brun3a058f32009-06-30 18:26:00 +02003675 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003676 ha_alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003677 err_code |= ERR_ALERT | ERR_FATAL;
3678 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02003679 }
William Lallemanddf1425a2015-04-28 20:17:49 +02003680 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
3681 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02003682 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02003683 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
3684 char *oldlogformat = "log-format";
3685 char *clflogformat = "";
3686
3687 if (curproxy->conf.logformat_string == default_http_log_format)
3688 oldlogformat = "option httplog";
3689 else if (curproxy->conf.logformat_string == default_tcp_log_format)
3690 oldlogformat = "option tcplog";
3691 else if (curproxy->conf.logformat_string == clf_http_log_format)
3692 oldlogformat = "option httplog clf";
3693 if (logformat == clf_http_log_format)
3694 clflogformat = " clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01003695 ha_warning("parsing [%s:%d]: 'option httplog%s' overrides previous '%s' in 'defaults' section.\n",
3696 file, linenum, clflogformat, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02003697 }
Willy Tarreau62a61232013-04-12 18:13:46 +02003698 if (curproxy->conf.logformat_string != default_http_log_format &&
3699 curproxy->conf.logformat_string != default_tcp_log_format &&
3700 curproxy->conf.logformat_string != clf_http_log_format)
3701 free(curproxy->conf.logformat_string);
3702 curproxy->conf.logformat_string = logformat;
3703
3704 free(curproxy->conf.lfs_file);
3705 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
3706 curproxy->conf.lfs_line = curproxy->conf.args.line;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01003707
3708 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
3709 ha_warning("parsing [%s:%d] : backend '%s' : 'option httplog' directive is ignored in backends.\n",
3710 file, linenum, curproxy->id);
3711 err_code |= ERR_WARN;
3712 }
Emeric Brun3a058f32009-06-30 18:26:00 +02003713 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01003714 else if (!strcmp(args[1], "tcplog")) {
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02003715 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
3716 char *oldlogformat = "log-format";
3717
3718 if (curproxy->conf.logformat_string == default_http_log_format)
3719 oldlogformat = "option httplog";
3720 else if (curproxy->conf.logformat_string == default_tcp_log_format)
3721 oldlogformat = "option tcplog";
3722 else if (curproxy->conf.logformat_string == clf_http_log_format)
3723 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01003724 ha_warning("parsing [%s:%d]: 'option tcplog' overrides previous '%s' in 'defaults' section.\n",
3725 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02003726 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003727 /* generate a detailed TCP log */
Willy Tarreau62a61232013-04-12 18:13:46 +02003728 if (curproxy->conf.logformat_string != default_http_log_format &&
3729 curproxy->conf.logformat_string != default_tcp_log_format &&
3730 curproxy->conf.logformat_string != clf_http_log_format)
3731 free(curproxy->conf.logformat_string);
3732 curproxy->conf.logformat_string = default_tcp_log_format;
3733
3734 free(curproxy->conf.lfs_file);
3735 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
3736 curproxy->conf.lfs_line = curproxy->conf.args.line;
William Lallemanddf1425a2015-04-28 20:17:49 +02003737
3738 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3739 goto out;
Tim Duesterhus9ad9f352018-02-05 20:52:27 +01003740
3741 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
3742 ha_warning("parsing [%s:%d] : backend '%s' : 'option tcplog' directive is ignored in backends.\n",
3743 file, linenum, curproxy->id);
3744 err_code |= ERR_WARN;
3745 }
William Lallemandbddd4fd2012-02-27 11:23:10 +01003746 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003747 else if (!strcmp(args[1], "tcpka")) {
Willy Tarreau87b09662015-04-03 00:22:06 +02003748 /* enable TCP keep-alives on client and server streams */
Willy Tarreau13943ab2006-12-31 00:24:10 +01003749 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003750 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01003751
William Lallemanddf1425a2015-04-28 20:17:49 +02003752 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3753 goto out;
3754
Willy Tarreau13943ab2006-12-31 00:24:10 +01003755 if (curproxy->cap & PR_CAP_FE)
3756 curproxy->options |= PR_O_TCP_CLI_KA;
3757 if (curproxy->cap & PR_CAP_BE)
3758 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003759 }
3760 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01003761 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003762 err_code |= ERR_WARN;
3763
Willy Tarreaubaaee002006-06-26 02:48:02 +02003764 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02003765 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01003766 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02003767 curproxy->options2 &= ~PR_O2_CHK_ANY;
3768 curproxy->options2 |= PR_O2_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003769 if (!*args[2]) { /* no argument */
3770 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
3771 curproxy->check_len = strlen(DEF_CHECK_REQ);
3772 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreaue9d87882010-01-27 11:28:42 +01003773 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003774 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003775 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01003776 "OPTIONS %s HTTP/1.0\r\n", args[2]); /* URI to use */
Willy Tarreaubaaee002006-06-26 02:48:02 +02003777 } else { /* more arguments : METHOD URI [HTTP_VER] */
Willy Tarreaue9d87882010-01-27 11:28:42 +01003778 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n");
Willy Tarreaubaaee002006-06-26 02:48:02 +02003779 if (*args[4])
3780 reqlen += strlen(args[4]);
3781 else
3782 reqlen += strlen("HTTP/1.0");
3783
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003784 curproxy->check_req = malloc(reqlen);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003785 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
Willy Tarreaue9d87882010-01-27 11:28:42 +01003786 "%s %s %s\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
Willy Tarreaubaaee002006-06-26 02:48:02 +02003787 }
William Lallemanddf1425a2015-04-28 20:17:49 +02003788 if (alertif_too_many_args_idx(3, 1, file, linenum, args, &err_code))
3789 goto out;
Willy Tarreauf3c69202006-07-09 16:42:34 +02003790 }
3791 else if (!strcmp(args[1], "ssl-hello-chk")) {
3792 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01003793 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003794 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01003795
Willy Tarreaua534fea2008-08-03 12:19:50 +02003796 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01003797 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02003798 curproxy->options2 &= ~PR_O2_CHK_ANY;
Willy Tarreau07a54902010-03-29 18:33:29 +02003799 curproxy->options2 |= PR_O2_SSL3_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02003800
3801 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3802 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003803 }
Willy Tarreau23677902007-05-08 23:50:35 +02003804 else if (!strcmp(args[1], "smtpchk")) {
3805 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02003806 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01003807 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02003808 curproxy->options2 &= ~PR_O2_CHK_ANY;
3809 curproxy->options2 |= PR_O2_SMTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02003810
3811 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
3812 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
3813 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
3814 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
3815 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
3816 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003817 curproxy->check_req = malloc(reqlen);
Willy Tarreau23677902007-05-08 23:50:35 +02003818 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
3819 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
3820 } else {
3821 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
3822 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
3823 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
3824 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
3825 }
3826 }
William Lallemanddf1425a2015-04-28 20:17:49 +02003827 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
3828 goto out;
Willy Tarreau23677902007-05-08 23:50:35 +02003829 }
Rauf Kuliyev38b41562011-01-04 15:14:13 +01003830 else if (!strcmp(args[1], "pgsql-check")) {
3831 /* use PostgreSQL request to check servers' health */
3832 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
3833 err_code |= ERR_WARN;
3834
3835 free(curproxy->check_req);
3836 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02003837 curproxy->options2 &= ~PR_O2_CHK_ANY;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01003838 curproxy->options2 |= PR_O2_PGSQL_CHK;
3839
3840 if (*(args[2])) {
3841 int cur_arg = 2;
3842
3843 while (*(args[cur_arg])) {
3844 if (strcmp(args[cur_arg], "user") == 0) {
3845 char * packet;
3846 uint32_t packet_len;
3847 uint32_t pv;
3848
3849 /* suboption header - needs additional argument for it */
3850 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003851 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
3852 file, linenum, args[0], args[1], args[cur_arg]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01003853 err_code |= ERR_ALERT | ERR_FATAL;
3854 goto out;
3855 }
3856
3857 /* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
3858 packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
3859 pv = htonl(0x30000); /* protocol version 3.0 */
3860
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003861 packet = calloc(1, packet_len);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01003862
3863 memcpy(packet + 4, &pv, 4);
3864
3865 /* copy "user" */
3866 memcpy(packet + 8, "user", 4);
3867
3868 /* copy username */
3869 memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
3870
3871 free(curproxy->check_req);
3872 curproxy->check_req = packet;
3873 curproxy->check_len = packet_len;
3874
3875 packet_len = htonl(packet_len);
3876 memcpy(packet, &packet_len, 4);
3877 cur_arg += 2;
3878 } else {
3879 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01003880 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
3881 file, linenum, args[0], args[1]);
Rauf Kuliyev38b41562011-01-04 15:14:13 +01003882 err_code |= ERR_ALERT | ERR_FATAL;
3883 goto out;
3884 }
3885 } /* end while loop */
3886 }
William Lallemanddf1425a2015-04-28 20:17:49 +02003887 if (alertif_too_many_args_idx(2, 1, file, linenum, args, &err_code))
3888 goto out;
Rauf Kuliyev38b41562011-01-04 15:14:13 +01003889 }
3890
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02003891 else if (!strcmp(args[1], "redis-check")) {
3892 /* use REDIS PING request to check servers' health */
3893 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
3894 err_code |= ERR_WARN;
3895
3896 free(curproxy->check_req);
3897 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02003898 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02003899 curproxy->options2 |= PR_O2_REDIS_CHK;
3900
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003901 curproxy->check_req = malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02003902 memcpy(curproxy->check_req, DEF_REDIS_CHECK_REQ, sizeof(DEF_REDIS_CHECK_REQ) - 1);
3903 curproxy->check_len = sizeof(DEF_REDIS_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02003904
3905 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
3906 goto out;
Hervé COMMOWICKec032d62011-08-05 16:23:48 +02003907 }
3908
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01003909 else if (!strcmp(args[1], "mysql-check")) {
3910 /* use MYSQL request to check servers' health */
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003911 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
3912 err_code |= ERR_WARN;
3913
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01003914 free(curproxy->check_req);
Willy Tarreau54f6a582010-02-01 16:31:14 +01003915 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02003916 curproxy->options2 &= ~PR_O2_CHK_ANY;
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01003917 curproxy->options2 |= PR_O2_MYSQL_CHK;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003918
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02003919 /* This is an example of a MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003920 * const char mysql40_client_auth_pkt[] = {
3921 * "\x0e\x00\x00" // packet length
3922 * "\x01" // packet number
3923 * "\x00\x00" // client capabilities
3924 * "\x00\x00\x01" // max packet
3925 * "haproxy\x00" // username (null terminated string)
3926 * "\x00" // filler (always 0x00)
3927 * "\x01\x00\x00" // packet length
3928 * "\x00" // packet number
3929 * "\x01" // COM_QUIT command
3930 * };
3931 */
3932
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02003933 /* This is an example of a MySQL >=4.1 client Authentication packet provided by Nenad Merdanovic.
3934 * const char mysql41_client_auth_pkt[] = {
3935 * "\x0e\x00\x00\" // packet length
3936 * "\x01" // packet number
3937 * "\x00\x00\x00\x00" // client capabilities
3938 * "\x00\x00\x00\x01" // max packet
3939 * "\x21" // character set (UTF-8)
3940 * char[23] // All zeroes
3941 * "haproxy\x00" // username (null terminated string)
3942 * "\x00" // filler (always 0x00)
3943 * "\x01\x00\x00" // packet length
3944 * "\x00" // packet number
3945 * "\x01" // COM_QUIT command
3946 * };
3947 */
3948
3949
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003950 if (*(args[2])) {
3951 int cur_arg = 2;
3952
3953 while (*(args[cur_arg])) {
3954 if (strcmp(args[cur_arg], "user") == 0) {
3955 char *mysqluser;
3956 int packetlen, reqlen, userlen;
3957
3958 /* suboption header - needs additional argument for it */
3959 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003960 ha_alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
3961 file, linenum, args[0], args[1], args[cur_arg]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003962 err_code |= ERR_ALERT | ERR_FATAL;
3963 goto out;
3964 }
3965 mysqluser = args[cur_arg + 1];
3966 userlen = strlen(mysqluser);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003967
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02003968 if (*(args[cur_arg+2])) {
3969 if (!strcmp(args[cur_arg+2], "post-41")) {
3970 packetlen = userlen + 7 + 27;
3971 reqlen = packetlen + 9;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003972
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02003973 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003974 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02003975 curproxy->check_len = reqlen;
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02003976
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02003977 snprintf(curproxy->check_req, 4, "%c%c%c",
3978 ((unsigned char) packetlen & 0xff),
3979 ((unsigned char) (packetlen >> 8) & 0xff),
3980 ((unsigned char) (packetlen >> 16) & 0xff));
3981
3982 curproxy->check_req[3] = 1;
Olivier Houchard33320902018-10-16 18:39:38 +02003983 curproxy->check_req[5] = 0x82; // 130
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02003984 curproxy->check_req[11] = 1;
3985 curproxy->check_req[12] = 33;
3986 memcpy(&curproxy->check_req[36], mysqluser, userlen);
3987 curproxy->check_req[36 + userlen + 1 + 1] = 1;
3988 curproxy->check_req[36 + userlen + 1 + 1 + 4] = 1;
3989 cur_arg += 3;
3990 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01003991 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 +02003992 err_code |= ERR_ALERT | ERR_FATAL;
3993 goto out;
3994 }
3995 } else {
3996 packetlen = userlen + 7;
3997 reqlen = packetlen + 9;
3998
3999 free(curproxy->check_req);
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004000 curproxy->check_req = calloc(1, reqlen);
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004001 curproxy->check_len = reqlen;
4002
4003 snprintf(curproxy->check_req, 4, "%c%c%c",
4004 ((unsigned char) packetlen & 0xff),
4005 ((unsigned char) (packetlen >> 8) & 0xff),
4006 ((unsigned char) (packetlen >> 16) & 0xff));
4007
4008 curproxy->check_req[3] = 1;
Olivier Houchard33320902018-10-16 18:39:38 +02004009 curproxy->check_req[5] = 0x80;
Nenad Merdanovic6639a7c2014-05-30 14:26:32 +02004010 curproxy->check_req[8] = 1;
4011 memcpy(&curproxy->check_req[9], mysqluser, userlen);
4012 curproxy->check_req[9 + userlen + 1 + 1] = 1;
4013 curproxy->check_req[9 + userlen + 1 + 1 + 4] = 1;
4014 cur_arg += 2;
4015 }
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004016 } else {
4017 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004018 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
4019 file, linenum, args[0], args[1]);
Hervé COMMOWICK8776f1b2010-10-18 15:58:36 +02004020 err_code |= ERR_ALERT | ERR_FATAL;
4021 goto out;
4022 }
4023 } /* end while loop */
4024 }
Hervé COMMOWICK698ae002010-01-12 09:25:13 +01004025 }
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02004026 else if (!strcmp(args[1], "ldap-check")) {
4027 /* use LDAP request to check servers' health */
4028 free(curproxy->check_req);
4029 curproxy->check_req = NULL;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004030 curproxy->options2 &= ~PR_O2_CHK_ANY;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02004031 curproxy->options2 |= PR_O2_LDAP_CHK;
4032
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004033 curproxy->check_req = malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02004034 memcpy(curproxy->check_req, DEF_LDAP_CHECK_REQ, sizeof(DEF_LDAP_CHECK_REQ) - 1);
4035 curproxy->check_len = sizeof(DEF_LDAP_CHECK_REQ) - 1;
William Lallemanddf1425a2015-04-28 20:17:49 +02004036 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4037 goto out;
Gabor Lekenyb4c81e42010-09-29 18:17:05 +02004038 }
Christopher Fauletba7bc162016-11-07 21:07:38 +01004039 else if (!strcmp(args[1], "spop-check")) {
4040 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004041 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n",
4042 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01004043 err_code |= ERR_ALERT | ERR_FATAL;
4044 goto out;
4045 }
4046 if (curproxy->cap & PR_CAP_FE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004047 ha_alert("parsing [%s:%d] : '%s %s' not allowed in 'frontend' and 'listen' sections.\n",
4048 file, linenum, args[0], args[1]);
Christopher Fauletba7bc162016-11-07 21:07:38 +01004049 err_code |= ERR_ALERT | ERR_FATAL;
4050 goto out;
4051 }
4052
4053 /* use SPOE request to check servers' health */
4054 free(curproxy->check_req);
4055 curproxy->check_req = NULL;
4056 curproxy->options2 &= ~PR_O2_CHK_ANY;
4057 curproxy->options2 |= PR_O2_SPOP_CHK;
4058
Christopher Faulet8ef75252017-02-20 22:56:03 +01004059 if (spoe_prepare_healthcheck_request(&curproxy->check_req, &curproxy->check_len)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004060 ha_alert("parsing [%s:%d] : failed to prepare SPOP healthcheck request.\n", file, linenum);
Christopher Fauletba7bc162016-11-07 21:07:38 +01004061 err_code |= ERR_ALERT | ERR_FATAL;
4062 goto out;
4063 }
4064 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4065 goto out;
4066 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004067 else if (!strcmp(args[1], "tcp-check")) {
4068 /* use raw TCPCHK send/expect to check servers' health */
4069 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
4070 err_code |= ERR_WARN;
4071
4072 free(curproxy->check_req);
4073 curproxy->check_req = NULL;
4074 curproxy->options2 &= ~PR_O2_CHK_ANY;
4075 curproxy->options2 |= PR_O2_TCPCHK_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004076 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4077 goto out;
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004078 }
Simon Horman98637e52014-06-20 12:30:16 +09004079 else if (!strcmp(args[1], "external-check")) {
4080 /* excute an external command to check servers' health */
4081 free(curproxy->check_req);
4082 curproxy->check_req = NULL;
4083 curproxy->options2 &= ~PR_O2_CHK_ANY;
4084 curproxy->options2 |= PR_O2_EXT_CHK;
William Lallemanddf1425a2015-04-28 20:17:49 +02004085 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4086 goto out;
Simon Horman98637e52014-06-20 12:30:16 +09004087 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02004088 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02004089 int cur_arg;
4090
4091 /* insert x-forwarded-for field, but not for the IP address listed as an except.
4092 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02004093 */
Ross Westaf72a1d2008-08-03 10:51:45 +02004094
Willy Tarreau87cf5142011-08-19 22:57:24 +02004095 curproxy->options |= PR_O_FWDFOR | PR_O_FF_ALWAYS;
Ross Westaf72a1d2008-08-03 10:51:45 +02004096
4097 free(curproxy->fwdfor_hdr_name);
4098 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
4099 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
4100
4101 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
4102 cur_arg = 2;
4103 while (*(args[cur_arg])) {
4104 if (!strcmp(args[cur_arg], "except")) {
4105 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01004106 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], 1, &curproxy->except_net, &curproxy->except_mask)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004107 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
4108 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02004109 err_code |= ERR_ALERT | ERR_FATAL;
4110 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02004111 }
4112 /* flush useless bits */
4113 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02004114 cur_arg += 2;
4115 } else if (!strcmp(args[cur_arg], "header")) {
4116 /* suboption header - needs additional argument for it */
4117 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004118 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
4119 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02004120 err_code |= ERR_ALERT | ERR_FATAL;
4121 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02004122 }
4123 free(curproxy->fwdfor_hdr_name);
4124 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
4125 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
4126 cur_arg += 2;
Willy Tarreau87cf5142011-08-19 22:57:24 +02004127 } else if (!strcmp(args[cur_arg], "if-none")) {
4128 curproxy->options &= ~PR_O_FF_ALWAYS;
4129 cur_arg += 1;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02004130 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02004131 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004132 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except', 'header' and 'if-none'.\n",
4133 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004134 err_code |= ERR_ALERT | ERR_FATAL;
4135 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02004136 }
Ross Westaf72a1d2008-08-03 10:51:45 +02004137 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02004138 }
Maik Broemme2850cb42009-04-17 18:53:21 +02004139 else if (!strcmp(args[1], "originalto")) {
4140 int cur_arg;
4141
4142 /* insert x-original-to field, but not for the IP address listed as an except.
4143 * set default options (ie: bitfield, header name, etc)
4144 */
4145
4146 curproxy->options |= PR_O_ORGTO;
4147
4148 free(curproxy->orgto_hdr_name);
4149 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
4150 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
4151
Willy Tarreau87cf5142011-08-19 22:57:24 +02004152 /* loop to go through arguments - start at 2, since 0+1 = "option" "originalto" */
Maik Broemme2850cb42009-04-17 18:53:21 +02004153 cur_arg = 2;
4154 while (*(args[cur_arg])) {
4155 if (!strcmp(args[cur_arg], "except")) {
4156 /* suboption except - needs additional argument for it */
Thierry FOURNIERfc7ac7b2014-02-11 15:23:04 +01004157 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 +01004158 ha_alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
4159 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02004160 err_code |= ERR_ALERT | ERR_FATAL;
4161 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02004162 }
4163 /* flush useless bits */
4164 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
4165 cur_arg += 2;
4166 } else if (!strcmp(args[cur_arg], "header")) {
4167 /* suboption header - needs additional argument for it */
4168 if (*(args[cur_arg+1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004169 ha_alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
4170 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02004171 err_code |= ERR_ALERT | ERR_FATAL;
4172 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02004173 }
4174 free(curproxy->orgto_hdr_name);
4175 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
4176 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
4177 cur_arg += 2;
4178 } else {
4179 /* unknown suboption - catchall */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004180 ha_alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
4181 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004182 err_code |= ERR_ALERT | ERR_FATAL;
4183 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02004184 }
4185 } /* end while loop */
4186 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004187 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004188 ha_alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004189 err_code |= ERR_ALERT | ERR_FATAL;
4190 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004191 }
Willy Tarreau93893792009-07-23 13:19:11 +02004192 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004193 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004194 else if (!strcmp(args[0], "default_backend")) {
4195 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004196 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004197
4198 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004199 ha_alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004200 err_code |= ERR_ALERT | ERR_FATAL;
4201 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004202 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02004203 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004204 curproxy->defbe.name = strdup(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02004205
4206 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
4207 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004208 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004209 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01004210 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004211 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01004212
Willy Tarreaua3c504c2014-04-28 22:37:32 +02004213 if (!already_warned(WARN_REDISPATCH_DEPRECATED))
Christopher Faulet767a84b2017-11-24 16:50:31 +01004214 ha_warning("parsing [%s:%d]: keyword '%s' is deprecated in favor of 'option redispatch', and will not be supported by future versions.\n",
4215 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004216 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004217 /* enable reconnections to dispatch */
4218 curproxy->options |= PR_O_REDISP;
William Lallemanddf1425a2015-04-28 20:17:49 +02004219
4220 if (alertif_too_many_args_idx(1, 0, file, linenum, args, &err_code))
4221 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004222 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02004223 else if (!strcmp(args[0], "http-reuse")) {
4224 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4225 err_code |= ERR_WARN;
4226
4227 if (strcmp(args[1], "never") == 0) {
4228 /* enable a graceful server shutdown on an HTTP 404 response */
4229 curproxy->options &= ~PR_O_REUSE_MASK;
4230 curproxy->options |= PR_O_REUSE_NEVR;
4231 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4232 goto out;
4233 }
Willy Tarreau161d45f2015-08-05 16:02:46 +02004234 else if (strcmp(args[1], "safe") == 0) {
4235 /* enable a graceful server shutdown on an HTTP 404 response */
4236 curproxy->options &= ~PR_O_REUSE_MASK;
4237 curproxy->options |= PR_O_REUSE_SAFE;
4238 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4239 goto out;
4240 }
Willy Tarreau449d74a2015-08-05 17:16:33 +02004241 else if (strcmp(args[1], "aggressive") == 0) {
4242 curproxy->options &= ~PR_O_REUSE_MASK;
4243 curproxy->options |= PR_O_REUSE_AGGR;
4244 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4245 goto out;
4246 }
Willy Tarreaud8fecee2015-08-05 14:12:31 +02004247 else if (strcmp(args[1], "always") == 0) {
4248 /* enable a graceful server shutdown on an HTTP 404 response */
4249 curproxy->options &= ~PR_O_REUSE_MASK;
4250 curproxy->options |= PR_O_REUSE_ALWS;
4251 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4252 goto out;
4253 }
4254 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004255 ha_alert("parsing [%s:%d] : '%s' only supports 'never', 'safe', 'aggressive', 'always'.\n", file, linenum, args[0]);
Willy Tarreaud8fecee2015-08-05 14:12:31 +02004256 err_code |= ERR_ALERT | ERR_FATAL;
4257 goto out;
4258 }
4259 }
Willy Tarreau48494c02007-11-30 10:41:39 +01004260 else if (!strcmp(args[0], "http-check")) {
4261 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004262 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01004263
4264 if (strcmp(args[1], "disable-on-404") == 0) {
4265 /* enable a graceful server shutdown on an HTTP 404 response */
4266 curproxy->options |= PR_O_DISABLE404;
William Lallemanddf1425a2015-04-28 20:17:49 +02004267 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4268 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01004269 }
Willy Tarreauef781042010-01-27 11:53:01 +01004270 else if (strcmp(args[1], "send-state") == 0) {
4271 /* enable emission of the apparent state of a server in HTTP checks */
4272 curproxy->options2 |= PR_O2_CHK_SNDST;
William Lallemanddf1425a2015-04-28 20:17:49 +02004273 if (alertif_too_many_args_idx(0, 1, file, linenum, args, &err_code))
4274 goto out;
Willy Tarreauef781042010-01-27 11:53:01 +01004275 }
Willy Tarreaubd741542010-03-16 18:46:54 +01004276 else if (strcmp(args[1], "expect") == 0) {
4277 const char *ptr_arg;
4278 int cur_arg;
4279
4280 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004281 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Willy Tarreaubd741542010-03-16 18:46:54 +01004282 err_code |= ERR_ALERT | ERR_FATAL;
4283 goto out;
4284 }
4285
4286 cur_arg = 2;
4287 /* consider exclamation marks, sole or at the beginning of a word */
4288 while (*(ptr_arg = args[cur_arg])) {
4289 while (*ptr_arg == '!') {
4290 curproxy->options2 ^= PR_O2_EXP_INV;
4291 ptr_arg++;
4292 }
4293 if (*ptr_arg)
4294 break;
4295 cur_arg++;
4296 }
4297 /* now ptr_arg points to the beginning of a word past any possible
4298 * exclamation mark, and cur_arg is the argument which holds this word.
4299 */
4300 if (strcmp(ptr_arg, "status") == 0) {
4301 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004302 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
4303 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01004304 err_code |= ERR_ALERT | ERR_FATAL;
4305 goto out;
4306 }
4307 curproxy->options2 |= PR_O2_EXP_STS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02004308 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01004309 curproxy->expect_str = strdup(args[cur_arg + 1]);
4310 }
4311 else if (strcmp(ptr_arg, "string") == 0) {
4312 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004313 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
4314 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01004315 err_code |= ERR_ALERT | ERR_FATAL;
4316 goto out;
4317 }
4318 curproxy->options2 |= PR_O2_EXP_STR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02004319 free(curproxy->expect_str);
Willy Tarreaubd741542010-03-16 18:46:54 +01004320 curproxy->expect_str = strdup(args[cur_arg + 1]);
4321 }
4322 else if (strcmp(ptr_arg, "rstatus") == 0) {
4323 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004324 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
4325 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01004326 err_code |= ERR_ALERT | ERR_FATAL;
4327 goto out;
4328 }
4329 curproxy->options2 |= PR_O2_EXP_RSTS;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02004330 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02004331 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004332 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02004333 free(curproxy->expect_regex);
4334 curproxy->expect_regex = NULL;
4335 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02004336 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004337 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
4338 error = NULL;
4339 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004340 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
4341 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004342 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01004343 err_code |= ERR_ALERT | ERR_FATAL;
4344 goto out;
4345 }
4346 }
4347 else if (strcmp(ptr_arg, "rstring") == 0) {
4348 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004349 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
4350 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01004351 err_code |= ERR_ALERT | ERR_FATAL;
4352 goto out;
4353 }
4354 curproxy->options2 |= PR_O2_EXP_RSTR;
Willy Tarreau1ee51a62011-08-19 20:04:17 +02004355 free(curproxy->expect_str);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02004356 if (curproxy->expect_regex) {
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004357 regex_free(curproxy->expect_regex);
Thierry FOURNIER148f4082014-06-11 14:45:31 +02004358 free(curproxy->expect_regex);
4359 curproxy->expect_regex = NULL;
4360 }
Willy Tarreau1ee51a62011-08-19 20:04:17 +02004361 curproxy->expect_str = strdup(args[cur_arg + 1]);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004362 curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
4363 error = NULL;
4364 if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004365 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
4366 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004367 free(error);
Willy Tarreaubd741542010-03-16 18:46:54 +01004368 err_code |= ERR_ALERT | ERR_FATAL;
4369 goto out;
4370 }
4371 }
4372 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004373 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'status', 'string', 'rstatus', 'rstring', found '%s'.\n",
4374 file, linenum, args[0], args[1], ptr_arg);
Willy Tarreaubd741542010-03-16 18:46:54 +01004375 err_code |= ERR_ALERT | ERR_FATAL;
4376 goto out;
4377 }
4378 }
Willy Tarreau48494c02007-11-30 10:41:39 +01004379 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004380 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 +02004381 err_code |= ERR_ALERT | ERR_FATAL;
4382 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01004383 }
4384 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004385 else if (!strcmp(args[0], "tcp-check")) {
4386 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4387 err_code |= ERR_WARN;
4388
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004389 if (strcmp(args[1], "comment") == 0) {
4390 int cur_arg;
4391 struct tcpcheck_rule *tcpcheck;
4392
4393 cur_arg = 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004394 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004395 tcpcheck->action = TCPCHK_ACT_COMMENT;
4396
4397 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004398 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
4399 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004400 err_code |= ERR_ALERT | ERR_FATAL;
4401 goto out;
4402 }
4403
4404 tcpcheck->comment = strdup(args[cur_arg + 1]);
4405
4406 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
William Lallemanddf1425a2015-04-28 20:17:49 +02004407 if (alertif_too_many_args_idx(1, 1, file, linenum, args, &err_code))
4408 goto out;
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004409 }
4410 else if (strcmp(args[1], "connect") == 0) {
Baptiste Assmann69e273f2013-12-11 00:52:19 +01004411 const char *ptr_arg;
4412 int cur_arg;
4413 struct tcpcheck_rule *tcpcheck;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01004414
4415 /* check if first rule is also a 'connect' action */
Willy Tarreau5581c272015-05-13 12:24:53 +02004416 tcpcheck = LIST_NEXT(&curproxy->tcpcheck_rules, struct tcpcheck_rule *, list);
4417 while (&tcpcheck->list != &curproxy->tcpcheck_rules &&
4418 tcpcheck->action == TCPCHK_ACT_COMMENT) {
4419 tcpcheck = LIST_NEXT(&tcpcheck->list, struct tcpcheck_rule *, list);
4420 }
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004421
Willy Tarreau5581c272015-05-13 12:24:53 +02004422 if (&tcpcheck->list != &curproxy->tcpcheck_rules
4423 && tcpcheck->action != TCPCHK_ACT_CONNECT) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004424 ha_alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
4425 file, linenum);
Willy Tarreau5581c272015-05-13 12:24:53 +02004426 err_code |= ERR_ALERT | ERR_FATAL;
4427 goto out;
Baptiste Assmann69e273f2013-12-11 00:52:19 +01004428 }
4429
4430 cur_arg = 2;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004431 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann69e273f2013-12-11 00:52:19 +01004432 tcpcheck->action = TCPCHK_ACT_CONNECT;
4433
4434 /* parsing each parameters to fill up the rule */
4435 while (*(ptr_arg = args[cur_arg])) {
4436 /* tcp port */
4437 if (strcmp(args[cur_arg], "port") == 0) {
4438 if ( (atol(args[cur_arg + 1]) > 65535) ||
4439 (atol(args[cur_arg + 1]) < 1) ){
Christopher Faulet767a84b2017-11-24 16:50:31 +01004440 ha_alert("parsing [%s:%d] : '%s %s %s' expects a valid TCP port (from range 1 to 65535), got %s.\n",
4441 file, linenum, args[0], args[1], "port", args[cur_arg + 1]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01004442 err_code |= ERR_ALERT | ERR_FATAL;
4443 goto out;
4444 }
4445 tcpcheck->port = atol(args[cur_arg + 1]);
4446 cur_arg += 2;
4447 }
4448 /* send proxy protocol */
4449 else if (strcmp(args[cur_arg], "send-proxy") == 0) {
4450 tcpcheck->conn_opts |= TCPCHK_OPT_SEND_PROXY;
4451 cur_arg++;
4452 }
4453#ifdef USE_OPENSSL
4454 else if (strcmp(args[cur_arg], "ssl") == 0) {
4455 curproxy->options |= PR_O_TCPCHK_SSL;
4456 tcpcheck->conn_opts |= TCPCHK_OPT_SSL;
4457 cur_arg++;
4458 }
4459#endif /* USE_OPENSSL */
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004460 /* comment for this tcpcheck line */
4461 else if (strcmp(args[cur_arg], "comment") == 0) {
4462 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004463 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
4464 file, linenum, args[cur_arg]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004465 err_code |= ERR_ALERT | ERR_FATAL;
4466 goto out;
4467 }
4468 tcpcheck->comment = strdup(args[cur_arg + 1]);
4469 cur_arg += 2;
4470 }
Baptiste Assmann69e273f2013-12-11 00:52:19 +01004471 else {
4472#ifdef USE_OPENSSL
Christopher Faulet767a84b2017-11-24 16:50:31 +01004473 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 +01004474#else /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004475 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 +01004476#endif /* USE_OPENSSL */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004477 file, linenum, args[0], args[1], args[cur_arg]);
Baptiste Assmann69e273f2013-12-11 00:52:19 +01004478 err_code |= ERR_ALERT | ERR_FATAL;
4479 goto out;
4480 }
4481
4482 }
4483
4484 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
4485 }
4486 else if (strcmp(args[1], "send") == 0) {
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004487 if (! *(args[2]) ) {
4488 /* SEND string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004489 ha_alert("parsing [%s:%d] : '%s %s %s' expects <STRING> as argument.\n",
4490 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004491 err_code |= ERR_ALERT | ERR_FATAL;
4492 goto out;
4493 } else {
4494 struct tcpcheck_rule *tcpcheck;
4495
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004496 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004497
4498 tcpcheck->action = TCPCHK_ACT_SEND;
4499 tcpcheck->string_len = strlen(args[2]);
4500 tcpcheck->string = strdup(args[2]);
4501 tcpcheck->expect_regex = NULL;
4502
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004503 /* comment for this tcpcheck line */
4504 if (strcmp(args[3], "comment") == 0) {
4505 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004506 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
4507 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004508 err_code |= ERR_ALERT | ERR_FATAL;
4509 goto out;
4510 }
4511 tcpcheck->comment = strdup(args[4]);
4512 }
4513
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004514 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
4515 }
4516 }
4517 else if (strcmp(args[1], "send-binary") == 0) {
4518 if (! *(args[2]) ) {
4519 /* SEND binary string expected */
Christopher Faulet767a84b2017-11-24 16:50:31 +01004520 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument.\n",
4521 file, linenum, args[0], args[1], args[2]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004522 err_code |= ERR_ALERT | ERR_FATAL;
4523 goto out;
4524 } else {
4525 struct tcpcheck_rule *tcpcheck;
4526 char *err = NULL;
4527
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004528 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004529
4530 tcpcheck->action = TCPCHK_ACT_SEND;
4531 if (parse_binary(args[2], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004532 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
4533 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004534 err_code |= ERR_ALERT | ERR_FATAL;
4535 goto out;
4536 }
4537 tcpcheck->expect_regex = NULL;
4538
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004539 /* comment for this tcpcheck line */
4540 if (strcmp(args[3], "comment") == 0) {
4541 if (!*args[4]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004542 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
4543 file, linenum, args[3]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004544 err_code |= ERR_ALERT | ERR_FATAL;
4545 goto out;
4546 }
4547 tcpcheck->comment = strdup(args[4]);
4548 }
4549
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004550 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
4551 }
4552 }
4553 else if (strcmp(args[1], "expect") == 0) {
4554 const char *ptr_arg;
4555 int cur_arg;
4556 int inverse = 0;
4557
4558 if (curproxy->options2 & PR_O2_EXP_TYPE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004559 ha_alert("parsing [%s:%d] : '%s %s' already specified.\n", file, linenum, args[0], args[1]);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004560 err_code |= ERR_ALERT | ERR_FATAL;
4561 goto out;
4562 }
4563
4564 cur_arg = 2;
4565 /* consider exclamation marks, sole or at the beginning of a word */
4566 while (*(ptr_arg = args[cur_arg])) {
4567 while (*ptr_arg == '!') {
4568 inverse = !inverse;
4569 ptr_arg++;
4570 }
4571 if (*ptr_arg)
4572 break;
4573 cur_arg++;
4574 }
4575 /* now ptr_arg points to the beginning of a word past any possible
4576 * exclamation mark, and cur_arg is the argument which holds this word.
4577 */
4578 if (strcmp(ptr_arg, "binary") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01004579 struct tcpcheck_rule *tcpcheck;
4580 char *err = NULL;
4581
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004582 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004583 ha_alert("parsing [%s:%d] : '%s %s %s' expects <binary string> as an argument.\n",
4584 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004585 err_code |= ERR_ALERT | ERR_FATAL;
4586 goto out;
4587 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004588
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004589 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004590
4591 tcpcheck->action = TCPCHK_ACT_EXPECT;
4592 if (parse_binary(args[cur_arg + 1], &tcpcheck->string, &tcpcheck->string_len, &err) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004593 ha_alert("parsing [%s:%d] : '%s %s %s' expects <BINARY STRING> as argument, but %s\n",
4594 file, linenum, args[0], args[1], args[2], err);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004595 err_code |= ERR_ALERT | ERR_FATAL;
4596 goto out;
4597 }
4598 tcpcheck->expect_regex = NULL;
4599 tcpcheck->inverse = inverse;
4600
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004601 /* tcpcheck comment */
4602 cur_arg += 2;
4603 if (strcmp(args[cur_arg], "comment") == 0) {
4604 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004605 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
4606 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004607 err_code |= ERR_ALERT | ERR_FATAL;
4608 goto out;
4609 }
4610 tcpcheck->comment = strdup(args[cur_arg + 1]);
4611 }
4612
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004613 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
4614 }
4615 else if (strcmp(ptr_arg, "string") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01004616 struct tcpcheck_rule *tcpcheck;
4617
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004618 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004619 ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
4620 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004621 err_code |= ERR_ALERT | ERR_FATAL;
4622 goto out;
4623 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004624
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004625 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004626
4627 tcpcheck->action = TCPCHK_ACT_EXPECT;
4628 tcpcheck->string_len = strlen(args[cur_arg + 1]);
4629 tcpcheck->string = strdup(args[cur_arg + 1]);
4630 tcpcheck->expect_regex = NULL;
4631 tcpcheck->inverse = inverse;
4632
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004633 /* tcpcheck comment */
4634 cur_arg += 2;
4635 if (strcmp(args[cur_arg], "comment") == 0) {
4636 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004637 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
4638 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004639 err_code |= ERR_ALERT | ERR_FATAL;
4640 goto out;
4641 }
4642 tcpcheck->comment = strdup(args[cur_arg + 1]);
4643 }
4644
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004645 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
4646 }
4647 else if (strcmp(ptr_arg, "rstring") == 0) {
Willy Tarreaue7acee72015-02-27 16:37:05 +01004648 struct tcpcheck_rule *tcpcheck;
4649
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004650 if (!*(args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004651 ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
4652 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004653 err_code |= ERR_ALERT | ERR_FATAL;
4654 goto out;
4655 }
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004656
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02004657 tcpcheck = calloc(1, sizeof(*tcpcheck));
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004658
4659 tcpcheck->action = TCPCHK_ACT_EXPECT;
4660 tcpcheck->string_len = 0;
4661 tcpcheck->string = NULL;
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004662 tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
4663 error = NULL;
4664 if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004665 ha_alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
4666 file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
Thierry FOURNIER09af0d62014-06-18 11:35:54 +02004667 free(error);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004668 err_code |= ERR_ALERT | ERR_FATAL;
4669 goto out;
4670 }
4671 tcpcheck->inverse = inverse;
4672
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004673 /* tcpcheck comment */
4674 cur_arg += 2;
4675 if (strcmp(args[cur_arg], "comment") == 0) {
4676 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004677 ha_alert("parsing [%s:%d] : '%s' expects a comment string.\n",
4678 file, linenum, args[cur_arg + 1]);
Baptiste Assmann22b09d22015-05-01 08:03:04 +02004679 err_code |= ERR_ALERT | ERR_FATAL;
4680 goto out;
4681 }
4682 tcpcheck->comment = strdup(args[cur_arg + 1]);
4683 }
4684
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004685 LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
4686 }
4687 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004688 ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
4689 file, linenum, args[0], args[1], ptr_arg);
Baptiste Assmann5ecb77f2013-10-06 23:24:13 +02004690 err_code |= ERR_ALERT | ERR_FATAL;
4691 goto out;
4692 }
4693 }
4694 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004695 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 +02004696 err_code |= ERR_ALERT | ERR_FATAL;
4697 goto out;
4698 }
4699 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01004700 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02004701 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004702 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004703 err_code |= ERR_ALERT | ERR_FATAL;
4704 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02004705 }
4706
Willy Tarreaub80c2302007-11-30 20:51:32 +01004707 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004708 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01004709
4710 if (strcmp(args[1], "fail") == 0) {
4711 /* add a condition to fail monitor requests */
Willy Tarreauef6494c2010-01-28 17:12:36 +01004712 if (strcmp(args[2], "if") != 0 && strcmp(args[2], "unless") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004713 ha_alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
4714 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004715 err_code |= ERR_ALERT | ERR_FATAL;
4716 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01004717 }
4718
Willy Tarreau721d8e02017-12-01 18:25:08 +01004719 err_code |= warnif_misplaced_monitor(curproxy, file, linenum, "monitor fail");
Christopher Faulet1b421ea2017-09-22 14:38:56 +02004720 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args + 2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004721 ha_alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition : %s.\n",
4722 file, linenum, args[0], args[1], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02004723 err_code |= ERR_ALERT | ERR_FATAL;
4724 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01004725 }
4726 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
4727 }
4728 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004729 ha_alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004730 err_code |= ERR_ALERT | ERR_FATAL;
4731 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01004732 }
4733 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004734#ifdef TPROXY
4735 else if (!strcmp(args[0], "transparent")) {
4736 /* enable transparent proxy connections */
4737 curproxy->options |= PR_O_TRANSP;
William Lallemanddf1425a2015-04-28 20:17:49 +02004738 if (alertif_too_many_args(0, file, linenum, args, &err_code))
4739 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004740 }
4741#endif
4742 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01004743 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02004744 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01004745
Willy Tarreaubaaee002006-06-26 02:48:02 +02004746 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004747 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004748 err_code |= ERR_ALERT | ERR_FATAL;
4749 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004750 }
4751 curproxy->maxconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02004752 if (alertif_too_many_args(1, file, linenum, args, &err_code))
4753 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004754 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01004755 else if (!strcmp(args[0], "backlog")) { /* backlog */
4756 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004757 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01004758
4759 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004760 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004761 err_code |= ERR_ALERT | ERR_FATAL;
4762 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01004763 }
4764 curproxy->backlog = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02004765 if (alertif_too_many_args(1, file, linenum, args, &err_code))
4766 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01004767 }
Willy Tarreau86034312006-12-29 00:10:33 +01004768 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01004769 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02004770 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01004771
Willy Tarreau86034312006-12-29 00:10:33 +01004772 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004773 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004774 err_code |= ERR_ALERT | ERR_FATAL;
4775 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01004776 }
4777 curproxy->fullconn = atol(args[1]);
William Lallemanddf1425a2015-04-28 20:17:49 +02004778 if (alertif_too_many_args(1, file, linenum, args, &err_code))
4779 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01004780 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004781 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
4782 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004783 ha_alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004784 err_code |= ERR_ALERT | ERR_FATAL;
4785 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004786 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004787 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
4788 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004789 ha_alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
4790 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02004791 err_code |= ERR_ALERT | ERR_FATAL;
4792 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01004793 }
4794 curproxy->grace = val;
William Lallemanddf1425a2015-04-28 20:17:49 +02004795 if (alertif_too_many_args(1, file, linenum, args, &err_code))
4796 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004797 }
4798 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
David du Colombier6f5ccb12011-03-10 22:26:24 +01004799 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01004800 int port1, port2;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01004801 struct protocol *proto;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01004802
Willy Tarreaubaaee002006-06-26 02:48:02 +02004803 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004804 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02004805 err_code |= ERR_ALERT | ERR_FATAL;
4806 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004807 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01004808 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004809 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01004810
Willy Tarreau48ef4c92017-01-06 18:32:38 +01004811 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01004812 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004813 ha_alert("parsing [%s:%d] : '%s' : %s\n", file, linenum, args[0], errmsg);
Willy Tarreauf3559bf2013-03-06 16:52:04 +01004814 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreauf3559bf2013-03-06 16:52:04 +01004815 goto out;
4816 }
Willy Tarreauf3559bf2013-03-06 16:52:04 +01004817
4818 proto = protocol_by_family(sk->ss_family);
4819 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004820 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
4821 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01004822 err_code |= ERR_ALERT | ERR_FATAL;
4823 goto out;
4824 }
4825
4826 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004827 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'.\n",
4828 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02004829 err_code |= ERR_ALERT | ERR_FATAL;
4830 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004831 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01004832
4833 if (!port1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004834 ha_alert("parsing [%s:%d] : '%s' : missing port number in '%s', <addr:port> expected.\n",
4835 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01004836 err_code |= ERR_ALERT | ERR_FATAL;
4837 goto out;
4838 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01004839
William Lallemanddf1425a2015-04-28 20:17:49 +02004840 if (alertif_too_many_args(1, file, linenum, args, &err_code))
4841 goto out;
4842
Willy Tarreaud5191e72010-02-09 20:50:45 +01004843 curproxy->dispatch_addr = *sk;
Willy Tarreau1620ec32011-08-06 17:05:02 +02004844 curproxy->options |= PR_O_DISPATCH;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004845 }
4846 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01004847 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02004848 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01004849
Willy Tarreaua93c74b2012-05-08 18:14:39 +02004850 if (backend_parse_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004851 ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02004852 err_code |= ERR_ALERT | ERR_FATAL;
4853 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02004854 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004855 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02004856 else if (!strcmp(args[0], "hash-type")) { /* set hashing method */
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05004857 /**
4858 * The syntax for hash-type config element is
4859 * hash-type {map-based|consistent} [[<algo>] avalanche]
4860 *
4861 * The default hash function is sdbm for map-based and sdbm+avalanche for consistent.
4862 */
4863 curproxy->lbprm.algo &= ~(BE_LB_HASH_TYPE | BE_LB_HASH_FUNC | BE_LB_HASH_MOD);
Bhaskar98634f02013-10-29 23:30:51 -04004864
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02004865 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
4866 err_code |= ERR_WARN;
4867
4868 if (strcmp(args[1], "consistent") == 0) { /* use consistent hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02004869 curproxy->lbprm.algo |= BE_LB_HASH_CONS;
4870 }
4871 else if (strcmp(args[1], "map-based") == 0) { /* use map-based hashing */
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02004872 curproxy->lbprm.algo |= BE_LB_HASH_MAP;
4873 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05004874 else if (strcmp(args[1], "avalanche") == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004875 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 -05004876 err_code |= ERR_ALERT | ERR_FATAL;
4877 goto out;
Willy Tarreau798a39c2010-11-24 15:04:29 +01004878 }
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02004879 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004880 ha_alert("parsing [%s:%d] : '%s' only supports 'consistent' and 'map-based'.\n", file, linenum, args[0]);
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02004881 err_code |= ERR_ALERT | ERR_FATAL;
4882 goto out;
4883 }
Bhaskar98634f02013-10-29 23:30:51 -04004884
4885 /* set the hash function to use */
4886 if (!*args[2]) {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05004887 /* the default algo is sdbm */
Bhaskar98634f02013-10-29 23:30:51 -04004888 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05004889
4890 /* if consistent with no argument, then avalanche modifier is also applied */
4891 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS)
4892 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
Bhaskar98634f02013-10-29 23:30:51 -04004893 } else {
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05004894 /* set the hash function */
4895 if (!strcmp(args[2], "sdbm")) {
4896 curproxy->lbprm.algo |= BE_LB_HFCN_SDBM;
4897 }
4898 else if (!strcmp(args[2], "djb2")) {
4899 curproxy->lbprm.algo |= BE_LB_HFCN_DJB2;
Willy Tarreau324f07f2015-01-20 19:44:50 +01004900 }
4901 else if (!strcmp(args[2], "wt6")) {
Willy Tarreaua0f42712013-11-14 14:30:35 +01004902 curproxy->lbprm.algo |= BE_LB_HFCN_WT6;
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05004903 }
Willy Tarreau324f07f2015-01-20 19:44:50 +01004904 else if (!strcmp(args[2], "crc32")) {
4905 curproxy->lbprm.algo |= BE_LB_HFCN_CRC32;
4906 }
Bhaskar Maddalab6c0ac92013-11-05 11:54:02 -05004907 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004908 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 -05004909 err_code |= ERR_ALERT | ERR_FATAL;
4910 goto out;
4911 }
4912
4913 /* set the hash modifier */
4914 if (!strcmp(args[3], "avalanche")) {
4915 curproxy->lbprm.algo |= BE_LB_HMOD_AVAL;
4916 }
4917 else if (*args[3]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004918 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 -05004919 err_code |= ERR_ALERT | ERR_FATAL;
4920 goto out;
4921 }
Krzysztof Piotr Oledzkic6df0662010-01-05 16:38:49 +01004922 }
William Lallemanda73203e2012-03-12 12:48:57 +01004923 }
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04004924 else if (strcmp(args[0], "hash-balance-factor") == 0) {
4925 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004926 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Andrew Rodlandb1f48e32016-10-25 12:49:05 -04004927 err_code |= ERR_ALERT | ERR_FATAL;
4928 goto out;
4929 }
4930 curproxy->lbprm.chash.balance_factor = atol(args[1]);
4931 if (curproxy->lbprm.chash.balance_factor != 0 && curproxy->lbprm.chash.balance_factor <= 100) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004932 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 -04004933 err_code |= ERR_ALERT | ERR_FATAL;
4934 goto out;
4935 }
4936 }
William Lallemanda73203e2012-03-12 12:48:57 +01004937 else if (strcmp(args[0], "unique-id-format") == 0) {
4938 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004939 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01004940 err_code |= ERR_ALERT | ERR_FATAL;
4941 goto out;
4942 }
William Lallemand3203ff42012-11-11 17:30:56 +01004943 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004944 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 +01004945 err_code |= ERR_ALERT | ERR_FATAL;
4946 goto out;
4947 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004948 free(curproxy->conf.uniqueid_format_string);
4949 curproxy->conf.uniqueid_format_string = strdup(args[1]);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004950
Willy Tarreau62a61232013-04-12 18:13:46 +02004951 free(curproxy->conf.uif_file);
4952 curproxy->conf.uif_file = strdup(curproxy->conf.args.file);
4953 curproxy->conf.uif_line = curproxy->conf.args.line;
William Lallemand723b73a2012-02-08 16:37:49 +01004954 }
William Lallemanda73203e2012-03-12 12:48:57 +01004955
4956 else if (strcmp(args[0], "unique-id-header") == 0) {
4957 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004958 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemanda73203e2012-03-12 12:48:57 +01004959 err_code |= ERR_ALERT | ERR_FATAL;
4960 goto out;
4961 }
4962 free(curproxy->header_unique_id);
4963 curproxy->header_unique_id = strdup(args[1]);
4964 }
4965
William Lallemand723b73a2012-02-08 16:37:49 +01004966 else if (strcmp(args[0], "log-format") == 0) {
4967 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004968 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
William Lallemand723b73a2012-02-08 16:37:49 +01004969 err_code |= ERR_ALERT | ERR_FATAL;
4970 goto out;
4971 }
William Lallemand3203ff42012-11-11 17:30:56 +01004972 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01004973 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 +01004974 err_code |= ERR_ALERT | ERR_FATAL;
4975 goto out;
4976 }
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004977 if (curproxy->conf.logformat_string && curproxy == &defproxy) {
4978 char *oldlogformat = "log-format";
Willy Tarreau196729e2012-05-31 19:30:26 +02004979
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004980 if (curproxy->conf.logformat_string == default_http_log_format)
4981 oldlogformat = "option httplog";
4982 else if (curproxy->conf.logformat_string == default_tcp_log_format)
4983 oldlogformat = "option tcplog";
4984 else if (curproxy->conf.logformat_string == clf_http_log_format)
4985 oldlogformat = "option httplog clf";
Christopher Faulet767a84b2017-11-24 16:50:31 +01004986 ha_warning("parsing [%s:%d]: 'log-format' overrides previous '%s' in 'defaults' section.\n",
4987 file, linenum, oldlogformat);
Guillaume de Lafondea5b0e62017-03-31 19:54:09 +02004988 }
Willy Tarreau62a61232013-04-12 18:13:46 +02004989 if (curproxy->conf.logformat_string != default_http_log_format &&
4990 curproxy->conf.logformat_string != default_tcp_log_format &&
4991 curproxy->conf.logformat_string != clf_http_log_format)
4992 free(curproxy->conf.logformat_string);
4993 curproxy->conf.logformat_string = strdup(args[1]);
4994
4995 free(curproxy->conf.lfs_file);
4996 curproxy->conf.lfs_file = strdup(curproxy->conf.args.file);
4997 curproxy->conf.lfs_line = curproxy->conf.args.line;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02004998
4999 /* get a chance to improve log-format error reporting by
5000 * reporting the correct line-number when possible.
5001 */
5002 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005003 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format' directive is ignored in backends.\n",
5004 file, linenum, curproxy->id);
Willy Tarreaua4312fa2013-04-02 16:34:32 +02005005 err_code |= ERR_WARN;
5006 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005007 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02005008 else if (!strcmp(args[0], "log-format-sd")) {
5009 if (!*(args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005010 ha_alert("parsing [%s:%d] : %s expects an argument.\n", file, linenum, args[0]);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02005011 err_code |= ERR_ALERT | ERR_FATAL;
5012 goto out;
5013 }
5014 if (*(args[2])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005015 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 +02005016 err_code |= ERR_ALERT | ERR_FATAL;
5017 goto out;
5018 }
5019
5020 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
5021 free(curproxy->conf.logformat_sd_string);
5022 curproxy->conf.logformat_sd_string = strdup(args[1]);
5023
5024 free(curproxy->conf.lfsd_file);
5025 curproxy->conf.lfsd_file = strdup(curproxy->conf.args.file);
5026 curproxy->conf.lfsd_line = curproxy->conf.args.line;
5027
5028 /* get a chance to improve log-format-sd error reporting by
5029 * reporting the correct line-number when possible.
5030 */
5031 if (curproxy != &defproxy && !(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005032 ha_warning("parsing [%s:%d] : backend '%s' : 'log-format-sd' directive is ignored in backends.\n",
5033 file, linenum, curproxy->id);
Dragan Dosen0b85ece2015-09-25 19:17:44 +02005034 err_code |= ERR_WARN;
5035 }
5036 }
Willy Tarreau094af4e2015-01-07 15:03:42 +01005037 else if (!strcmp(args[0], "log-tag")) { /* tag to report to syslog */
5038 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005039 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 +01005040 err_code |= ERR_ALERT | ERR_FATAL;
5041 goto out;
5042 }
Dragan Dosen43885c72015-10-01 13:18:13 +02005043 chunk_destroy(&curproxy->log_tag);
5044 chunk_initstr(&curproxy->log_tag, strdup(args[1]));
Willy Tarreau094af4e2015-01-07 15:03:42 +01005045 }
Christopher Faulet4b0b79d2018-03-26 15:54:32 +02005046 else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
5047 if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
5048 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005049 err_code |= ERR_ALERT | ERR_FATAL;
5050 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005051 }
5052 }
5053 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005054 int cur_arg;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005055 int port1, port2;
David du Colombier6f5ccb12011-03-10 22:26:24 +01005056 struct sockaddr_storage *sk;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005057 struct protocol *proto;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005058
Willy Tarreau977b8e42006-12-29 14:19:17 +01005059 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005060 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005061
Willy Tarreaubaaee002006-06-26 02:48:02 +02005062 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005063 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
5064 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02005065 err_code |= ERR_ALERT | ERR_FATAL;
5066 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005067 }
Willy Tarreau368480c2009-03-01 08:27:21 +01005068
5069 /* we must first clear any optional default setting */
Willy Tarreauef9a3602012-12-08 22:29:20 +01005070 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
5071 free(curproxy->conn_src.iface_name);
5072 curproxy->conn_src.iface_name = NULL;
5073 curproxy->conn_src.iface_len = 0;
Willy Tarreau368480c2009-03-01 08:27:21 +01005074
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005075 sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005076 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005077 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
5078 file, linenum, args[0], args[1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005079 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005080 goto out;
5081 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005082
5083 proto = protocol_by_family(sk->ss_family);
5084 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005085 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5086 file, linenum, args[0], args[1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005087 err_code |= ERR_ALERT | ERR_FATAL;
5088 goto out;
5089 }
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005090
5091 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005092 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
5093 file, linenum, args[0], args[1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005094 err_code |= ERR_ALERT | ERR_FATAL;
5095 goto out;
5096 }
5097
Willy Tarreauef9a3602012-12-08 22:29:20 +01005098 curproxy->conn_src.source_addr = *sk;
5099 curproxy->conn_src.opts |= CO_SRC_BIND;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005100
5101 cur_arg = 2;
5102 while (*(args[cur_arg])) {
5103 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau29fbe512015-08-20 19:35:14 +02005104#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005105 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005106 ha_alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
5107 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02005108 err_code |= ERR_ALERT | ERR_FATAL;
5109 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005110 }
5111
5112 if (!strcmp(args[cur_arg + 1], "client")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01005113 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
5114 curproxy->conn_src.opts |= CO_SRC_TPROXY_CLI;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005115 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
Willy Tarreauef9a3602012-12-08 22:29:20 +01005116 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
5117 curproxy->conn_src.opts |= CO_SRC_TPROXY_CIP;
Willy Tarreaubce70882009-09-07 11:51:47 +02005118 } else if (!strncmp(args[cur_arg + 1], "hdr_ip(", 7)) {
5119 char *name, *end;
5120
5121 name = args[cur_arg+1] + 7;
5122 while (isspace(*name))
5123 name++;
5124
5125 end = name;
5126 while (*end && !isspace(*end) && *end != ',' && *end != ')')
5127 end++;
5128
Willy Tarreauef9a3602012-12-08 22:29:20 +01005129 curproxy->conn_src.opts &= ~CO_SRC_TPROXY_MASK;
5130 curproxy->conn_src.opts |= CO_SRC_TPROXY_DYN;
5131 curproxy->conn_src.bind_hdr_name = calloc(1, end - name + 1);
5132 curproxy->conn_src.bind_hdr_len = end - name;
5133 memcpy(curproxy->conn_src.bind_hdr_name, name, end - name);
5134 curproxy->conn_src.bind_hdr_name[end-name] = '\0';
5135 curproxy->conn_src.bind_hdr_occ = -1;
Willy Tarreaubce70882009-09-07 11:51:47 +02005136
5137 /* now look for an occurrence number */
5138 while (isspace(*end))
5139 end++;
5140 if (*end == ',') {
5141 end++;
5142 name = end;
5143 if (*end == '-')
5144 end++;
Willy Tarreau83d84cf2012-11-22 01:04:31 +01005145 while (isdigit((int)*end))
Willy Tarreaubce70882009-09-07 11:51:47 +02005146 end++;
Willy Tarreauef9a3602012-12-08 22:29:20 +01005147 curproxy->conn_src.bind_hdr_occ = strl2ic(name, end-name);
Willy Tarreaubce70882009-09-07 11:51:47 +02005148 }
5149
Willy Tarreauef9a3602012-12-08 22:29:20 +01005150 if (curproxy->conn_src.bind_hdr_occ < -MAX_HDR_HISTORY) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005151 ha_alert("parsing [%s:%d] : usesrc hdr_ip(name,num) does not support negative"
5152 " occurrences values smaller than %d.\n",
5153 file, linenum, MAX_HDR_HISTORY);
Willy Tarreaubce70882009-09-07 11:51:47 +02005154 err_code |= ERR_ALERT | ERR_FATAL;
5155 goto out;
5156 }
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005157 } else {
Willy Tarreau902636f2013-03-10 19:44:48 +01005158 struct sockaddr_storage *sk;
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005159
Willy Tarreau48ef4c92017-01-06 18:32:38 +01005160 sk = str2sa_range(args[cur_arg + 1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005161 if (!sk) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005162 ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
5163 file, linenum, args[cur_arg], args[cur_arg+1], errmsg);
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005164 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005165 goto out;
5166 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005167
5168 proto = protocol_by_family(sk->ss_family);
5169 if (!proto || !proto->connect) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005170 ha_alert("parsing [%s:%d] : '%s %s' : connect() not supported for this address family.\n",
5171 file, linenum, args[cur_arg], args[cur_arg+1]);
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005172 err_code |= ERR_ALERT | ERR_FATAL;
5173 goto out;
5174 }
Willy Tarreau2de5dae2013-03-10 18:51:54 +01005175
Willy Tarreau6d03cc32013-02-20 17:26:02 +01005176 if (port1 != port2) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005177 ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
5178 file, linenum, args[cur_arg], args[cur_arg + 1]);
Willy Tarreaud5191e72010-02-09 20:50:45 +01005179 err_code |= ERR_ALERT | ERR_FATAL;
5180 goto out;
5181 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01005182 curproxy->conn_src.tproxy_addr = *sk;
5183 curproxy->conn_src.opts |= CO_SRC_TPROXY_ADDR;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005184 }
5185 global.last_checks |= LSTCHK_NETADM;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005186#else /* no TPROXY support */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005187 ha_alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
5188 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02005189 err_code |= ERR_ALERT | ERR_FATAL;
5190 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005191#endif
5192 cur_arg += 2;
5193 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01005194 }
5195
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005196 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
5197#ifdef SO_BINDTODEVICE
5198 if (!*args[cur_arg + 1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005199 ha_alert("parsing [%s:%d] : '%s' : missing interface name.\n",
5200 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005201 err_code |= ERR_ALERT | ERR_FATAL;
5202 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005203 }
Willy Tarreauef9a3602012-12-08 22:29:20 +01005204 free(curproxy->conn_src.iface_name);
5205 curproxy->conn_src.iface_name = strdup(args[cur_arg + 1]);
5206 curproxy->conn_src.iface_len = strlen(curproxy->conn_src.iface_name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005207 global.last_checks |= LSTCHK_NETADM;
5208#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01005209 ha_alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
5210 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02005211 err_code |= ERR_ALERT | ERR_FATAL;
5212 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01005213#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01005214 cur_arg += 2;
5215 continue;
5216 }
Christopher Faulet767a84b2017-11-24 16:50:31 +01005217 ha_alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
5218 file, linenum, args[0], "interface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02005219 err_code |= ERR_ALERT | ERR_FATAL;
5220 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01005221 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005222 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01005223 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
Christopher Faulet767a84b2017-11-24 16:50:31 +01005224 ha_alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
5225 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02005226 err_code |= ERR_ALERT | ERR_FATAL;
5227 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01005228 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005229 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005230 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005231 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
5232 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005233 err_code |= ERR_ALERT | ERR_FATAL;
5234 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005235 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01005236
5237 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005238 SMP_OPT_DIR_REQ, ACT_REPLACE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01005239 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005240 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005241 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005242 }
5243 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005244 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005245 SMP_OPT_DIR_REQ, ACT_REMOVE, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01005246 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005247 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005248 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005249 }
5250 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005251 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005252 SMP_OPT_DIR_REQ, ACT_DENY, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01005253 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005254 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005255 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005256 }
5257 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005258 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005259 SMP_OPT_DIR_REQ, ACT_PASS, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01005260 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005261 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005262 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005263 }
5264 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005265 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005266 SMP_OPT_DIR_REQ, ACT_ALLOW, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01005267 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005268 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005269 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005270 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02005271 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005272 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005273 SMP_OPT_DIR_REQ, ACT_TARPIT, 0,
Willy Tarreau5321c422010-01-28 20:35:13 +01005274 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005275 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005276 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02005277 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005278 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005279 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005280 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
5281 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005282 err_code |= ERR_ALERT | ERR_FATAL;
5283 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005284 }
Willy Tarreauade5ec42010-01-28 19:33:49 +01005285
5286 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005287 SMP_OPT_DIR_REQ, ACT_REPLACE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01005288 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005289 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005290 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005291 }
5292 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005293 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005294 SMP_OPT_DIR_REQ, ACT_REMOVE, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01005295 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005296 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005297 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005298 }
5299 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005300 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005301 SMP_OPT_DIR_REQ, ACT_DENY, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01005302 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005303 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005304 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005305 }
5306 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005307 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005308 SMP_OPT_DIR_REQ, ACT_PASS, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01005309 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005310 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005311 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005312 }
5313 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005314 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005315 SMP_OPT_DIR_REQ, ACT_ALLOW, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01005316 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005317 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005318 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005319 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02005320 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005321 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005322 SMP_OPT_DIR_REQ, ACT_TARPIT, REG_ICASE,
Willy Tarreau5321c422010-01-28 20:35:13 +01005323 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005324 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005325 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02005326 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005327 else if (!strcmp(args[0], "reqadd")) { /* add request header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01005328 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01005329
Willy Tarreaubaaee002006-06-26 02:48:02 +02005330 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005331 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005332 err_code |= ERR_ALERT | ERR_FATAL;
5333 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005334 }
Christopher Faulet898566e2016-10-26 11:06:28 +02005335 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005336 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005337
Willy Tarreaubaaee002006-06-26 02:48:02 +02005338 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005339 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005340 err_code |= ERR_ALERT | ERR_FATAL;
5341 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005342 }
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01005343
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01005344 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005345 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005346 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
5347 file, linenum, args[0], errmsg);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01005348 err_code |= ERR_ALERT | ERR_FATAL;
5349 goto out;
5350 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01005351 err_code |= warnif_cond_conflicts(cond,
5352 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR,
5353 file, linenum);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01005354 }
5355 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005356 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
5357 file, linenum, args[0], args[2]);
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01005358 err_code |= ERR_ALERT | ERR_FATAL;
5359 goto out;
5360 }
5361
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01005362 wl = calloc(1, sizeof(*wl));
Willy Tarreau8abd4cd2010-01-31 14:30:44 +01005363 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01005364 wl->s = strdup(args[1]);
5365 LIST_ADDQ(&curproxy->req_add, &wl->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02005366 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02005367 }
5368 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005369 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005370 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
5371 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005372 err_code |= ERR_ALERT | ERR_FATAL;
5373 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005374 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01005375
Willy Tarreauade5ec42010-01-28 19:33:49 +01005376 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005377 SMP_OPT_DIR_RES, ACT_REPLACE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005378 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005379 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005380 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005381 }
5382 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005383 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005384 SMP_OPT_DIR_RES, ACT_REMOVE, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005385 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005386 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005387 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005388 }
5389 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005390 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005391 SMP_OPT_DIR_RES, ACT_DENY, 0,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005392 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005393 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005394 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005395 }
5396 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005397 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005398 ha_alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
5399 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005400 err_code |= ERR_ALERT | ERR_FATAL;
5401 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005402 }
5403
Willy Tarreauade5ec42010-01-28 19:33:49 +01005404 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005405 SMP_OPT_DIR_RES, ACT_REPLACE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005406 args[0], args[1], args[2], (const char **)args+3);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005407 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005408 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005409 }
5410 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005411 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005412 SMP_OPT_DIR_RES, ACT_REMOVE, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005413 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005414 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005415 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005416 }
5417 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
Willy Tarreauade5ec42010-01-28 19:33:49 +01005418 err_code |= create_cond_regex_rule(file, linenum, curproxy,
Willy Tarreau32a6f2e2012-04-25 10:13:36 +02005419 SMP_OPT_DIR_RES, ACT_DENY, REG_ICASE,
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005420 args[0], args[1], NULL, (const char **)args+2);
Willy Tarreauade5ec42010-01-28 19:33:49 +01005421 if (err_code & ERR_FATAL)
Willy Tarreau93893792009-07-23 13:19:11 +02005422 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005423 }
5424 else if (!strcmp(args[0], "rspadd")) { /* add response header */
Willy Tarreauf4f04122010-01-28 18:10:50 +01005425 struct cond_wordlist *wl;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01005426
Willy Tarreaubaaee002006-06-26 02:48:02 +02005427 if (curproxy == &defproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005428 ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005429 err_code |= ERR_ALERT | ERR_FATAL;
5430 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005431 }
Christopher Faulet898566e2016-10-26 11:06:28 +02005432 else if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005433 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005434
Willy Tarreaubaaee002006-06-26 02:48:02 +02005435 if (*(args[1]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005436 ha_alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005437 err_code |= ERR_ALERT | ERR_FATAL;
5438 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005439 }
5440
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005441 if ((strcmp(args[2], "if") == 0 || strcmp(args[2], "unless") == 0)) {
Christopher Faulet1b421ea2017-09-22 14:38:56 +02005442 if ((cond = build_acl_cond(file, linenum, &curproxy->acl, curproxy, (const char **)args+2, &errmsg)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005443 ha_alert("parsing [%s:%d] : error detected while parsing a '%s' condition : %s.\n",
5444 file, linenum, args[0], errmsg);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005445 err_code |= ERR_ALERT | ERR_FATAL;
5446 goto out;
5447 }
Willy Tarreaua91d0a52013-03-25 08:12:18 +01005448 err_code |= warnif_cond_conflicts(cond,
5449 (curproxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR,
5450 file, linenum);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005451 }
5452 else if (*args[2]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005453 ha_alert("parsing [%s:%d] : '%s' : Expecting nothing, 'if', or 'unless', got '%s'.\n",
5454 file, linenum, args[0], args[2]);
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005455 err_code |= ERR_ALERT | ERR_FATAL;
5456 goto out;
5457 }
5458
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01005459 wl = calloc(1, sizeof(*wl));
Willy Tarreaufdb563c2010-01-31 15:43:27 +01005460 wl->cond = cond;
Willy Tarreaudeb9ed82010-01-03 21:03:22 +01005461 wl->s = strdup(args[1]);
5462 LIST_ADDQ(&curproxy->rsp_add, &wl->list);
Willy Tarreaubaaee002006-06-26 02:48:02 +02005463 }
5464 else if (!strcmp(args[0], "errorloc") ||
5465 !strcmp(args[0], "errorloc302") ||
5466 !strcmp(args[0], "errorloc303")) { /* error location */
5467 int errnum, errlen;
5468 char *err;
5469
Willy Tarreau977b8e42006-12-29 14:19:17 +01005470 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005471 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01005472
Willy Tarreaubaaee002006-06-26 02:48:02 +02005473 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005474 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 +02005475 err_code |= ERR_ALERT | ERR_FATAL;
5476 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005477 }
5478
5479 errnum = atol(args[1]);
5480 if (!strcmp(args[0], "errorloc303")) {
Willy Tarreau348acfe2014-04-14 15:00:39 +02005481 errlen = strlen(HTTP_303) + strlen(args[2]) + 5;
5482 err = malloc(errlen);
5483 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_303, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02005484 } else {
Willy Tarreau348acfe2014-04-14 15:00:39 +02005485 errlen = strlen(HTTP_302) + strlen(args[2]) + 5;
5486 err = malloc(errlen);
5487 errlen = snprintf(err, errlen, "%s%s\r\n\r\n", HTTP_302, args[2]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02005488 }
5489
Willy Tarreau0f772532006-12-23 20:51:41 +01005490 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
5491 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02005492 chunk_destroy(&curproxy->errmsg[rc]);
5493 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01005494 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005495 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005496 }
Willy Tarreau0f772532006-12-23 20:51:41 +01005497
5498 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005499 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error relocation will be ignored.\n",
5500 file, linenum, errnum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02005501 free(err);
5502 }
5503 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02005504 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
5505 int errnum, errlen, fd;
5506 char *err;
5507 struct stat stat;
5508
5509 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02005510 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02005511
5512 if (*(args[2]) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005513 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 +02005514 err_code |= ERR_ALERT | ERR_FATAL;
5515 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02005516 }
5517
5518 fd = open(args[2], O_RDONLY);
5519 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005520 ha_alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
5521 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02005522 if (fd >= 0)
5523 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02005524 err_code |= ERR_ALERT | ERR_FATAL;
5525 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02005526 }
5527
Willy Tarreau27a674e2009-08-17 07:23:33 +02005528 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02005529 errlen = stat.st_size;
5530 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005531 ha_warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
5532 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02005533 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02005534 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02005535 }
5536
5537 err = malloc(errlen); /* malloc() must succeed during parsing */
5538 errnum = read(fd, err, errlen);
5539 if (errnum != errlen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005540 ha_alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
5541 file, linenum, args[2], args[1]);
Willy Tarreau3f49b302007-06-11 00:29:26 +02005542 close(fd);
5543 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02005544 err_code |= ERR_ALERT | ERR_FATAL;
5545 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02005546 }
5547 close(fd);
5548
5549 errnum = atol(args[1]);
5550 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
5551 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02005552 chunk_destroy(&curproxy->errmsg[rc]);
5553 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02005554 break;
5555 }
5556 }
5557
5558 if (rc >= HTTP_ERR_SIZE) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005559 ha_warning("parsing [%s:%d] : status code %d not handled by '%s', error customization will be ignored.\n",
5560 file, linenum, errnum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02005561 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02005562 free(err);
5563 }
5564 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005565 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02005566 struct cfg_kw_list *kwl;
5567 int index;
5568
5569 list_for_each_entry(kwl, &cfg_keywords.list, list) {
5570 for (index = 0; kwl->kw[index].kw != NULL; index++) {
5571 if (kwl->kw[index].section != CFG_LISTEN)
5572 continue;
5573 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
5574 /* prepare error message just in case */
Willy Tarreau28a47d62012-09-18 20:02:48 +02005575 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
Willy Tarreau39f23b62008-07-09 20:22:56 +02005576 if (rc < 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005577 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005578 err_code |= ERR_ALERT | ERR_FATAL;
5579 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02005580 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02005581 else if (rc > 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005582 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005583 err_code |= ERR_WARN;
5584 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02005585 }
Willy Tarreau93893792009-07-23 13:19:11 +02005586 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02005587 }
5588 }
5589 }
William Lallemand82fe75c2012-10-23 10:25:10 +02005590
Christopher Faulet767a84b2017-11-24 16:50:31 +01005591 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02005592 err_code |= ERR_ALERT | ERR_FATAL;
5593 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005594 }
Willy Tarreau93893792009-07-23 13:19:11 +02005595 out:
Willy Tarreauf4068b62012-05-08 17:37:49 +02005596 free(errmsg);
Willy Tarreau93893792009-07-23 13:19:11 +02005597 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005598}
5599
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005600int
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01005601cfg_parse_netns(const char *file, int linenum, char **args, int kwm)
5602{
5603#ifdef CONFIG_HAP_NS
5604 const char *err;
5605 const char *item = args[0];
5606
5607 if (!strcmp(item, "namespace_list")) {
5608 return 0;
5609 }
5610 else if (!strcmp(item, "namespace")) {
5611 size_t idx = 1;
5612 const char *current;
5613 while (*(current = args[idx++])) {
5614 err = invalid_char(current);
5615 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005616 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
5617 file, linenum, *err, item, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01005618 return ERR_ALERT | ERR_FATAL;
5619 }
5620
5621 if (netns_store_lookup(current, strlen(current))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005622 ha_alert("parsing [%s:%d]: Namespace '%s' is already added.\n",
5623 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01005624 return ERR_ALERT | ERR_FATAL;
5625 }
5626 if (!netns_store_insert(current)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005627 ha_alert("parsing [%s:%d]: Cannot open namespace '%s'.\n",
5628 file, linenum, current);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01005629 return ERR_ALERT | ERR_FATAL;
5630 }
5631 }
5632 }
5633
5634 return 0;
5635#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01005636 ha_alert("parsing [%s:%d]: namespace support is not compiled in.",
5637 file, linenum);
KOVACS Krisztianb3e54fe2014-11-17 15:11:45 +01005638 return ERR_ALERT | ERR_FATAL;
5639#endif
5640}
5641
5642int
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005643cfg_parse_users(const char *file, int linenum, char **args, int kwm)
5644{
5645
5646 int err_code = 0;
5647 const char *err;
5648
5649 if (!strcmp(args[0], "userlist")) { /* new userlist */
5650 struct userlist *newul;
5651
5652 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005653 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
5654 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005655 err_code |= ERR_ALERT | ERR_FATAL;
5656 goto out;
5657 }
William Lallemand6e62fb62015-04-28 16:55:23 +02005658 if (alertif_too_many_args(1, file, linenum, args, &err_code))
5659 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005660
5661 err = invalid_char(args[1]);
5662 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005663 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
5664 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005665 err_code |= ERR_ALERT | ERR_FATAL;
5666 goto out;
5667 }
5668
5669 for (newul = userlist; newul; newul = newul->next)
5670 if (!strcmp(newul->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005671 ha_warning("parsing [%s:%d]: ignoring duplicated userlist '%s'.\n",
5672 file, linenum, args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005673 err_code |= ERR_WARN;
5674 goto out;
5675 }
5676
Vincent Bernat02779b62016-04-03 13:48:43 +02005677 newul = calloc(1, sizeof(*newul));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005678 if (!newul) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005679 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005680 err_code |= ERR_ALERT | ERR_ABORT;
5681 goto out;
5682 }
5683
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005684 newul->name = strdup(args[1]);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005685 if (!newul->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005686 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005687 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier97880bb2016-04-08 10:35:26 +01005688 free(newul);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005689 goto out;
5690 }
5691
5692 newul->next = userlist;
5693 userlist = newul;
5694
5695 } else if (!strcmp(args[0], "group")) { /* new group */
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005696 int cur_arg;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005697 const char *err;
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005698 struct auth_groups *ag;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005699
5700 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005701 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
5702 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005703 err_code |= ERR_ALERT | ERR_FATAL;
5704 goto out;
5705 }
5706
5707 err = invalid_char(args[1]);
5708 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005709 ha_alert("parsing [%s:%d]: character '%c' is not permitted in '%s' name '%s'.\n",
5710 file, linenum, *err, args[0], args[1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005711 err_code |= ERR_ALERT | ERR_FATAL;
5712 goto out;
5713 }
5714
William Lallemand4ac9f542015-05-28 18:03:51 +02005715 if (!userlist)
5716 goto out;
5717
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005718 for (ag = userlist->groups; ag; ag = ag->next)
5719 if (!strcmp(ag->name, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005720 ha_warning("parsing [%s:%d]: ignoring duplicated group '%s' in userlist '%s'.\n",
5721 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005722 err_code |= ERR_ALERT;
5723 goto out;
5724 }
5725
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005726 ag = calloc(1, sizeof(*ag));
5727 if (!ag) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005728 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005729 err_code |= ERR_ALERT | ERR_ABORT;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005730 goto out;
5731 }
5732
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005733 ag->name = strdup(args[1]);
David Carlier70d60452016-08-22 23:27:42 +01005734 if (!ag->name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005735 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005736 err_code |= ERR_ALERT | ERR_ABORT;
David Carlier70d60452016-08-22 23:27:42 +01005737 free(ag);
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005738 goto out;
5739 }
5740
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005741 cur_arg = 2;
5742
5743 while (*args[cur_arg]) {
5744 if (!strcmp(args[cur_arg], "users")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005745 ag->groupusers = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005746 cur_arg += 2;
5747 continue;
5748 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005749 ha_alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
5750 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005751 err_code |= ERR_ALERT | ERR_FATAL;
David Carlier70d60452016-08-22 23:27:42 +01005752 free(ag->groupusers);
5753 free(ag->name);
5754 free(ag);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005755 goto out;
5756 }
5757 }
5758
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005759 ag->next = userlist->groups;
5760 userlist->groups = ag;
5761
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005762 } else if (!strcmp(args[0], "user")) { /* new user */
5763 struct auth_users *newuser;
5764 int cur_arg;
5765
5766 if (!*args[1]) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005767 ha_alert("parsing [%s:%d]: '%s' expects <name> as arguments.\n",
5768 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005769 err_code |= ERR_ALERT | ERR_FATAL;
5770 goto out;
5771 }
William Lallemand4ac9f542015-05-28 18:03:51 +02005772 if (!userlist)
5773 goto out;
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005774
5775 for (newuser = userlist->users; newuser; newuser = newuser->next)
5776 if (!strcmp(newuser->user, args[1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005777 ha_warning("parsing [%s:%d]: ignoring duplicated user '%s' in userlist '%s'.\n",
5778 file, linenum, args[1], userlist->name);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005779 err_code |= ERR_ALERT;
5780 goto out;
5781 }
5782
Vincent Bernat02779b62016-04-03 13:48:43 +02005783 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005784 if (!newuser) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005785 ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005786 err_code |= ERR_ALERT | ERR_ABORT;
5787 goto out;
5788 }
5789
5790 newuser->user = strdup(args[1]);
5791
5792 newuser->next = userlist->users;
5793 userlist->users = newuser;
5794
5795 cur_arg = 2;
5796
5797 while (*args[cur_arg]) {
5798 if (!strcmp(args[cur_arg], "password")) {
Cyril Bonté1a0191d2014-08-29 20:20:02 +02005799#ifdef CONFIG_HAP_CRYPT
5800 if (!crypt("", args[cur_arg + 1])) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005801 ha_alert("parsing [%s:%d]: the encrypted password used for user '%s' is not supported by crypt(3).\n",
5802 file, linenum, newuser->user);
Cyril Bonté1a0191d2014-08-29 20:20:02 +02005803 err_code |= ERR_ALERT | ERR_FATAL;
5804 goto out;
5805 }
5806#else
Christopher Faulet767a84b2017-11-24 16:50:31 +01005807 ha_warning("parsing [%s:%d]: no crypt(3) support compiled, encrypted passwords will not work.\n",
5808 file, linenum);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005809 err_code |= ERR_ALERT;
5810#endif
5811 newuser->pass = strdup(args[cur_arg + 1]);
5812 cur_arg += 2;
5813 continue;
5814 } else if (!strcmp(args[cur_arg], "insecure-password")) {
5815 newuser->pass = strdup(args[cur_arg + 1]);
5816 newuser->flags |= AU_O_INSECURE;
5817 cur_arg += 2;
5818 continue;
5819 } else if (!strcmp(args[cur_arg], "groups")) {
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01005820 newuser->u.groups_names = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005821 cur_arg += 2;
5822 continue;
5823 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005824 ha_alert("parsing [%s:%d]: '%s' only supports 'password', 'insecure-password' and 'groups' options.\n",
5825 file, linenum, args[0]);
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01005826 err_code |= ERR_ALERT | ERR_FATAL;
5827 goto out;
5828 }
5829 }
5830 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005831 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 +01005832 err_code |= ERR_ALERT | ERR_FATAL;
5833 }
5834
5835out:
5836 return err_code;
5837}
Willy Tarreaubaaee002006-06-26 02:48:02 +02005838
Christopher Faulet79bdef32016-11-04 22:36:15 +01005839int
5840cfg_parse_scope(const char *file, int linenum, char *line)
5841{
5842 char *beg, *end, *scope = NULL;
5843 int err_code = 0;
5844 const char *err;
5845
5846 beg = line + 1;
5847 end = strchr(beg, ']');
5848
5849 /* Detect end of scope declaration */
5850 if (!end || end == beg) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005851 ha_alert("parsing [%s:%d] : empty scope name is forbidden.\n",
5852 file, linenum);
Christopher Faulet79bdef32016-11-04 22:36:15 +01005853 err_code |= ERR_ALERT | ERR_FATAL;
5854 goto out;
5855 }
5856
5857 /* Get scope name and check its validity */
5858 scope = my_strndup(beg, end-beg);
5859 err = invalid_char(scope);
5860 if (err) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005861 ha_alert("parsing [%s:%d] : character '%c' is not permitted in a scope name.\n",
5862 file, linenum, *err);
Christopher Faulet79bdef32016-11-04 22:36:15 +01005863 err_code |= ERR_ALERT | ERR_ABORT;
5864 goto out;
5865 }
5866
5867 /* Be sure to have a scope declaration alone on its line */
5868 line = end+1;
5869 while (isspace((unsigned char)*line))
5870 line++;
5871 if (*line && *line != '#' && *line != '\n' && *line != '\r') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005872 ha_alert("parsing [%s:%d] : character '%c' is not permitted after scope declaration.\n",
5873 file, linenum, *line);
Christopher Faulet79bdef32016-11-04 22:36:15 +01005874 err_code |= ERR_ALERT | ERR_ABORT;
5875 goto out;
5876 }
5877
5878 /* We have a valid scope declaration, save it */
5879 free(cfg_scope);
5880 cfg_scope = scope;
5881 scope = NULL;
5882
5883 out:
5884 free(scope);
5885 return err_code;
5886}
5887
Frédéric Lécaillea41d5312018-01-29 12:05:07 +01005888int
5889cfg_parse_track_sc_num(unsigned int *track_sc_num,
5890 const char *arg, const char *end, char **errmsg)
5891{
5892 const char *p;
5893 unsigned int num;
5894
5895 p = arg;
5896 num = read_uint64(&arg, end);
5897
5898 if (arg != end) {
5899 memprintf(errmsg, "Wrong track-sc number '%s'", p);
5900 return -1;
5901 }
5902
5903 if (num >= MAX_SESS_STKCTR) {
5904 memprintf(errmsg, "%u track-sc number exceeding "
5905 "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1);
5906 return -1;
5907 }
5908
5909 *track_sc_num = num;
5910 return 0;
5911}
5912
Willy Tarreaubaaee002006-06-26 02:48:02 +02005913/*
5914 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02005915 * Returns the error code, 0 if OK, or any combination of :
5916 * - ERR_ABORT: must abort ASAP
5917 * - ERR_FATAL: we can continue parsing but not start the service
5918 * - ERR_WARN: a warning has been emitted
5919 * - ERR_ALERT: an alert has been emitted
5920 * Only the two first ones can stop processing, the two others are just
5921 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02005922 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02005923int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02005924{
William Lallemand64e84512015-05-12 14:25:37 +02005925 char *thisline;
5926 int linesize = LINESIZE;
Willy Tarreaubaaee002006-06-26 02:48:02 +02005927 FILE *f;
5928 int linenum = 0;
Willy Tarreau058e9072009-07-20 09:30:05 +02005929 int err_code = 0;
William Lallemandd2ff56d2017-10-16 11:06:50 +02005930 struct cfg_section *cs = NULL, *pcs = NULL;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01005931 struct cfg_section *ics;
William Lallemand64e84512015-05-12 14:25:37 +02005932 int readbytes = 0;
5933
5934 if ((thisline = malloc(sizeof(*thisline) * linesize)) == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005935 ha_alert("parsing [%s] : out of memory.\n", file);
William Lallemand64e84512015-05-12 14:25:37 +02005936 return -1;
5937 }
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01005938
David Carlier97880bb2016-04-08 10:35:26 +01005939 if ((f=fopen(file,"r")) == NULL) {
5940 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02005941 return -1;
David Carlier97880bb2016-04-08 10:35:26 +01005942 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02005943
William Lallemandb2f07452015-05-12 14:27:13 +02005944next_line:
William Lallemand64e84512015-05-12 14:25:37 +02005945 while (fgets(thisline + readbytes, linesize - readbytes, f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02005946 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01005947 char *end;
5948 char *args[MAX_LINE_ARGS + 1];
5949 char *line = thisline;
William Lallemandf9873ba2015-05-05 17:37:14 +02005950 int dquote = 0; /* double quote */
5951 int squote = 0; /* simple quote */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01005952
Willy Tarreaubaaee002006-06-26 02:48:02 +02005953 linenum++;
5954
5955 end = line + strlen(line);
5956
William Lallemand64e84512015-05-12 14:25:37 +02005957 if (end-line == linesize-1 && *(end-1) != '\n') {
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01005958 /* Check if we reached the limit and the last char is not \n.
5959 * Watch out for the last line without the terminating '\n'!
5960 */
William Lallemand64e84512015-05-12 14:25:37 +02005961 char *newline;
5962 int newlinesize = linesize * 2;
5963
5964 newline = realloc(thisline, sizeof(*thisline) * newlinesize);
5965 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01005966 ha_alert("parsing [%s:%d]: line too long, cannot allocate memory.\n",
5967 file, linenum);
William Lallemand64e84512015-05-12 14:25:37 +02005968 err_code |= ERR_ALERT | ERR_FATAL;
5969 continue;
5970 }
5971
5972 readbytes = linesize - 1;
5973 linesize = newlinesize;
5974 thisline = newline;
5975 continue;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01005976 }
5977
William Lallemand64e84512015-05-12 14:25:37 +02005978 readbytes = 0;
5979
Willy Tarreaubaaee002006-06-26 02:48:02 +02005980 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02005981 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02005982 line++;
William Lallemandf9873ba2015-05-05 17:37:14 +02005983
Christopher Faulet79bdef32016-11-04 22:36:15 +01005984
Joseph Herlanta14c03e2018-11-15 14:04:19 -08005985 if (*line == '[') {/* This is the beginning if a scope */
Christopher Faulet79bdef32016-11-04 22:36:15 +01005986 err_code |= cfg_parse_scope(file, linenum, line);
5987 goto next_line;
5988 }
5989
Willy Tarreaubaaee002006-06-26 02:48:02 +02005990 arg = 0;
5991 args[arg] = line;
5992
5993 while (*line && arg < MAX_LINE_ARGS) {
William Lallemandf9873ba2015-05-05 17:37:14 +02005994 if (*line == '"' && !squote) { /* double quote outside single quotes */
5995 if (dquote)
5996 dquote = 0;
5997 else
5998 dquote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02005999 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02006000 end--;
6001 }
6002 else if (*line == '\'' && !dquote) { /* single quote outside double quotes */
6003 if (squote)
6004 squote = 0;
6005 else
6006 squote = 1;
William Lallemand3f415602015-05-12 14:01:09 +02006007 memmove(line, line + 1, end - line);
William Lallemandf9873ba2015-05-05 17:37:14 +02006008 end--;
6009 }
6010 else if (*line == '\\' && !squote) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02006011 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
6012 * C equivalent value. Other combinations left unchanged (eg: \1).
6013 */
Willy Tarreaubaaee002006-06-26 02:48:02 +02006014 int skip = 0;
6015 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
6016 *line = line[1];
6017 skip = 1;
6018 }
6019 else if (line[1] == 'r') {
6020 *line = '\r';
6021 skip = 1;
William Lallemandf9873ba2015-05-05 17:37:14 +02006022 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006023 else if (line[1] == 'n') {
6024 *line = '\n';
6025 skip = 1;
6026 }
6027 else if (line[1] == 't') {
6028 *line = '\t';
6029 skip = 1;
6030 }
6031 else if (line[1] == 'x') {
Emeric Brunb982a3d2010-01-04 15:45:53 +01006032 if ((line + 3 < end) && ishex(line[2]) && ishex(line[3])) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02006033 unsigned char hex1, hex2;
6034 hex1 = toupper(line[2]) - '0';
6035 hex2 = toupper(line[3]) - '0';
6036 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
6037 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
6038 *line = (hex1<<4) + hex2;
6039 skip = 3;
6040 }
6041 else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006042 ha_alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02006043 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006044 }
William Lallemandf9873ba2015-05-05 17:37:14 +02006045 } else if (line[1] == '"') {
6046 *line = '"';
6047 skip = 1;
6048 } else if (line[1] == '\'') {
6049 *line = '\'';
6050 skip = 1;
William Lallemandb2f07452015-05-12 14:27:13 +02006051 } else if (line[1] == '$' && dquote) { /* escaping of $ only inside double quotes */
6052 *line = '$';
6053 skip = 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006054 }
6055 if (skip) {
Cyril Bontédd1b01d2009-12-06 13:43:42 +01006056 memmove(line + 1, line + 1 + skip, end - (line + skip));
Willy Tarreaubaaee002006-06-26 02:48:02 +02006057 end -= skip;
6058 }
6059 line++;
6060 }
William Lallemandf9873ba2015-05-05 17:37:14 +02006061 else if ((!squote && !dquote && *line == '#') || *line == '\n' || *line == '\r') {
Willy Tarreaubaaee002006-06-26 02:48:02 +02006062 /* end of string, end of loop */
6063 *line = 0;
6064 break;
6065 }
William Lallemandf9873ba2015-05-05 17:37:14 +02006066 else if (!squote && !dquote && isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02006067 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01006068 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02006069 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02006070 line++;
6071 args[++arg] = line;
6072 }
William Lallemandb2f07452015-05-12 14:27:13 +02006073 else if (dquote && *line == '$') {
6074 /* environment variables are evaluated inside double quotes */
6075 char *var_beg;
6076 char *var_end;
6077 char save_char;
6078 char *value;
6079 int val_len;
6080 int newlinesize;
6081 int braces = 0;
6082
6083 var_beg = line + 1;
6084 var_end = var_beg;
6085
6086 if (*var_beg == '{') {
6087 var_beg++;
6088 var_end++;
6089 braces = 1;
6090 }
6091
6092 if (!isalpha((int)(unsigned char)*var_beg) && *var_beg != '_') {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006093 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 +02006094 err_code |= ERR_ALERT | ERR_FATAL;
6095 goto next_line; /* skip current line */
6096 }
6097
6098 while (isalnum((int)(unsigned char)*var_end) || *var_end == '_')
6099 var_end++;
6100
6101 save_char = *var_end;
6102 *var_end = '\0';
6103 value = getenv(var_beg);
6104 *var_end = save_char;
6105 val_len = value ? strlen(value) : 0;
6106
6107 if (braces) {
6108 if (*var_end == '}') {
6109 var_end++;
6110 braces = 0;
6111 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006112 ha_alert("parsing [%s:%d] : Variable expansion: Mismatched braces.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02006113 err_code |= ERR_ALERT | ERR_FATAL;
6114 goto next_line; /* skip current line */
6115 }
6116 }
6117
6118 newlinesize = (end - thisline) - (var_end - line) + val_len + 1;
6119
6120 /* if not enough space in thisline */
6121 if (newlinesize > linesize) {
6122 char *newline;
6123
6124 newline = realloc(thisline, newlinesize * sizeof(*thisline));
6125 if (newline == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006126 ha_alert("parsing [%s:%d] : Variable expansion: Not enough memory.\n", file, linenum);
William Lallemandb2f07452015-05-12 14:27:13 +02006127 err_code |= ERR_ALERT | ERR_FATAL;
6128 goto next_line; /* slip current line */
6129 }
6130 /* recompute pointers if realloc returns a new pointer */
6131 if (newline != thisline) {
6132 int i;
6133 int diff;
6134
6135 for (i = 0; i <= arg; i++) {
6136 diff = args[i] - thisline;
6137 args[i] = newline + diff;
6138 }
6139
6140 diff = var_end - thisline;
6141 var_end = newline + diff;
6142 diff = end - thisline;
6143 end = newline + diff;
6144 diff = line - thisline;
6145 line = newline + diff;
6146 thisline = newline;
6147 }
6148 linesize = newlinesize;
6149 }
6150
6151 /* insert value inside the line */
6152 memmove(line + val_len, var_end, end - var_end + 1);
6153 memcpy(line, value, val_len);
6154 end += val_len - (var_end - line);
6155 line += val_len;
6156 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006157 else {
6158 line++;
6159 }
6160 }
William Lallemandb2f07452015-05-12 14:27:13 +02006161
William Lallemandf9873ba2015-05-05 17:37:14 +02006162 if (dquote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006163 ha_alert("parsing [%s:%d] : Mismatched double quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02006164 err_code |= ERR_ALERT | ERR_FATAL;
6165 }
6166
6167 if (squote) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006168 ha_alert("parsing [%s:%d] : Mismatched simple quotes.\n", file, linenum);
William Lallemandf9873ba2015-05-05 17:37:14 +02006169 err_code |= ERR_ALERT | ERR_FATAL;
6170 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006171
6172 /* empty line */
6173 if (!**args)
6174 continue;
6175
Willy Tarreau7bb651e2009-11-09 21:16:53 +01006176 if (*line) {
6177 /* we had to stop due to too many args.
6178 * Let's terminate the string, print the offending part then cut the
6179 * last arg.
6180 */
6181 while (*line && *line != '#' && *line != '\n' && *line != '\r')
6182 line++;
6183 *line = '\0';
6184
Christopher Faulet767a84b2017-11-24 16:50:31 +01006185 ha_alert("parsing [%s:%d]: line too long, truncating at word %d, position %ld: <%s>.\n",
6186 file, linenum, arg + 1, (long)(args[arg] - thisline + 1), args[arg]);
Willy Tarreau7bb651e2009-11-09 21:16:53 +01006187 err_code |= ERR_ALERT | ERR_FATAL;
6188 args[arg] = line;
6189 }
6190
Willy Tarreau540abe42007-05-02 20:50:16 +02006191 /* zero out remaining args and ensure that at least one entry
6192 * is zeroed out.
6193 */
6194 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02006195 args[arg] = line;
6196 }
6197
Willy Tarreau3842f002009-06-14 11:39:52 +02006198 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01006199 if (!strcmp(args[0], "no")) {
William Lallemand0f99e342011-10-12 17:50:54 +02006200 char *tmp;
6201
Willy Tarreau3842f002009-06-14 11:39:52 +02006202 kwm = KWM_NO;
William Lallemand0f99e342011-10-12 17:50:54 +02006203 tmp = args[0];
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01006204 for (arg=0; *args[arg+1]; arg++)
6205 args[arg] = args[arg+1]; // shift args after inversion
William Lallemand0f99e342011-10-12 17:50:54 +02006206 *tmp = '\0'; // fix the next arg to \0
6207 args[arg] = tmp;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01006208 }
Willy Tarreau3842f002009-06-14 11:39:52 +02006209 else if (!strcmp(args[0], "default")) {
6210 kwm = KWM_DEF;
6211 for (arg=0; *args[arg+1]; arg++)
6212 args[arg] = args[arg+1]; // shift args after inversion
6213 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01006214
William Lallemand0f99e342011-10-12 17:50:54 +02006215 if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
6216 strcmp(args[0], "log") != 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006217 ha_alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02006218 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01006219 }
6220
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01006221 /* detect section start */
6222 list_for_each_entry(ics, &sections, list) {
6223 if (strcmp(args[0], ics->section_name) == 0) {
6224 cursection = ics->section_name;
6225 cs = ics;
6226 break;
6227 }
Emeric Brun32da3c42010-09-23 18:39:19 +02006228 }
6229
William Lallemandd2ff56d2017-10-16 11:06:50 +02006230 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006231 ha_alert("parsing [%s:%d]: unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02006232 err_code |= ERR_ALERT | ERR_FATAL;
William Lallemandd2ff56d2017-10-16 11:06:50 +02006233 } else {
6234 /* else it's a section keyword */
Willy Tarreau058e9072009-07-20 09:30:05 +02006235
William Lallemandd2ff56d2017-10-16 11:06:50 +02006236 if (pcs != cs && pcs && pcs->post_section_parser) {
6237 err_code |= pcs->post_section_parser();
6238 if (err_code & ERR_ABORT)
6239 goto err;
6240 }
6241
6242 err_code |= cs->section_parser(file, linenum, args, kwm);
6243 if (err_code & ERR_ABORT)
6244 goto err;
6245 }
6246 pcs = cs;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006247 }
William Lallemandd2ff56d2017-10-16 11:06:50 +02006248
6249 if (pcs == cs && pcs && pcs->post_section_parser)
6250 err_code |= pcs->post_section_parser();
6251
6252err:
Christopher Faulet79bdef32016-11-04 22:36:15 +01006253 free(cfg_scope);
6254 cfg_scope = NULL;
Willy Tarreau6daf3432008-01-22 16:44:08 +01006255 cursection = NULL;
William Lallemand64e84512015-05-12 14:25:37 +02006256 free(thisline);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006257 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02006258 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02006259}
6260
Willy Tarreau64ab6072014-09-16 12:17:36 +02006261/* This function propagates processes from frontend <from> to backend <to> so
6262 * that it is always guaranteed that a backend pointed to by a frontend is
6263 * bound to all of its processes. After that, if the target is a "listen"
6264 * instance, the function recursively descends the target's own targets along
Willy Tarreau98d04852015-05-26 12:18:29 +02006265 * default_backend and use_backend rules. Since the bits are
Willy Tarreau64ab6072014-09-16 12:17:36 +02006266 * checked first to ensure that <to> is already bound to all processes of
6267 * <from>, there is no risk of looping and we ensure to follow the shortest
6268 * path to the destination.
6269 *
6270 * It is possible to set <to> to NULL for the first call so that the function
6271 * takes care of visiting the initial frontend in <from>.
6272 *
6273 * It is important to note that the function relies on the fact that all names
6274 * have already been resolved.
6275 */
6276void propagate_processes(struct proxy *from, struct proxy *to)
6277{
6278 struct switching_rule *rule;
Willy Tarreau64ab6072014-09-16 12:17:36 +02006279
6280 if (to) {
6281 /* check whether we need to go down */
6282 if (from->bind_proc &&
6283 (from->bind_proc & to->bind_proc) == from->bind_proc)
6284 return;
6285
6286 if (!from->bind_proc && !to->bind_proc)
6287 return;
6288
6289 to->bind_proc = from->bind_proc ?
6290 (to->bind_proc | from->bind_proc) : 0;
6291
6292 /* now propagate down */
6293 from = to;
6294 }
6295
Willy Tarreau8a95d8c2014-12-18 13:56:26 +01006296 if (!(from->cap & PR_CAP_FE))
Willy Tarreau64ab6072014-09-16 12:17:36 +02006297 return;
6298
Willy Tarreauf6b70012014-12-18 14:00:43 +01006299 if (from->state == PR_STSTOPPED)
6300 return;
6301
Willy Tarreau64ab6072014-09-16 12:17:36 +02006302 /* default_backend */
6303 if (from->defbe.be)
6304 propagate_processes(from, from->defbe.be);
6305
6306 /* use_backend */
6307 list_for_each_entry(rule, &from->switching_rules, list) {
Cyril Bonté51639692014-10-02 19:56:25 +02006308 if (rule->dynamic)
6309 continue;
Willy Tarreau64ab6072014-09-16 12:17:36 +02006310 to = rule->be.backend;
6311 propagate_processes(from, to);
6312 }
Willy Tarreau64ab6072014-09-16 12:17:36 +02006313}
6314
Willy Tarreaubb925012009-07-23 13:36:36 +02006315/*
6316 * Returns the error code, 0 if OK, or any combination of :
6317 * - ERR_ABORT: must abort ASAP
6318 * - ERR_FATAL: we can continue parsing but not start the service
6319 * - ERR_WARN: a warning has been emitted
6320 * - ERR_ALERT: an alert has been emitted
6321 * Only the two first ones can stop processing, the two others are just
6322 * indicators.
6323 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02006324int check_config_validity()
6325{
6326 int cfgerr = 0;
6327 struct proxy *curproxy = NULL;
6328 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02006329 int err_code = 0;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02006330 unsigned int next_pxid = 1;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02006331 struct bind_conf *bind_conf;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01006332 char *err;
William Lallemand48b4bb42017-10-23 14:36:34 +02006333 struct cfg_postparser *postparser;
Ben Draut054fbee2018-04-13 15:43:04 -06006334 struct dns_resolvers *curr_resolvers = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006335
Willy Tarreau2a65ff02012-09-13 17:54:29 +02006336 bind_conf = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006337 /*
6338 * Now, check for the integrity of all that we have collected.
6339 */
6340
6341 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02006342 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02006343
Willy Tarreau193b8c62012-11-22 00:17:38 +01006344 if (!global.tune.max_http_hdr)
6345 global.tune.max_http_hdr = MAX_HTTP_HDR;
6346
6347 if (!global.tune.cookie_len)
6348 global.tune.cookie_len = CAPTURE_LEN;
6349
Stéphane Cottin23e9e932017-05-18 08:58:41 +02006350 if (!global.tune.requri_len)
6351 global.tune.requri_len = REQURI_LEN;
6352
Willy Tarreaubafbe012017-11-24 17:34:44 +01006353 pool_head_requri = create_pool("requri", global.tune.requri_len , MEM_F_SHARED);
Emeric Brun96fd9262017-07-05 13:33:16 +02006354
Willy Tarreaubafbe012017-11-24 17:34:44 +01006355 pool_head_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED);
Willy Tarreau193b8c62012-11-22 00:17:38 +01006356
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01006357 /* Post initialisation of the users and groups lists. */
6358 err_code = userlist_postinit();
6359 if (err_code != ERR_NONE)
6360 goto out;
6361
Willy Tarreau55bc0f82009-03-15 14:51:53 +01006362 /* first, we will invert the proxy list order */
6363 curproxy = NULL;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01006364 while (proxies_list) {
Willy Tarreau55bc0f82009-03-15 14:51:53 +01006365 struct proxy *next;
6366
Olivier Houchardfbc74e82017-11-24 16:54:05 +01006367 next = proxies_list->next;
6368 proxies_list->next = curproxy;
6369 curproxy = proxies_list;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01006370 if (!next)
6371 break;
Olivier Houchardfbc74e82017-11-24 16:54:05 +01006372 proxies_list = next;
Willy Tarreau55bc0f82009-03-15 14:51:53 +01006373 }
6374
Olivier Houchardfbc74e82017-11-24 16:54:05 +01006375 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02006376 struct switching_rule *rule;
Willy Tarreau4a5cade2012-04-05 21:09:48 +02006377 struct server_rule *srule;
Emeric Brunb982a3d2010-01-04 15:45:53 +01006378 struct sticking_rule *mrule;
Christopher Faulete4e830d2017-09-18 14:51:41 +02006379 struct act_rule *arule;
Dragan Dosen1322d092015-09-22 16:05:32 +02006380 struct logsrv *tmplogsrv;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02006381 unsigned int next_id;
Willy Tarreau16a21472012-11-19 12:39:59 +01006382 int nbproc;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02006383
Willy Tarreau050536d2012-10-04 08:47:34 +02006384 if (curproxy->uuid < 0) {
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02006385 /* proxy ID not set, use automatic numbering with first
6386 * spare entry starting with next_pxid.
6387 */
6388 next_pxid = get_next_id(&used_proxy_id, next_pxid);
6389 curproxy->conf.id.key = curproxy->uuid = next_pxid;
6390 eb32_insert(&used_proxy_id, &curproxy->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02006391 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01006392 next_pxid++;
6393
Willy Tarreau55ea7572007-06-17 19:56:27 +02006394
Willy Tarreaubaaee002006-06-26 02:48:02 +02006395 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02006396 /* ensure we don't keep listeners uselessly bound */
6397 stop_proxy(curproxy);
Willy Tarreau02df7742015-05-01 19:59:56 +02006398 free((void *)curproxy->table.peers.name);
6399 curproxy->table.peers.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006400 continue;
6401 }
6402
Willy Tarreau102df612014-05-07 23:56:38 +02006403 /* Check multi-process mode compatibility for the current proxy */
6404
6405 if (curproxy->bind_proc) {
6406 /* an explicit bind-process was specified, let's check how many
6407 * processes remain.
6408 */
David Carliere6c39412015-07-02 07:00:17 +00006409 nbproc = my_popcountl(curproxy->bind_proc);
Willy Tarreau102df612014-05-07 23:56:38 +02006410
6411 curproxy->bind_proc &= nbits(global.nbproc);
6412 if (!curproxy->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006413 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 +02006414 curproxy->bind_proc = 1;
6415 }
6416 else if (!curproxy->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006417 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 +02006418 curproxy->bind_proc = 0;
6419 }
6420 }
6421
Willy Tarreau3d209582014-05-09 17:06:11 +02006422 /* check and reduce the bind-proc of each listener */
6423 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
6424 unsigned long mask;
6425
Willy Tarreau45a66cc2017-11-24 11:28:00 +01006426 /* HTTP frontends with "h2" as ALPN/NPN will work in
6427 * HTTP/2 and absolutely require buffers 16kB or larger.
6428 */
6429#ifdef USE_OPENSSL
6430 if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
6431#ifdef OPENSSL_NPN_NEGOTIATED
6432 /* check NPN */
Willy Tarreau4db49c02018-11-11 10:36:25 +01006433 if (bind_conf->ssl_conf.npn_str && strstr(bind_conf->ssl_conf.npn_str, "\002h2")) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006434 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",
6435 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01006436 cfgerr++;
6437 }
6438#endif
6439#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
6440 /* check ALPN */
Willy Tarreau4db49c02018-11-11 10:36:25 +01006441 if (bind_conf->ssl_conf.alpn_str && strstr(bind_conf->ssl_conf.alpn_str, "\002h2")) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006442 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",
6443 curproxy->id, bind_conf->file, bind_conf->line, global.tune.bufsize);
Willy Tarreau45a66cc2017-11-24 11:28:00 +01006444 cfgerr++;
6445 }
6446#endif
6447 } /* HTTP && bufsize < 16384 */
6448#endif
6449
Willy Tarreauc477b6f2018-07-27 18:07:41 +02006450 /* detect and address thread affinity inconsistencies */
6451 nbproc = 0;
6452 if (bind_conf->bind_proc)
6453 nbproc = my_ffsl(bind_conf->bind_proc);
6454
6455 mask = bind_conf->bind_thread[nbproc - 1];
Willy Tarreau0c026f42018-08-01 19:12:20 +02006456 if (mask && !(mask & all_threads_mask)) {
Willy Tarreauc477b6f2018-07-27 18:07:41 +02006457 unsigned long new_mask = 0;
6458
6459 while (mask) {
Willy Tarreau0c026f42018-08-01 19:12:20 +02006460 new_mask |= mask & all_threads_mask;
Willy Tarreauc477b6f2018-07-27 18:07:41 +02006461 mask >>= global.nbthread;
6462 }
6463
6464 for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
6465 if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
6466 bind_conf->bind_thread[nbproc] = new_mask;
6467 }
6468 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",
6469 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
6470 }
6471
6472 /* detect process and nbproc affinity inconsistencies */
Willy Tarreau3d209582014-05-09 17:06:11 +02006473 if (!bind_conf->bind_proc)
6474 continue;
6475
6476 mask = nbits(global.nbproc);
6477 if (curproxy->bind_proc)
6478 mask &= curproxy->bind_proc;
6479 /* mask cannot be null here thanks to the previous checks */
6480
David Carliere6c39412015-07-02 07:00:17 +00006481 nbproc = my_popcountl(bind_conf->bind_proc);
Willy Tarreau3d209582014-05-09 17:06:11 +02006482 bind_conf->bind_proc &= mask;
6483
6484 if (!bind_conf->bind_proc && nbproc == 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006485 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",
6486 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02006487 bind_conf->bind_proc = mask & ~(mask - 1);
6488 }
6489 else if (!bind_conf->bind_proc && nbproc > 1) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006490 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",
6491 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Willy Tarreau3d209582014-05-09 17:06:11 +02006492 bind_conf->bind_proc = 0;
6493 }
6494 }
6495
Willy Tarreauff01a212009-03-15 13:46:16 +01006496 switch (curproxy->mode) {
6497 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02006498 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01006499 if (!(curproxy->cap & PR_CAP_FE)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006500 ha_alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
6501 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01006502 cfgerr++;
6503 }
6504
6505 if (curproxy->srv != NULL)
Christopher Faulet767a84b2017-11-24 16:50:31 +01006506 ha_warning("config : servers will be ignored for %s '%s'.\n",
6507 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01006508 break;
6509
6510 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02006511 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01006512 break;
6513
6514 case PR_MODE_HTTP:
Willy Tarreau25320b22013-03-24 07:22:08 +01006515 curproxy->http_needed = 1;
Willy Tarreauff01a212009-03-15 13:46:16 +01006516 break;
William Lallemandcf62f7e2018-10-26 14:47:40 +02006517
6518 case PR_MODE_CLI:
6519 cfgerr += proxy_cfg_ensure_no_http(curproxy);
6520 break;
Willy Tarreauff01a212009-03-15 13:46:16 +01006521 }
6522
Willy Tarreau58aa5cc2018-02-08 09:55:09 +01006523 if (curproxy != global.stats_fe && (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->conf.listeners)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006524 ha_warning("config : %s '%s' has no 'bind' directive. Please declare it as a backend if this was intended.\n",
6525 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauf3934b82015-08-11 11:36:45 +02006526 err_code |= ERR_WARN;
6527 }
6528
Willy Tarreau3cd9af22009-03-15 14:06:41 +01006529 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02006530 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01006531 if (curproxy->options & PR_O_TRANSP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006532 ha_alert("config : %s '%s' cannot use both transparent and balance mode.\n",
6533 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01006534 cfgerr++;
6535 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006536#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01006537 else if (curproxy->srv == NULL) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006538 ha_alert("config : %s '%s' needs at least 1 server in balance mode.\n",
6539 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01006540 cfgerr++;
6541 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006542#endif
Willy Tarreau1620ec32011-08-06 17:05:02 +02006543 else if (curproxy->options & PR_O_DISPATCH) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006544 ha_warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
6545 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02006546 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01006547 }
6548 }
Willy Tarreau1620ec32011-08-06 17:05:02 +02006549 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01006550 /* If no LB algo is set in a backend, and we're not in
6551 * transparent mode, dispatch mode nor proxy mode, we
6552 * want to use balance roundrobin by default.
6553 */
6554 curproxy->lbprm.algo &= ~BE_LB_ALGO;
6555 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02006556 }
6557 }
Willy Tarreau193cf932007-09-17 10:17:23 +02006558
Willy Tarreau1620ec32011-08-06 17:05:02 +02006559 if (curproxy->options & PR_O_DISPATCH)
6560 curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
6561 else if (curproxy->options & PR_O_HTTP_PROXY)
6562 curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
6563 else if (curproxy->options & PR_O_TRANSP)
6564 curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
Willy Tarreau82936582007-11-30 15:20:09 +01006565
Willy Tarreau1620ec32011-08-06 17:05:02 +02006566 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
6567 if (curproxy->options & PR_O_DISABLE404) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006568 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
6569 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02006570 err_code |= ERR_WARN;
6571 curproxy->options &= ~PR_O_DISABLE404;
6572 }
6573 if (curproxy->options2 & PR_O2_CHK_SNDST) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006574 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
6575 "send-state", proxy_type_str(curproxy), curproxy->id);
Willy Tarreau1620ec32011-08-06 17:05:02 +02006576 err_code |= ERR_WARN;
6577 curproxy->options &= ~PR_O2_CHK_SNDST;
6578 }
Willy Tarreauef781042010-01-27 11:53:01 +01006579 }
6580
Simon Horman98637e52014-06-20 12:30:16 +09006581 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_EXT_CHK) {
6582 if (!global.external_check) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006583 ha_alert("Proxy '%s' : '%s' unable to find required 'global.external-check'.\n",
6584 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09006585 cfgerr++;
6586 }
6587 if (!curproxy->check_command) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006588 ha_alert("Proxy '%s' : '%s' unable to find required 'external-check command'.\n",
6589 curproxy->id, "option external-check");
Simon Horman98637e52014-06-20 12:30:16 +09006590 cfgerr++;
6591 }
6592 }
6593
Simon Horman64e34162015-02-06 11:11:57 +09006594 if (curproxy->email_alert.set) {
Simon Horman0ba0e4a2015-01-30 11:23:00 +09006595 if (!(curproxy->email_alert.mailers.name && curproxy->email_alert.from && curproxy->email_alert.to)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006596 ha_warning("config : 'email-alert' will be ignored for %s '%s' (the presence any of "
6597 "'email-alert from', 'email-alert level' 'email-alert mailers', "
6598 "'email-alert myhostname', or 'email-alert to' "
6599 "requires each of 'email-alert from', 'email-alert mailers' and 'email-alert to' "
6600 "to be present).\n",
6601 proxy_type_str(curproxy), curproxy->id);
Simon Horman0ba0e4a2015-01-30 11:23:00 +09006602 err_code |= ERR_WARN;
6603 free_email_alert(curproxy);
6604 }
6605 if (!curproxy->email_alert.myhostname)
Cyril Bontée22bfd62015-12-04 03:07:07 +01006606 curproxy->email_alert.myhostname = strdup(hostname);
Simon Horman9dc49962015-01-30 11:22:59 +09006607 }
6608
Simon Horman98637e52014-06-20 12:30:16 +09006609 if (curproxy->check_command) {
6610 int clear = 0;
6611 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006612 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
6613 "external-check command", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09006614 err_code |= ERR_WARN;
6615 clear = 1;
6616 }
6617 if (curproxy->check_command[0] != '/' && !curproxy->check_path) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006618 ha_alert("Proxy '%s': '%s' does not have a leading '/' and 'external-check path' is not set.\n",
6619 curproxy->id, "external-check command");
Simon Horman98637e52014-06-20 12:30:16 +09006620 cfgerr++;
6621 }
6622 if (clear) {
6623 free(curproxy->check_command);
6624 curproxy->check_command = NULL;
6625 }
6626 }
6627
6628 if (curproxy->check_path) {
6629 if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_EXT_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006630 ha_warning("config : '%s' will be ignored for %s '%s' (requires 'option external-check').\n",
6631 "external-check path", proxy_type_str(curproxy), curproxy->id);
Simon Horman98637e52014-06-20 12:30:16 +09006632 err_code |= ERR_WARN;
6633 free(curproxy->check_path);
6634 curproxy->check_path = NULL;
6635 }
6636 }
6637
Willy Tarreau5fdfb912007-01-01 23:11:07 +01006638 /* if a default backend was specified, let's find it */
6639 if (curproxy->defbe.name) {
6640 struct proxy *target;
6641
Willy Tarreauafb39922015-05-26 12:04:09 +02006642 target = proxy_be_by_name(curproxy->defbe.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01006643 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006644 ha_alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
6645 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01006646 cfgerr++;
6647 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006648 ha_alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
6649 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02006650 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02006651 } else if (target->mode != curproxy->mode &&
6652 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
6653
Christopher Faulet767a84b2017-11-24 16:50:31 +01006654 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) as its default backend (see 'mode').\n",
6655 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
6656 curproxy->conf.file, curproxy->conf.line,
6657 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
6658 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02006659 cfgerr++;
Willy Tarreau68ad3a42018-10-22 11:49:15 +02006660 } else if ((curproxy->options2 ^ target->options2) & PR_O2_USE_HTX) {
6661 ha_alert("%s %s '%s' (%s:%d) tries to use %s %s '%s' (%s:%d) as its default backend, both of which disagree on 'option http-use-htx'.\n",
6662 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
6663 curproxy->conf.file, curproxy->conf.line,
6664 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
6665 target->conf.file, target->conf.line);
6666 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01006667 } else {
6668 free(curproxy->defbe.name);
6669 curproxy->defbe.be = target;
Emeric Brun3f783572017-01-12 11:21:28 +01006670 /* Update tot_fe_maxconn for a further fullconn's computation */
6671 target->tot_fe_maxconn += curproxy->maxconn;
Willy Tarreauff678132012-02-13 14:32:34 +01006672 /* Emit a warning if this proxy also has some servers */
6673 if (curproxy->srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006674 ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
6675 curproxy->id);
Willy Tarreauff678132012-02-13 14:32:34 +01006676 err_code |= ERR_WARN;
6677 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02006678 }
6679 }
6680
Emeric Brun3f783572017-01-12 11:21:28 +01006681 if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
6682 /* Case of listen without default backend
6683 * The curproxy will be its own default backend
6684 * so we update tot_fe_maxconn for a further
6685 * fullconn's computation */
6686 curproxy->tot_fe_maxconn += curproxy->maxconn;
6687 }
6688
Willy Tarreau55ea7572007-06-17 19:56:27 +02006689 /* find the target proxy for 'use_backend' rules */
6690 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02006691 struct proxy *target;
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01006692 struct logformat_node *node;
6693 char *pxname;
6694
6695 /* Try to parse the string as a log format expression. If the result
6696 * of the parsing is only one entry containing a simple string, then
6697 * it's a standard string corresponding to a static rule, thus the
6698 * parsing is cancelled and be.name is restored to be resolved.
6699 */
6700 pxname = rule->be.name;
6701 LIST_INIT(&rule->be.expr);
Thierry FOURNIER / OZON.IO4ed1c952016-11-24 23:57:54 +01006702 curproxy->conf.args.ctx = ARGC_UBK;
6703 curproxy->conf.args.file = rule->file;
6704 curproxy->conf.args.line = rule->line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01006705 err = NULL;
6706 if (!parse_logformat_string(pxname, curproxy, &rule->be.expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006707 ha_alert("Parsing [%s:%d]: failed to parse use_backend rule '%s' : %s.\n",
6708 rule->file, rule->line, pxname, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01006709 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01006710 cfgerr++;
6711 continue;
6712 }
Bertrand Jacquin702d44f2013-11-19 11:43:06 +01006713 node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
6714
6715 if (!LIST_ISEMPTY(&rule->be.expr)) {
6716 if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
6717 rule->dynamic = 1;
6718 free(pxname);
6719 continue;
6720 }
6721 /* simple string: free the expression and fall back to static rule */
6722 free(node->arg);
6723 free(node);
6724 }
6725
6726 rule->dynamic = 0;
6727 rule->be.name = pxname;
Willy Tarreau55ea7572007-06-17 19:56:27 +02006728
Willy Tarreauafb39922015-05-26 12:04:09 +02006729 target = proxy_be_by_name(rule->be.name);
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01006730 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006731 ha_alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
6732 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02006733 cfgerr++;
6734 } else if (target == curproxy) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006735 ha_alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
6736 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02006737 cfgerr++;
Willy Tarreauafb39922015-05-26 12:04:09 +02006738 } else if (target->mode != curproxy->mode &&
6739 !(curproxy->mode == PR_MODE_TCP && target->mode == PR_MODE_HTTP)) {
6740
Christopher Faulet767a84b2017-11-24 16:50:31 +01006741 ha_alert("%s %s '%s' (%s:%d) tries to use incompatible %s %s '%s' (%s:%d) in a 'use_backend' rule (see 'mode').\n",
6742 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
6743 curproxy->conf.file, curproxy->conf.line,
6744 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
6745 target->conf.file, target->conf.line);
Willy Tarreauafb39922015-05-26 12:04:09 +02006746 cfgerr++;
Willy Tarreau68ad3a42018-10-22 11:49:15 +02006747 } else if ((curproxy->options2 ^ target->options2) & PR_O2_USE_HTX) {
6748 ha_alert("%s %s '%s' (%s:%d) tries to use %s %s '%s' (%s:%d) in a 'use_backend' rule, both of which disagree on 'option http-use-htx'.\n",
6749 proxy_mode_str(curproxy->mode), proxy_type_str(curproxy), curproxy->id,
6750 curproxy->conf.file, curproxy->conf.line,
6751 proxy_mode_str(target->mode), proxy_type_str(target), target->id,
6752 target->conf.file, target->conf.line);
6753 cfgerr++;
Willy Tarreau55ea7572007-06-17 19:56:27 +02006754 } else {
6755 free((void *)rule->be.name);
6756 rule->be.backend = target;
Emeric Brun3f783572017-01-12 11:21:28 +01006757 /* For each target of switching rules, we update
6758 * their tot_fe_maxconn, except if a previous rule point
6759 * on the same backend or on the default backend */
6760 if (rule->be.backend != curproxy->defbe.be) {
6761 struct switching_rule *swrule;
6762
6763 list_for_each_entry(swrule, &curproxy->switching_rules, list) {
6764 if (rule == swrule) {
6765 target->tot_fe_maxconn += curproxy->maxconn;
6766 break;
6767 }
6768 else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
6769 /* there is multiple ref of this backend */
6770 break;
6771 }
6772 }
6773 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02006774 }
Willy Tarreau4a5cade2012-04-05 21:09:48 +02006775 }
6776
Willy Tarreau64ab6072014-09-16 12:17:36 +02006777 /* find the target server for 'use_server' rules */
Willy Tarreau4a5cade2012-04-05 21:09:48 +02006778 list_for_each_entry(srule, &curproxy->server_rules, list) {
6779 struct server *target = findserver(curproxy, srule->srv.name);
6780
6781 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006782 ha_alert("config : %s '%s' : unable to find server '%s' referenced in a 'use-server' rule.\n",
6783 proxy_type_str(curproxy), curproxy->id, srule->srv.name);
Willy Tarreau4a5cade2012-04-05 21:09:48 +02006784 cfgerr++;
6785 continue;
6786 }
6787 free((void *)srule->srv.name);
6788 srule->srv.ptr = target;
Willy Tarreau55ea7572007-06-17 19:56:27 +02006789 }
6790
Emeric Brunb982a3d2010-01-04 15:45:53 +01006791 /* find the target table for 'stick' rules */
6792 list_for_each_entry(mrule, &curproxy->sticking_rules, list) {
6793 struct proxy *target;
6794
Emeric Brun1d33b292010-01-04 15:47:17 +01006795 curproxy->be_req_ana |= AN_REQ_STICKING_RULES;
6796 if (mrule->flags & STK_IS_STORE)
6797 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
6798
Emeric Brunb982a3d2010-01-04 15:45:53 +01006799 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02006800 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006801 else
6802 target = curproxy;
6803
6804 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006805 ha_alert("Proxy '%s': unable to find stick-table '%s'.\n",
6806 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006807 cfgerr++;
6808 }
6809 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006810 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
6811 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006812 cfgerr++;
6813 }
Willy Tarreau12785782012-04-27 21:37:17 +02006814 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006815 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
6816 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006817 cfgerr++;
6818 }
6819 else {
6820 free((void *)mrule->table.name);
6821 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02006822 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006823 }
6824 }
6825
6826 /* find the target table for 'store response' rules */
6827 list_for_each_entry(mrule, &curproxy->storersp_rules, list) {
6828 struct proxy *target;
6829
Emeric Brun1d33b292010-01-04 15:47:17 +01006830 curproxy->be_rsp_ana |= AN_RES_STORE_RULES;
6831
Emeric Brunb982a3d2010-01-04 15:45:53 +01006832 if (mrule->table.name)
Willy Tarreau9e0bb102015-05-26 11:24:42 +02006833 target = proxy_tbl_by_name(mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006834 else
6835 target = curproxy;
6836
6837 if (!target) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006838 ha_alert("Proxy '%s': unable to find store table '%s'.\n",
6839 curproxy->id, mrule->table.name);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006840 cfgerr++;
6841 }
6842 else if (target->table.size == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006843 ha_alert("Proxy '%s': stick-table '%s' used but not configured.\n",
6844 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006845 cfgerr++;
6846 }
Willy Tarreau12785782012-04-27 21:37:17 +02006847 else if (!stktable_compatible_sample(mrule->expr, target->table.type)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006848 ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n",
6849 curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006850 cfgerr++;
6851 }
6852 else {
6853 free((void *)mrule->table.name);
6854 mrule->table.t = &(target->table);
Willy Tarreau888617d2010-06-20 09:11:39 +02006855 stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
Emeric Brunb982a3d2010-01-04 15:45:53 +01006856 }
6857 }
6858
Christopher Faulete4e830d2017-09-18 14:51:41 +02006859 /* check validity for 'tcp-request' layer 4 rules */
6860 list_for_each_entry(arule, &curproxy->tcp_req.l4_rules, list) {
6861 err = NULL;
6862 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006863 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02006864 free(err);
Willy Tarreau5f53de72012-12-12 00:25:44 +01006865 cfgerr++;
6866 }
Willy Tarreaud1f96522010-08-03 19:34:32 +02006867 }
6868
Christopher Faulete4e830d2017-09-18 14:51:41 +02006869 /* check validity for 'tcp-request' layer 5 rules */
6870 list_for_each_entry(arule, &curproxy->tcp_req.l5_rules, list) {
6871 err = NULL;
6872 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006873 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02006874 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01006875 cfgerr++;
6876 }
6877 }
6878
Christopher Faulete4e830d2017-09-18 14:51:41 +02006879 /* check validity for 'tcp-request' layer 6 rules */
6880 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
6881 err = NULL;
6882 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006883 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02006884 free(err);
Baptiste Assmanne9544932015-11-03 23:31:35 +01006885 cfgerr++;
6886 }
6887 }
6888
Christopher Faulete4e830d2017-09-18 14:51:41 +02006889 /* check validity for 'http-request' layer 7 rules */
6890 list_for_each_entry(arule, &curproxy->http_req_rules, list) {
6891 err = NULL;
6892 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006893 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02006894 free(err);
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08006895 cfgerr++;
6896 }
Ruoshan Huange4edc6b2016-07-14 15:07:45 +08006897 }
6898
Christopher Faulete4e830d2017-09-18 14:51:41 +02006899 /* check validity for 'http-response' layer 7 rules */
6900 list_for_each_entry(arule, &curproxy->http_res_rules, list) {
6901 err = NULL;
6902 if (arule->check_ptr && !arule->check_ptr(arule, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006903 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulete4e830d2017-09-18 14:51:41 +02006904 free(err);
Willy Tarreau09448f72014-06-25 18:12:15 +02006905 cfgerr++;
6906 }
Willy Tarreau09448f72014-06-25 18:12:15 +02006907 }
6908
Willy Tarreaub3dc39d2014-04-28 22:06:57 +02006909 /* move any "block" rules at the beginning of the http-request rules */
6910 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
6911 /* insert block_rules into http_req_rules at the beginning */
6912 curproxy->block_rules.p->n = curproxy->http_req_rules.n;
6913 curproxy->http_req_rules.n->p = curproxy->block_rules.p;
6914 curproxy->block_rules.n->p = &curproxy->http_req_rules;
6915 curproxy->http_req_rules.n = curproxy->block_rules.n;
6916 LIST_INIT(&curproxy->block_rules);
6917 }
6918
Emeric Brun32da3c42010-09-23 18:39:19 +02006919 if (curproxy->table.peers.name) {
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02006920 struct peers *curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02006921
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02006922 for (curpeers = cfg_peers; curpeers; curpeers = curpeers->next) {
Emeric Brun32da3c42010-09-23 18:39:19 +02006923 if (strcmp(curpeers->id, curproxy->table.peers.name) == 0) {
6924 free((void *)curproxy->table.peers.name);
Willy Tarreau973ca492013-01-17 21:34:52 +01006925 curproxy->table.peers.p = curpeers;
Emeric Brun32da3c42010-09-23 18:39:19 +02006926 break;
6927 }
6928 }
6929
6930 if (!curpeers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006931 ha_alert("Proxy '%s': unable to find sync peers '%s'.\n",
6932 curproxy->id, curproxy->table.peers.name);
Willy Tarreaud66bf962011-10-28 14:16:49 +02006933 free((void *)curproxy->table.peers.name);
6934 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02006935 cfgerr++;
6936 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02006937 else if (curpeers->state == PR_STSTOPPED) {
6938 /* silently disable this peers section */
6939 curproxy->table.peers.p = NULL;
6940 }
Emeric Brun32da3c42010-09-23 18:39:19 +02006941 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006942 ha_alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
6943 curproxy->id, localpeer, curpeers->id);
Willy Tarreaud66bf962011-10-28 14:16:49 +02006944 curproxy->table.peers.p = NULL;
Emeric Brun32da3c42010-09-23 18:39:19 +02006945 cfgerr++;
6946 }
6947 }
6948
Simon Horman9dc49962015-01-30 11:22:59 +09006949
6950 if (curproxy->email_alert.mailers.name) {
6951 struct mailers *curmailers = mailers;
6952
6953 for (curmailers = mailers; curmailers; curmailers = curmailers->next) {
Christopher Faulet0108bb32017-10-20 21:34:32 +02006954 if (!strcmp(curmailers->id, curproxy->email_alert.mailers.name))
Simon Horman9dc49962015-01-30 11:22:59 +09006955 break;
Simon Horman9dc49962015-01-30 11:22:59 +09006956 }
Simon Horman9dc49962015-01-30 11:22:59 +09006957 if (!curmailers) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006958 ha_alert("Proxy '%s': unable to find mailers '%s'.\n",
6959 curproxy->id, curproxy->email_alert.mailers.name);
Simon Horman9dc49962015-01-30 11:22:59 +09006960 free_email_alert(curproxy);
6961 cfgerr++;
6962 }
Christopher Faulet0108bb32017-10-20 21:34:32 +02006963 else {
6964 err = NULL;
6965 if (init_email_alert(curmailers, curproxy, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006966 ha_alert("Proxy '%s': %s.\n", curproxy->id, err);
Christopher Faulet0108bb32017-10-20 21:34:32 +02006967 free(err);
6968 cfgerr++;
6969 }
6970 }
Simon Horman9dc49962015-01-30 11:22:59 +09006971 }
6972
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01006973 if (curproxy->uri_auth && !(curproxy->uri_auth->flags & ST_CONVDONE) &&
Willy Tarreauff011f22011-01-06 17:51:27 +01006974 !LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01006975 (curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01006976 ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
6977 "proxy", curproxy->id);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01006978 cfgerr++;
6979 goto out_uri_auth_compat;
6980 }
6981
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01006982 if (curproxy->uri_auth && curproxy->uri_auth->userlist && !(curproxy->uri_auth->flags & ST_CONVDONE)) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01006983 const char *uri_auth_compat_req[10];
Thierry FOURNIERa28a9422015-08-04 19:35:46 +02006984 struct act_rule *rule;
Willy Tarreau95fa4692010-02-01 13:05:50 +01006985 int i = 0;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01006986
Willy Tarreau95fa4692010-02-01 13:05:50 +01006987 /* build the ACL condition from scratch. We're relying on anonymous ACLs for that */
6988 uri_auth_compat_req[i++] = "auth";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01006989
6990 if (curproxy->uri_auth->auth_realm) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01006991 uri_auth_compat_req[i++] = "realm";
6992 uri_auth_compat_req[i++] = curproxy->uri_auth->auth_realm;
6993 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01006994
Willy Tarreau95fa4692010-02-01 13:05:50 +01006995 uri_auth_compat_req[i++] = "unless";
6996 uri_auth_compat_req[i++] = "{";
6997 uri_auth_compat_req[i++] = "http_auth(.internal-stats-userlist)";
6998 uri_auth_compat_req[i++] = "}";
6999 uri_auth_compat_req[i++] = "";
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007000
Willy Tarreauff011f22011-01-06 17:51:27 +01007001 rule = parse_http_req_cond(uri_auth_compat_req, "internal-stats-auth-compat", 0, curproxy);
7002 if (!rule) {
Willy Tarreau95fa4692010-02-01 13:05:50 +01007003 cfgerr++;
7004 break;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007005 }
7006
Willy Tarreauff011f22011-01-06 17:51:27 +01007007 LIST_ADDQ(&curproxy->uri_auth->http_req_rules, &rule->list);
Willy Tarreau95fa4692010-02-01 13:05:50 +01007008
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007009 if (curproxy->uri_auth->auth_realm) {
7010 free(curproxy->uri_auth->auth_realm);
7011 curproxy->uri_auth->auth_realm = NULL;
7012 }
Krzysztof Piotr Oledzki329f74d2010-02-22 20:27:23 +01007013
7014 curproxy->uri_auth->flags |= ST_CONVDONE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +01007015 }
7016out_uri_auth_compat:
7017
Dragan Dosen43885c72015-10-01 13:18:13 +02007018 /* check whether we have a log server that uses RFC5424 log format */
Dragan Dosen1322d092015-09-22 16:05:32 +02007019 list_for_each_entry(tmplogsrv, &curproxy->logsrvs, list) {
Dragan Dosen43885c72015-10-01 13:18:13 +02007020 if (tmplogsrv->format == LOG_FORMAT_RFC5424) {
7021 if (!curproxy->conf.logformat_sd_string) {
7022 /* set the default logformat_sd_string */
7023 curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
7024 }
Dragan Dosen1322d092015-09-22 16:05:32 +02007025 break;
Dragan Dosen1322d092015-09-22 16:05:32 +02007026 }
Dragan Dosen1322d092015-09-22 16:05:32 +02007027 }
Dragan Dosen68d2e3a2015-09-19 22:35:44 +02007028
Willy Tarreaua4312fa2013-04-02 16:34:32 +02007029 /* compile the log format */
7030 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau62a61232013-04-12 18:13:46 +02007031 if (curproxy->conf.logformat_string != default_http_log_format &&
7032 curproxy->conf.logformat_string != default_tcp_log_format &&
7033 curproxy->conf.logformat_string != clf_http_log_format)
7034 free(curproxy->conf.logformat_string);
7035 curproxy->conf.logformat_string = NULL;
7036 free(curproxy->conf.lfs_file);
7037 curproxy->conf.lfs_file = NULL;
7038 curproxy->conf.lfs_line = 0;
Dragan Dosen0b85ece2015-09-25 19:17:44 +02007039
7040 if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
7041 free(curproxy->conf.logformat_sd_string);
7042 curproxy->conf.logformat_sd_string = NULL;
7043 free(curproxy->conf.lfsd_file);
7044 curproxy->conf.lfsd_file = NULL;
7045 curproxy->conf.lfsd_line = 0;
Willy Tarreaua4312fa2013-04-02 16:34:32 +02007046 }
7047
Willy Tarreau62a61232013-04-12 18:13:46 +02007048 if (curproxy->conf.logformat_string) {
7049 curproxy->conf.args.ctx = ARGC_LOG;
7050 curproxy->conf.args.file = curproxy->conf.lfs_file;
7051 curproxy->conf.args.line = curproxy->conf.lfs_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007052 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007053 if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007054 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007055 ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
7056 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007057 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007058 cfgerr++;
7059 }
Willy Tarreau62a61232013-04-12 18:13:46 +02007060 curproxy->conf.args.file = NULL;
7061 curproxy->conf.args.line = 0;
7062 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02007063
Dragan Dosen0b85ece2015-09-25 19:17:44 +02007064 if (curproxy->conf.logformat_sd_string) {
7065 curproxy->conf.args.ctx = ARGC_LOGSD;
7066 curproxy->conf.args.file = curproxy->conf.lfsd_file;
7067 curproxy->conf.args.line = curproxy->conf.lfsd_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007068 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007069 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 +01007070 SMP_VAL_FE_LOG_END, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007071 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
7072 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007073 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007074 cfgerr++;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007075 } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007076 ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
7077 curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007078 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007079 cfgerr++;
7080 }
Dragan Dosen0b85ece2015-09-25 19:17:44 +02007081 curproxy->conf.args.file = NULL;
7082 curproxy->conf.args.line = 0;
7083 }
7084
Willy Tarreau62a61232013-04-12 18:13:46 +02007085 if (curproxy->conf.uniqueid_format_string) {
7086 curproxy->conf.args.ctx = ARGC_UIF;
7087 curproxy->conf.args.file = curproxy->conf.uif_file;
7088 curproxy->conf.args.line = curproxy->conf.uif_line;
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007089 err = NULL;
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007090 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 +01007091 (curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007092 ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
7093 curproxy->conf.uif_file, curproxy->conf.uif_line, err);
Thierry FOURNIER / OZON.IO8a4e4422016-11-23 00:41:28 +01007094 free(err);
Thierry FOURNIER / OZON.IO59fd5112016-11-22 23:50:02 +01007095 cfgerr++;
7096 }
Willy Tarreau62a61232013-04-12 18:13:46 +02007097 curproxy->conf.args.file = NULL;
7098 curproxy->conf.args.line = 0;
7099 }
Willy Tarreaua4312fa2013-04-02 16:34:32 +02007100
Thierry FOURNIER9eec0a62014-01-22 18:38:02 +01007101 /* only now we can check if some args remain unresolved.
7102 * This must be done after the users and groups resolution.
7103 */
Willy Tarreaua4312fa2013-04-02 16:34:32 +02007104 cfgerr += smp_resolve_args(curproxy);
7105 if (!cfgerr)
7106 cfgerr += acl_find_targets(curproxy);
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +01007107
Willy Tarreau2738a142006-07-08 17:28:09 +02007108 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007109 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02007110 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreauce887fd2012-05-12 12:50:00 +02007111 (!curproxy->timeout.connect ||
7112 (!curproxy->timeout.server && (curproxy->mode == PR_MODE_HTTP || !curproxy->timeout.tunnel)))))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007113 ha_warning("config : missing timeouts for %s '%s'.\n"
7114 " | While not properly invalid, you will certainly encounter various problems\n"
7115 " | with such a configuration. To fix this, please ensure that all following\n"
7116 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
7117 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007118 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02007119 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02007120
Willy Tarreau1fa31262007-12-03 00:36:16 +01007121 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
7122 * We must still support older configurations, so let's find out whether those
7123 * parameters have been set or must be copied from contimeouts.
7124 */
7125 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007126 if (!curproxy->timeout.tarpit ||
7127 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01007128 /* tarpit timeout not set. We search in the following order:
7129 * default.tarpit, curr.connect, default.connect.
7130 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007131 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01007132 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007133 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01007134 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007135 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01007136 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01007137 }
7138 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007139 (!curproxy->timeout.queue ||
7140 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01007141 /* queue timeout not set. We search in the following order:
7142 * default.queue, curr.connect, default.connect.
7143 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007144 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01007145 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007146 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01007147 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02007148 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01007149 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01007150 }
7151 }
7152
Willy Tarreau1620ec32011-08-06 17:05:02 +02007153 if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
Willy Tarreau137325d2010-02-01 16:38:17 +01007154 curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02007155 curproxy->check_req = malloc(curproxy->check_len);
Willy Tarreau137325d2010-02-01 16:38:17 +01007156 memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
Willy Tarreauf3c69202006-07-09 16:42:34 +02007157 }
7158
Willy Tarreau215663d2014-06-13 18:30:23 +02007159 if (!LIST_ISEMPTY(&curproxy->tcpcheck_rules) &&
7160 (curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_TCPCHK_CHK) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007161 ha_warning("config : %s '%s' uses tcp-check rules without 'option tcp-check', so the rules are ignored.\n",
7162 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau215663d2014-06-13 18:30:23 +02007163 err_code |= ERR_WARN;
7164 }
7165
Willy Tarreau193b8c62012-11-22 00:17:38 +01007166 /* ensure that cookie capture length is not too large */
7167 if (curproxy->capture_len >= global.tune.cookie_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007168 ha_warning("config : truncating capture length to %d bytes for %s '%s'.\n",
7169 global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id);
Willy Tarreau193b8c62012-11-22 00:17:38 +01007170 err_code |= ERR_WARN;
7171 curproxy->capture_len = global.tune.cookie_len - 1;
7172 }
7173
Willy Tarreaucf7f3202007-05-13 22:46:04 +02007174 /* The small pools required for the capture lists */
Willy Tarreau9a54e132012-03-24 08:33:05 +01007175 if (curproxy->nb_req_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02007176 curproxy->req_cap_pool = create_pool("ptrcap",
7177 curproxy->nb_req_cap * sizeof(char *),
7178 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01007179 }
7180
7181 if (curproxy->nb_rsp_cap) {
Willy Tarreaud9ed3d22014-06-13 12:23:06 +02007182 curproxy->rsp_cap_pool = create_pool("ptrcap",
7183 curproxy->nb_rsp_cap * sizeof(char *),
7184 MEM_F_SHARED);
Willy Tarreau9a54e132012-03-24 08:33:05 +01007185 }
Willy Tarreaucf7f3202007-05-13 22:46:04 +02007186
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02007187 switch (curproxy->load_server_state_from_file) {
7188 case PR_SRV_STATE_FILE_UNSPEC:
7189 curproxy->load_server_state_from_file = PR_SRV_STATE_FILE_NONE;
7190 break;
7191 case PR_SRV_STATE_FILE_GLOBAL:
7192 if (!global.server_state_file) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007193 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",
7194 curproxy->id);
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02007195 err_code |= ERR_WARN;
7196 }
7197 break;
7198 }
7199
Willy Tarreaubaaee002006-06-26 02:48:02 +02007200 /* first, we will invert the servers list order */
7201 newsrv = NULL;
7202 while (curproxy->srv) {
7203 struct server *next;
7204
7205 next = curproxy->srv->next;
7206 curproxy->srv->next = newsrv;
7207 newsrv = curproxy->srv;
7208 if (!next)
7209 break;
7210 curproxy->srv = next;
7211 }
7212
Willy Tarreau17edc812014-01-03 12:14:34 +01007213 /* Check that no server name conflicts. This causes trouble in the stats.
7214 * We only emit a warning for the first conflict affecting each server,
7215 * in order to avoid combinatory explosion if all servers have the same
7216 * name. We do that only for servers which do not have an explicit ID,
7217 * because these IDs were made also for distinguishing them and we don't
7218 * want to annoy people who correctly manage them.
7219 */
7220 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
7221 struct server *other_srv;
7222
7223 if (newsrv->puid)
7224 continue;
7225
7226 for (other_srv = curproxy->srv; other_srv && other_srv != newsrv; other_srv = other_srv->next) {
7227 if (!other_srv->puid && strcmp(other_srv->id, newsrv->id) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007228 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",
7229 newsrv->conf.file, newsrv->conf.line,
7230 proxy_type_str(curproxy), curproxy->id,
7231 newsrv->id, other_srv->conf.line);
Willy Tarreau17edc812014-01-03 12:14:34 +01007232 break;
7233 }
7234 }
7235 }
7236
Willy Tarreaudd701652010-05-25 23:03:02 +02007237 /* assign automatic UIDs to servers which don't have one yet */
7238 next_id = 1;
7239 newsrv = curproxy->srv;
7240 while (newsrv != NULL) {
7241 if (!newsrv->puid) {
7242 /* server ID not set, use automatic numbering with first
7243 * spare entry starting with next_svid.
7244 */
7245 next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
7246 newsrv->conf.id.key = newsrv->puid = next_id;
7247 eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
7248 }
7249 next_id++;
7250 newsrv = newsrv->next;
7251 }
7252
Willy Tarreau20697042007-11-15 23:26:18 +01007253 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01007254 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02007255
Willy Tarreau62c3be22012-01-20 13:12:32 +01007256 /*
7257 * If this server supports a maxconn parameter, it needs a dedicated
7258 * tasks to fill the emptied slots when a connection leaves.
7259 * Also, resolve deferred tracking dependency if needed.
7260 */
7261 newsrv = curproxy->srv;
7262 while (newsrv != NULL) {
7263 if (newsrv->minconn > newsrv->maxconn) {
7264 /* Only 'minconn' was specified, or it was higher than or equal
7265 * to 'maxconn'. Let's turn this into maxconn and clean it, as
7266 * this will avoid further useless expensive computations.
7267 */
7268 newsrv->maxconn = newsrv->minconn;
7269 } else if (newsrv->maxconn && !newsrv->minconn) {
7270 /* minconn was not specified, so we set it to maxconn */
7271 newsrv->minconn = newsrv->maxconn;
7272 }
7273
Willy Tarreau17d45382016-12-22 21:16:08 +01007274 /* this will also properly set the transport layer for prod and checks */
7275 if (newsrv->use_ssl || newsrv->check.use_ssl) {
7276 if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
7277 cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
7278 }
Emeric Brun94324a42012-10-11 14:00:19 +02007279
Willy Tarreau2f075e92013-12-03 11:11:34 +01007280 /* set the check type on the server */
7281 newsrv->check.type = curproxy->options2 & PR_O2_CHK_ANY;
7282
Willy Tarreau62c3be22012-01-20 13:12:32 +01007283 if (newsrv->trackit) {
7284 struct proxy *px;
Willy Tarreau32091232014-05-16 13:52:00 +02007285 struct server *srv, *loop;
Willy Tarreau62c3be22012-01-20 13:12:32 +01007286 char *pname, *sname;
7287
7288 pname = newsrv->trackit;
7289 sname = strrchr(pname, '/');
7290
7291 if (sname)
7292 *sname++ = '\0';
7293 else {
7294 sname = pname;
7295 pname = NULL;
7296 }
7297
7298 if (pname) {
Willy Tarreau9e0bb102015-05-26 11:24:42 +02007299 px = proxy_be_by_name(pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01007300 if (!px) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007301 ha_alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
7302 proxy_type_str(curproxy), curproxy->id,
7303 newsrv->id, pname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01007304 cfgerr++;
7305 goto next_srv;
7306 }
7307 } else
7308 px = curproxy;
7309
7310 srv = findserver(px, sname);
7311 if (!srv) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007312 ha_alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
7313 proxy_type_str(curproxy), curproxy->id,
7314 newsrv->id, sname);
Willy Tarreau62c3be22012-01-20 13:12:32 +01007315 cfgerr++;
7316 goto next_srv;
7317 }
7318
Willy Tarreau32091232014-05-16 13:52:00 +02007319 if (!(srv->check.state & CHK_ST_CONFIGURED) &&
7320 !(srv->agent.state & CHK_ST_CONFIGURED) &&
7321 !srv->track && !srv->trackit) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007322 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for "
7323 "tracking as it does not have any check nor agent enabled.\n",
7324 proxy_type_str(curproxy), curproxy->id,
7325 newsrv->id, px->id, srv->id);
Willy Tarreau32091232014-05-16 13:52:00 +02007326 cfgerr++;
7327 goto next_srv;
7328 }
7329
7330 for (loop = srv->track; loop && loop != newsrv; loop = loop->track);
7331
Frédéric Lécaille2efc6492017-03-14 14:32:17 +01007332 if (newsrv == srv || loop) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007333 ha_alert("config : %s '%s', server '%s': unable to track %s/%s as it "
7334 "belongs to a tracking chain looping back to %s/%s.\n",
7335 proxy_type_str(curproxy), curproxy->id,
7336 newsrv->id, px->id, srv->id, px->id,
7337 newsrv == srv ? srv->id : loop->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01007338 cfgerr++;
7339 goto next_srv;
7340 }
7341
7342 if (curproxy != px &&
7343 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007344 ha_alert("config : %s '%s', server '%s': unable to use %s/%s for"
7345 "tracking: disable-on-404 option inconsistency.\n",
7346 proxy_type_str(curproxy), curproxy->id,
7347 newsrv->id, px->id, srv->id);
Willy Tarreau62c3be22012-01-20 13:12:32 +01007348 cfgerr++;
7349 goto next_srv;
7350 }
7351
Willy Tarreau62c3be22012-01-20 13:12:32 +01007352 newsrv->track = srv;
Willy Tarreau1a53a3a2013-12-11 15:27:05 +01007353 newsrv->tracknext = srv->trackers;
7354 srv->trackers = newsrv;
Willy Tarreau62c3be22012-01-20 13:12:32 +01007355
7356 free(newsrv->trackit);
7357 newsrv->trackit = NULL;
7358 }
Baptiste Assmanna68ca962015-04-14 01:15:08 +02007359
Willy Tarreau62c3be22012-01-20 13:12:32 +01007360 next_srv:
7361 newsrv = newsrv->next;
7362 }
7363
Olivier Houchard4e694042017-03-14 20:01:29 +01007364 /*
7365 * Try to generate dynamic cookies for servers now.
7366 * It couldn't be done earlier, since at the time we parsed
7367 * the server line, we may not have known yet that we
7368 * should use dynamic cookies, or the secret key may not
7369 * have been provided yet.
7370 */
7371 if (curproxy->ck_opts & PR_CK_DYNAMIC) {
7372 newsrv = curproxy->srv;
7373 while (newsrv != NULL) {
7374 srv_set_dyncookie(newsrv);
7375 newsrv = newsrv->next;
7376 }
7377
7378 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007379 /* We have to initialize the server lookup mechanism depending
Joseph Herlanta14c03e2018-11-15 14:04:19 -08007380 * on what LB algorithm was chosen.
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007381 */
7382
7383 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
7384 switch (curproxy->lbprm.algo & BE_LB_KIND) {
7385 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02007386 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
7387 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
7388 init_server_map(curproxy);
Willy Tarreau760e81d2018-05-03 07:20:40 +02007389 } else if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_RANDOM) {
7390 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
7391 chash_init_server_tree(curproxy);
Willy Tarreau9757a382009-10-03 12:56:50 +02007392 } else {
7393 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
7394 fwrr_init_server_groups(curproxy);
7395 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007396 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02007397
Willy Tarreau3ebb1162012-02-13 16:57:44 +01007398 case BE_LB_KIND_CB:
Willy Tarreauf09c6602012-02-13 17:12:08 +01007399 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_CB_LC) {
7400 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
7401 fwlc_init_server_tree(curproxy);
7402 } else {
7403 curproxy->lbprm.algo |= BE_LB_LKUP_FSTREE | BE_LB_PROP_DYN;
7404 fas_init_server_tree(curproxy);
7405 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007406 break;
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02007407
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007408 case BE_LB_KIND_HI:
Willy Tarreau6b2e11b2009-10-01 07:52:15 +02007409 if ((curproxy->lbprm.algo & BE_LB_HASH_TYPE) == BE_LB_HASH_CONS) {
7410 curproxy->lbprm.algo |= BE_LB_LKUP_CHTREE | BE_LB_PROP_DYN;
7411 chash_init_server_tree(curproxy);
7412 } else {
7413 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
7414 init_server_map(curproxy);
7415 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02007416 break;
7417 }
Christopher Faulet2a944ee2017-11-07 10:42:54 +01007418 HA_SPIN_INIT(&curproxy->lbprm.lock);
Willy Tarreaubaaee002006-06-26 02:48:02 +02007419
7420 if (curproxy->options & PR_O_LOGASAP)
7421 curproxy->to_log &= ~LW_BYTES;
7422
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02007423 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Dragan Dosen0b85ece2015-09-25 19:17:44 +02007424 (curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->logsrvs) &&
7425 (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007426 ha_warning("config : log format ignored for %s '%s' since it has no log address.\n",
7427 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02007428 err_code |= ERR_WARN;
7429 }
7430
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007431 if (curproxy->mode != PR_MODE_HTTP) {
7432 int optnum;
7433
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007434 if (curproxy->uri_auth) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007435 ha_warning("config : 'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
7436 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007437 err_code |= ERR_WARN;
7438 curproxy->uri_auth = NULL;
7439 }
7440
Willy Tarreaude7dc882017-03-10 11:49:21 +01007441 if (curproxy->capture_name) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007442 ha_warning("config : 'capture' statement ignored for %s '%s' as it requires HTTP mode.\n",
7443 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01007444 err_code |= ERR_WARN;
7445 }
7446
7447 if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007448 ha_warning("config : 'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
7449 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01007450 err_code |= ERR_WARN;
7451 }
7452
7453 if (!LIST_ISEMPTY(&curproxy->http_res_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007454 ha_warning("config : 'http-response' rules ignored for %s '%s' as they require HTTP mode.\n",
7455 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01007456 err_code |= ERR_WARN;
7457 }
7458
7459 if (!LIST_ISEMPTY(&curproxy->block_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007460 ha_warning("config : 'block' rules ignored for %s '%s' as they require HTTP mode.\n",
7461 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01007462 err_code |= ERR_WARN;
7463 }
7464
7465 if (!LIST_ISEMPTY(&curproxy->redirect_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007466 ha_warning("config : 'redirect' rules ignored for %s '%s' as they require HTTP mode.\n",
7467 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaude7dc882017-03-10 11:49:21 +01007468 err_code |= ERR_WARN;
7469 }
7470
Willy Tarreau87cf5142011-08-19 22:57:24 +02007471 if (curproxy->options & (PR_O_FWDFOR | PR_O_FF_ALWAYS)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007472 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
7473 "forwardfor", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007474 err_code |= ERR_WARN;
Willy Tarreau87cf5142011-08-19 22:57:24 +02007475 curproxy->options &= ~(PR_O_FWDFOR | PR_O_FF_ALWAYS);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007476 }
7477
7478 if (curproxy->options & PR_O_ORGTO) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007479 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
7480 "originalto", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007481 err_code |= ERR_WARN;
7482 curproxy->options &= ~PR_O_ORGTO;
7483 }
7484
7485 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
7486 if (cfg_opts[optnum].mode == PR_MODE_HTTP &&
7487 (curproxy->cap & cfg_opts[optnum].cap) &&
7488 (curproxy->options & cfg_opts[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007489 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
7490 cfg_opts[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007491 err_code |= ERR_WARN;
7492 curproxy->options &= ~cfg_opts[optnum].val;
7493 }
7494 }
7495
7496 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
7497 if (cfg_opts2[optnum].mode == PR_MODE_HTTP &&
7498 (curproxy->cap & cfg_opts2[optnum].cap) &&
7499 (curproxy->options2 & cfg_opts2[optnum].val)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007500 ha_warning("config : 'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
7501 cfg_opts2[optnum].name, proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007502 err_code |= ERR_WARN;
7503 curproxy->options2 &= ~cfg_opts2[optnum].val;
7504 }
7505 }
Willy Tarreaubce70882009-09-07 11:51:47 +02007506
Willy Tarreau29fbe512015-08-20 19:35:14 +02007507#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01007508 if (curproxy->conn_src.bind_hdr_occ) {
7509 curproxy->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01007510 ha_warning("config : %s '%s' : ignoring use of header %s as source IP in non-HTTP mode.\n",
7511 proxy_type_str(curproxy), curproxy->id, curproxy->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02007512 err_code |= ERR_WARN;
7513 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02007514#endif
Willy Tarreaue24fdfb2010-03-25 07:22:56 +01007515 }
7516
Willy Tarreaubaaee002006-06-26 02:48:02 +02007517 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01007518 * ensure that we're not cross-dressing a TCP server into HTTP.
7519 */
7520 newsrv = curproxy->srv;
7521 while (newsrv != NULL) {
Willy Tarreau0cec3312011-10-31 13:49:26 +01007522 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007523 ha_alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
7524 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02007525 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01007526 }
Willy Tarreaubce70882009-09-07 11:51:47 +02007527
Willy Tarreau0cec3312011-10-31 13:49:26 +01007528 if ((curproxy->mode != PR_MODE_HTTP) && newsrv->cklen) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007529 ha_warning("config : %s '%s' : ignoring cookie for server '%s' as HTTP mode is disabled.\n",
7530 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau0cec3312011-10-31 13:49:26 +01007531 err_code |= ERR_WARN;
7532 }
7533
Willy Tarreauc93cd162014-05-13 15:54:22 +02007534 if ((newsrv->flags & SRV_F_MAPPORTS) && (curproxy->options2 & PR_O2_RDPC_PRST)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007535 ha_warning("config : %s '%s' : RDP cookie persistence will not work for server '%s' because it lacks an explicit port number.\n",
7536 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau82ffa392013-08-13 17:19:08 +02007537 err_code |= ERR_WARN;
7538 }
7539
Willy Tarreau29fbe512015-08-20 19:35:14 +02007540#if defined(CONFIG_HAP_TRANSPARENT)
Willy Tarreauef9a3602012-12-08 22:29:20 +01007541 if (curproxy->mode != PR_MODE_HTTP && newsrv->conn_src.bind_hdr_occ) {
7542 newsrv->conn_src.bind_hdr_occ = 0;
Christopher Faulet767a84b2017-11-24 16:50:31 +01007543 ha_warning("config : %s '%s' : server %s cannot use header %s as source IP in non-HTTP mode.\n",
7544 proxy_type_str(curproxy), curproxy->id, newsrv->id, newsrv->conn_src.bind_hdr_name);
Willy Tarreaubce70882009-09-07 11:51:47 +02007545 err_code |= ERR_WARN;
7546 }
Willy Tarreauefa5f512010-03-30 20:13:29 +02007547#endif
Willy Tarreau4c183462017-01-06 12:21:38 +01007548
Willy Tarreau46deab62018-04-28 07:18:15 +02007549 if ((curproxy->mode != PR_MODE_HTTP) && (curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR)
7550 curproxy->options &= ~PR_O_REUSE_MASK;
7551
Willy Tarreau4c183462017-01-06 12:21:38 +01007552 if ((curproxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) {
7553 if ((curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
7554 (curproxy->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP ||
7555 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CLI ||
7556 (newsrv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_CIP) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007557 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",
7558 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01007559 err_code |= ERR_WARN;
7560 }
7561
7562
7563 if (newsrv->pp_opts & (SRV_PP_V1|SRV_PP_V2)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007564 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",
7565 proxy_type_str(curproxy), curproxy->id, newsrv->id);
Willy Tarreau4c183462017-01-06 12:21:38 +01007566 err_code |= ERR_WARN;
7567 }
7568 }
7569
Willy Tarreau21d2af32008-02-14 20:25:24 +01007570 newsrv = newsrv->next;
7571 }
7572
Willy Tarreaue42bd962014-09-16 16:21:19 +02007573 /* check if we have a frontend with "tcp-request content" looking at L7
7574 * with no inspect-delay
7575 */
7576 if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
Christopher Faulete4e830d2017-09-18 14:51:41 +02007577 list_for_each_entry(arule, &curproxy->tcp_req.inspect_rules, list) {
7578 if (arule->action == ACT_TCP_CAPTURE &&
7579 !(arule->arg.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02007580 break;
Christopher Faulete4e830d2017-09-18 14:51:41 +02007581 if ((arule->action >= ACT_ACTION_TRK_SC0 && arule->action <= ACT_ACTION_TRK_SCMAX) &&
7582 !(arule->arg.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
Willy Tarreaue42bd962014-09-16 16:21:19 +02007583 break;
7584 }
7585
Christopher Faulete4e830d2017-09-18 14:51:41 +02007586 if (&arule->list != &curproxy->tcp_req.inspect_rules) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007587 ha_warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
7588 " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
7589 " This means that these rules will randomly find their contents. This can be fixed by"
7590 " setting the tcp-request inspect-delay.\n",
7591 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaue42bd962014-09-16 16:21:19 +02007592 err_code |= ERR_WARN;
7593 }
7594 }
7595
Christopher Fauletd7c91962015-04-30 11:48:27 +02007596 /* Check filter configuration, if any */
7597 cfgerr += flt_check(curproxy);
7598
Willy Tarreauc1a21672009-08-16 22:37:44 +02007599 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau050536d2012-10-04 08:47:34 +02007600 if (!curproxy->accept)
7601 curproxy->accept = frontend_accept;
Willy Tarreau81f9aa32010-06-01 17:45:26 +02007602
Willy Tarreauc1a21672009-08-16 22:37:44 +02007603 if (curproxy->tcp_req.inspect_delay ||
7604 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
Willy Tarreaufb356202010-08-03 14:02:05 +02007605 curproxy->fe_req_ana |= AN_REQ_INSPECT_FE;
Willy Tarreauc1a21672009-08-16 22:37:44 +02007606
Willy Tarreau4e5b8282009-08-16 22:57:50 +02007607 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02007608 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02007609 curproxy->fe_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02007610 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02007611
William Lallemandcf62f7e2018-10-26 14:47:40 +02007612 if (curproxy->mode == PR_MODE_CLI) {
7613 curproxy->fe_req_ana |= AN_REQ_WAIT_CLI;
7614 curproxy->fe_rsp_ana |= AN_RES_WAIT_CLI;
7615 }
7616
Willy Tarreauc1a21672009-08-16 22:37:44 +02007617 /* both TCP and HTTP must check switching rules */
7618 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
Christopher Fauletd7c91962015-04-30 11:48:27 +02007619
7620 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01007621 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01007622 curproxy->fe_req_ana |= AN_REQ_FLT_START_FE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
7623 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 +01007624 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01007625 curproxy->fe_req_ana |= AN_REQ_FLT_HTTP_HDRS;
7626 curproxy->fe_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01007627 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02007628 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02007629 }
7630
7631 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaufb356202010-08-03 14:02:05 +02007632 if (curproxy->tcp_req.inspect_delay ||
7633 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
7634 curproxy->be_req_ana |= AN_REQ_INSPECT_BE;
7635
Emeric Brun97679e72010-09-23 17:56:44 +02007636 if (!LIST_ISEMPTY(&curproxy->tcp_rep.inspect_rules))
7637 curproxy->be_rsp_ana |= AN_RES_INSPECT;
7638
Willy Tarreau4e5b8282009-08-16 22:57:50 +02007639 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02007640 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02007641 curproxy->be_rsp_ana |= AN_RES_WAIT_HTTP | AN_RES_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02007642 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02007643
7644 /* If the backend does requires RDP cookie persistence, we have to
7645 * enable the corresponding analyser.
7646 */
7647 if (curproxy->options2 & PR_O2_RDPC_PRST)
7648 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
Christopher Fauletd7c91962015-04-30 11:48:27 +02007649
7650 /* Add filters analyzers if needed */
Christopher Faulet443ea1a2016-02-04 13:40:26 +01007651 if (!LIST_ISEMPTY(&curproxy->filter_configs)) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01007652 curproxy->be_req_ana |= AN_REQ_FLT_START_BE | AN_REQ_FLT_XFER_DATA | AN_REQ_FLT_END;
7653 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 +01007654 if (curproxy->mode == PR_MODE_HTTP) {
Christopher Faulet0184ea72017-01-05 14:06:34 +01007655 curproxy->be_req_ana |= AN_REQ_FLT_HTTP_HDRS;
7656 curproxy->be_rsp_ana |= AN_RES_FLT_HTTP_HDRS;
Christopher Faulet309c6412015-12-02 09:57:32 +01007657 }
Christopher Fauletd7c91962015-04-30 11:48:27 +02007658 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02007659 }
Christopher Fauleta717b992018-04-10 14:43:00 +02007660
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02007661 /* Check the mux protocols, if any, for each listener and server
Christopher Fauleta717b992018-04-10 14:43:00 +02007662 * attached to the current proxy */
7663 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7664 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
7665
7666 if (!bind_conf->mux_proto)
7667 continue;
7668 if (!(bind_conf->mux_proto->mode & mode)) {
7669 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n",
7670 proxy_type_str(curproxy), curproxy->id,
7671 (int)bind_conf->mux_proto->token.len,
7672 bind_conf->mux_proto->token.ptr,
7673 bind_conf->arg, bind_conf->file, bind_conf->line);
7674 cfgerr++;
7675 }
7676 }
Christopher Faulet8ed0a3e2018-04-10 14:45:45 +02007677 for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
7678 int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
7679
7680 if (!newsrv->mux_proto)
7681 continue;
7682 if (!(newsrv->mux_proto->mode & mode)) {
7683 ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n",
7684 proxy_type_str(curproxy), curproxy->id,
7685 (int)newsrv->mux_proto->token.len,
7686 newsrv->mux_proto->token.ptr,
7687 newsrv->id, newsrv->conf.file, newsrv->conf.line);
7688 cfgerr++;
7689 }
7690 }
Willy Tarreau419ead82014-09-16 13:41:21 +02007691 }
7692
7693 /***********************************************************/
7694 /* At this point, target names have already been resolved. */
7695 /***********************************************************/
7696
7697 /* Check multi-process mode compatibility */
7698
7699 if (global.nbproc > 1 && global.stats_fe) {
7700 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
7701 unsigned long mask;
7702
7703 mask = nbits(global.nbproc);
7704 if (global.stats_fe->bind_proc)
7705 mask &= global.stats_fe->bind_proc;
7706
7707 if (bind_conf->bind_proc)
7708 mask &= bind_conf->bind_proc;
7709
7710 /* stop here if more than one process is used */
Willy Tarreau9504dd62018-10-15 09:37:03 +02007711 if (atleast2(mask))
Willy Tarreau419ead82014-09-16 13:41:21 +02007712 break;
7713 }
7714 if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007715 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 +02007716 }
7717 }
7718
7719 /* Make each frontend inherit bind-process from its listeners when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007720 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02007721 if (curproxy->bind_proc)
7722 continue;
7723
7724 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
7725 unsigned long mask;
7726
Willy Tarreaue428b082015-05-04 21:57:58 +02007727 mask = bind_conf->bind_proc ? bind_conf->bind_proc : nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02007728 curproxy->bind_proc |= mask;
7729 }
7730
7731 if (!curproxy->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02007732 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02007733 }
7734
7735 if (global.stats_fe) {
7736 list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
7737 unsigned long mask;
7738
Cyril Bonté06181952016-02-24 00:14:54 +01007739 mask = bind_conf->bind_proc ? bind_conf->bind_proc : 0;
Willy Tarreau419ead82014-09-16 13:41:21 +02007740 global.stats_fe->bind_proc |= mask;
7741 }
7742 if (!global.stats_fe->bind_proc)
Willy Tarreaue428b082015-05-04 21:57:58 +02007743 global.stats_fe->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02007744 }
7745
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02007746 /* propagate bindings from frontends to backends. Don't do it if there
7747 * are any fatal errors as we must not call it with unresolved proxies.
7748 */
7749 if (!cfgerr) {
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007750 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreauacbe8ab2014-10-01 20:50:17 +02007751 if (curproxy->cap & PR_CAP_FE)
7752 propagate_processes(curproxy, NULL);
7753 }
Willy Tarreau419ead82014-09-16 13:41:21 +02007754 }
7755
7756 /* Bind each unbound backend to all processes when not specified. */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007757 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02007758 if (curproxy->bind_proc)
7759 continue;
Willy Tarreaue428b082015-05-04 21:57:58 +02007760 curproxy->bind_proc = nbits(global.nbproc);
Willy Tarreau419ead82014-09-16 13:41:21 +02007761 }
7762
7763 /*******************************************************/
7764 /* At this step, all proxies have a non-null bind_proc */
7765 /*******************************************************/
7766
7767 /* perform the final checks before creating tasks */
7768
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007769 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau419ead82014-09-16 13:41:21 +02007770 struct listener *listener;
7771 unsigned int next_id;
Willy Tarreauc1a21672009-08-16 22:37:44 +02007772
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02007773 /* Configure SSL for each bind line.
7774 * Note: if configuration fails at some point, the ->ctx member
7775 * remains NULL so that listeners can later detach.
7776 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007777 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau55d37912016-12-21 23:38:39 +01007778 if (bind_conf->xprt->prepare_bind_conf &&
7779 bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02007780 cfgerr++;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007781 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02007782
Willy Tarreaue6b98942007-10-29 01:09:36 +01007783 /* adjust this proxy's listeners */
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007784 next_id = 1;
Willy Tarreau4348fad2012-09-20 16:48:07 +02007785 list_for_each_entry(listener, &curproxy->conf.listeners, by_fe) {
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02007786 int nbproc;
7787
7788 nbproc = my_popcountl(curproxy->bind_proc &
Cyril Bonté4920d702016-04-15 07:58:43 +02007789 (listener->bind_conf->bind_proc ? listener->bind_conf->bind_proc : curproxy->bind_proc) &
Willy Tarreau7c0ffd22016-04-14 11:47:38 +02007790 nbits(global.nbproc));
7791
7792 if (!nbproc) /* no intersection between listener and frontend */
7793 nbproc = 1;
7794
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007795 if (!listener->luid) {
7796 /* listener ID not set, use automatic numbering with first
7797 * spare entry starting with next_luid.
7798 */
7799 next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
7800 listener->conf.id.key = listener->luid = next_id;
7801 eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007802 }
Krzysztof Piotr Oledzkidf5cb9f2010-02-05 20:58:27 +01007803 next_id++;
Willy Tarreau53fb4ae2009-10-04 23:04:08 +02007804
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02007805 /* enable separate counters */
7806 if (curproxy->options2 & PR_O2_SOCKSTAT) {
Willy Tarreauae9bea02016-11-25 14:44:52 +01007807 listener->counters = calloc(1, sizeof(*listener->counters));
Willy Tarreau19d14ef2012-10-29 16:51:55 +01007808 if (!listener->name)
7809 memprintf(&listener->name, "sock-%d", listener->luid);
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02007810 }
Willy Tarreau81796be2012-09-22 19:11:47 +02007811
Willy Tarreaue6b98942007-10-29 01:09:36 +01007812 if (curproxy->options & PR_O_TCP_NOLING)
7813 listener->options |= LI_O_NOLINGER;
Willy Tarreau32368ce2012-09-06 11:10:55 +02007814 if (!listener->maxconn)
7815 listener->maxconn = curproxy->maxconn;
7816 if (!listener->backlog)
7817 listener->backlog = curproxy->backlog;
Willy Tarreau16a21472012-11-19 12:39:59 +01007818 if (!listener->maxaccept)
7819 listener->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
7820
7821 /* we want to have an optimal behaviour on single process mode to
7822 * maximize the work at once, but in multi-process we want to keep
7823 * some fairness between processes, so we target half of the max
7824 * number of events to be balanced over all the processes the proxy
7825 * is bound to. Rememeber that maxaccept = -1 must be kept as it is
7826 * used to disable the limit.
7827 */
7828 if (listener->maxaccept > 0) {
7829 if (nbproc > 1)
7830 listener->maxaccept = (listener->maxaccept + 1) / 2;
7831 listener->maxaccept = (listener->maxaccept + nbproc - 1) / nbproc;
7832 }
7833
Willy Tarreau9903f0e2015-04-04 18:50:31 +02007834 listener->accept = session_accept_fd;
Willy Tarreauc1a21672009-08-16 22:37:44 +02007835 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau10b688f2015-03-13 16:43:12 +01007836 listener->default_target = curproxy->default_target;
Willy Tarreau3bc13772008-12-07 11:50:35 +01007837
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02007838 if (!LIST_ISEMPTY(&curproxy->tcp_req.l4_rules))
Willy Tarreau7d9736f2016-10-21 16:34:21 +02007839 listener->options |= LI_O_TCP_L4_RULES;
Willy Tarreaua5c0ab22010-05-31 10:30:33 +02007840
Willy Tarreau620408f2016-10-21 16:37:51 +02007841 if (!LIST_ISEMPTY(&curproxy->tcp_req.l5_rules))
7842 listener->options |= LI_O_TCP_L5_RULES;
7843
Willy Tarreaude3041d2010-05-31 10:56:17 +02007844 if (curproxy->mon_mask.s_addr)
7845 listener->options |= LI_O_CHK_MONNET;
7846
Willy Tarreau9ea05a72009-06-14 12:07:01 +02007847 /* smart accept mode is automatic in HTTP mode */
7848 if ((curproxy->options2 & PR_O2_SMARTACC) ||
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007849 ((curproxy->mode == PR_MODE_HTTP || listener->bind_conf->is_ssl) &&
Willy Tarreau9ea05a72009-06-14 12:07:01 +02007850 !(curproxy->no_options2 & PR_O2_SMARTACC)))
7851 listener->options |= LI_O_NOQUICKACK;
Willy Tarreaue6b98942007-10-29 01:09:36 +01007852 }
7853
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007854 /* Release unused SSL configs */
7855 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
Willy Tarreau795cdab2016-12-22 17:30:54 +01007856 if (!bind_conf->is_ssl && bind_conf->xprt->destroy_bind_conf)
7857 bind_conf->xprt->destroy_bind_conf(bind_conf);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02007858 }
Willy Tarreauf5ae8f72012-09-07 16:58:00 +02007859
Willy Tarreau9504dd62018-10-15 09:37:03 +02007860 if (atleast2(curproxy->bind_proc & nbits(global.nbproc))) {
Willy Tarreau102df612014-05-07 23:56:38 +02007861 if (curproxy->uri_auth) {
Willy Tarreaueb791e02014-09-16 15:11:04 +02007862 int count, maxproc = 0;
7863
7864 list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
David Carliere6c39412015-07-02 07:00:17 +00007865 count = my_popcountl(bind_conf->bind_proc);
Willy Tarreaueb791e02014-09-16 15:11:04 +02007866 if (count > maxproc)
7867 maxproc = count;
7868 }
7869 /* backends have 0, frontends have 1 or more */
7870 if (maxproc != 1)
Christopher Faulet767a84b2017-11-24 16:50:31 +01007871 ha_warning("Proxy '%s': in multi-process mode, stats will be"
7872 " limited to process assigned to the current request.\n",
7873 curproxy->id);
Willy Tarreaueb791e02014-09-16 15:11:04 +02007874
Willy Tarreau102df612014-05-07 23:56:38 +02007875 if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007876 ha_warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
7877 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01007878 }
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01007879 }
Willy Tarreau102df612014-05-07 23:56:38 +02007880 if (!LIST_ISEMPTY(&curproxy->sticking_rules)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007881 ha_warning("Proxy '%s': sticking rules will not work correctly in multi-process mode.\n",
7882 curproxy->id);
Cyril Bonté02ff8ef2010-12-14 22:48:49 +01007883 }
7884 }
Willy Tarreau918ff602011-07-25 16:33:49 +02007885
7886 /* create the task associated with the proxy */
Emeric Brunc60def82017-09-27 14:59:38 +02007887 curproxy->task = task_new(MAX_THREADS_MASK);
Willy Tarreau918ff602011-07-25 16:33:49 +02007888 if (curproxy->task) {
7889 curproxy->task->context = curproxy;
7890 curproxy->task->process = manage_proxy;
Willy Tarreau918ff602011-07-25 16:33:49 +02007891 } else {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007892 ha_alert("Proxy '%s': no more memory when trying to allocate the management task\n",
7893 curproxy->id);
Willy Tarreau918ff602011-07-25 16:33:49 +02007894 cfgerr++;
7895 }
Willy Tarreaub369a042014-09-16 13:21:03 +02007896 }
7897
Willy Tarreaufbb78422011-06-05 15:38:35 +02007898 /* automatically compute fullconn if not set. We must not do it in the
7899 * loop above because cross-references are not yet fully resolved.
7900 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007901 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02007902 /* If <fullconn> is not set, let's set it to 10% of the sum of
7903 * the possible incoming frontend's maxconns.
7904 */
7905 if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
Willy Tarreaufbb78422011-06-05 15:38:35 +02007906 /* we have the sum of the maxconns in <total>. We only
7907 * keep 10% of that sum to set the default fullconn, with
7908 * a hard minimum of 1 (to avoid a divide by zero).
7909 */
Emeric Brun3f783572017-01-12 11:21:28 +01007910 curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
Willy Tarreaufbb78422011-06-05 15:38:35 +02007911 if (!curproxy->fullconn)
7912 curproxy->fullconn = 1;
7913 }
Krzysztof Piotr Oledzki96105042010-01-29 17:50:44 +01007914 }
7915
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007916 /*
7917 * Recount currently required checks.
7918 */
7919
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007920 for (curproxy=proxies_list; curproxy; curproxy=curproxy->next) {
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007921 int optnum;
7922
Willy Tarreau66aa61f2009-01-18 21:44:07 +01007923 for (optnum = 0; cfg_opts[optnum].name; optnum++)
7924 if (curproxy->options & cfg_opts[optnum].val)
7925 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007926
Willy Tarreau66aa61f2009-01-18 21:44:07 +01007927 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
7928 if (curproxy->options2 & cfg_opts2[optnum].val)
7929 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01007930 }
7931
Willy Tarreau0fca4832015-05-01 19:12:05 +02007932 /* compute the required process bindings for the peers */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01007933 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next)
Willy Tarreau0fca4832015-05-01 19:12:05 +02007934 if (curproxy->table.peers.p)
7935 curproxy->table.peers.p->peers_fe->bind_proc |= curproxy->bind_proc;
7936
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02007937 if (cfg_peers) {
7938 struct peers *curpeers = cfg_peers, **last;
Willy Tarreau122541c2011-09-07 21:24:49 +02007939 struct peer *p, *pb;
7940
Willy Tarreau1e273012015-05-01 19:15:17 +02007941 /* Remove all peers sections which don't have a valid listener,
7942 * which are not used by any table, or which are bound to more
7943 * than one process.
Willy Tarreau122541c2011-09-07 21:24:49 +02007944 */
Frédéric Lécailleed2b4a62017-07-13 09:07:09 +02007945 last = &cfg_peers;
Willy Tarreau122541c2011-09-07 21:24:49 +02007946 while (*last) {
7947 curpeers = *last;
Willy Tarreau77e4bd12015-05-01 20:02:17 +02007948
7949 if (curpeers->state == PR_STSTOPPED) {
7950 /* the "disabled" keyword was present */
7951 if (curpeers->peers_fe)
7952 stop_proxy(curpeers->peers_fe);
7953 curpeers->peers_fe = NULL;
7954 }
7955 else if (!curpeers->peers_fe) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007956 ha_warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
7957 curpeers->id, localpeer);
Willy Tarreau77e4bd12015-05-01 20:02:17 +02007958 }
Willy Tarreau9504dd62018-10-15 09:37:03 +02007959 else if (atleast2(curpeers->peers_fe->bind_proc)) {
Willy Tarreau1e273012015-05-01 19:15:17 +02007960 /* either it's totally stopped or too much used */
7961 if (curpeers->peers_fe->bind_proc) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01007962 ha_alert("Peers section '%s': peers referenced by sections "
7963 "running in different processes (%d different ones). "
7964 "Check global.nbproc and all tables' bind-process "
7965 "settings.\n", curpeers->id, my_popcountl(curpeers->peers_fe->bind_proc));
Willy Tarreau1e273012015-05-01 19:15:17 +02007966 cfgerr++;
7967 }
7968 stop_proxy(curpeers->peers_fe);
7969 curpeers->peers_fe = NULL;
7970 }
Willy Tarreau77e4bd12015-05-01 20:02:17 +02007971 else {
Willy Tarreaud9443442018-10-15 11:18:03 +02007972 if (!peers_init_sync(curpeers)) {
7973 ha_alert("Peers section '%s': out of memory, giving up on peers.\n",
7974 curpeers->id);
7975 cfgerr++;
7976 break;
7977 }
Willy Tarreau122541c2011-09-07 21:24:49 +02007978 last = &curpeers->next;
7979 continue;
7980 }
7981
Willy Tarreau77e4bd12015-05-01 20:02:17 +02007982 /* clean what has been detected above */
Willy Tarreau122541c2011-09-07 21:24:49 +02007983 p = curpeers->remote;
7984 while (p) {
7985 pb = p->next;
7986 free(p->id);
7987 free(p);
7988 p = pb;
7989 }
7990
7991 /* Destroy and unlink this curpeers section.
7992 * Note: curpeers is backed up into *last.
7993 */
7994 free(curpeers->id);
7995 curpeers = curpeers->next;
7996 free(*last);
7997 *last = curpeers;
7998 }
7999 }
8000
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008001 /* initialize stick-tables on backend capable proxies. This must not
8002 * be done earlier because the data size may be discovered while parsing
8003 * other proxies.
8004 */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008005 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008006 if (curproxy->state == PR_STSTOPPED)
8007 continue;
8008
8009 if (!stktable_init(&curproxy->table)) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008010 ha_alert("Proxy '%s': failed to initialize stick-table.\n", curproxy->id);
Willy Tarreau6866f3f2015-05-01 19:09:08 +02008011 cfgerr++;
8012 }
8013 }
8014
Simon Horman0d16a402015-01-30 11:22:58 +09008015 if (mailers) {
8016 struct mailers *curmailers = mailers, **last;
8017 struct mailer *m, *mb;
8018
8019 /* Remove all mailers sections which don't have a valid listener.
8020 * This can happen when a mailers section is never referenced.
8021 */
8022 last = &mailers;
8023 while (*last) {
8024 curmailers = *last;
8025 if (curmailers->users) {
8026 last = &curmailers->next;
8027 continue;
8028 }
8029
Christopher Faulet767a84b2017-11-24 16:50:31 +01008030 ha_warning("Removing incomplete section 'mailers %s'.\n",
8031 curmailers->id);
Simon Horman0d16a402015-01-30 11:22:58 +09008032
8033 m = curmailers->mailer_list;
8034 while (m) {
8035 mb = m->next;
8036 free(m->id);
8037 free(m);
8038 m = mb;
8039 }
8040
8041 /* Destroy and unlink this curmailers section.
8042 * Note: curmailers is backed up into *last.
8043 */
8044 free(curmailers->id);
8045 curmailers = curmailers->next;
8046 free(*last);
8047 *last = curmailers;
8048 }
8049 }
8050
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008051 /* Update server_state_file_name to backend name if backend is supposed to use
8052 * a server-state file locally defined and none has been provided */
Olivier Houchardfbc74e82017-11-24 16:54:05 +01008053 for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
Baptiste Assmanne11cfcd2015-08-19 16:44:03 +02008054 if (curproxy->load_server_state_from_file == PR_SRV_STATE_FILE_LOCAL &&
8055 curproxy->server_state_file_name == NULL)
8056 curproxy->server_state_file_name = strdup(curproxy->id);
8057 }
8058
Willy Tarreaubafbe012017-11-24 17:34:44 +01008059 pool_head_hdr_idx = create_pool("hdr_idx",
Willy Tarreauac1932d2011-10-24 19:14:41 +02008060 global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
Willy Tarreau34eb6712011-10-24 18:15:04 +02008061 MEM_F_SHARED);
8062
Ben Draut054fbee2018-04-13 15:43:04 -06008063 list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
8064 if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
8065 ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",
8066 curr_resolvers->id, curr_resolvers->conf.file,
8067 curr_resolvers->conf.line);
8068 err_code |= ERR_WARN;
8069 }
8070 }
8071
William Lallemand48b4bb42017-10-23 14:36:34 +02008072 list_for_each_entry(postparser, &postparsers, list) {
8073 if (postparser->func)
8074 cfgerr += postparser->func();
8075 }
8076
Willy Tarreaubb925012009-07-23 13:36:36 +02008077 if (cfgerr > 0)
8078 err_code |= ERR_ALERT | ERR_FATAL;
8079 out:
8080 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02008081}
8082
Willy Tarreau5b2c3362008-07-09 19:39:06 +02008083/*
8084 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
8085 * parsing sessions.
8086 */
8087void cfg_register_keywords(struct cfg_kw_list *kwl)
8088{
8089 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
8090}
Willy Tarreaubaaee002006-06-26 02:48:02 +02008091
Willy Tarreau5b2c3362008-07-09 19:39:06 +02008092/*
8093 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
8094 */
8095void cfg_unregister_keywords(struct cfg_kw_list *kwl)
8096{
8097 LIST_DEL(&kwl->list);
8098 LIST_INIT(&kwl->list);
8099}
Willy Tarreaubaaee002006-06-26 02:48:02 +02008100
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01008101/* this function register new section in the haproxy configuration file.
8102 * <section_name> is the name of this new section and <section_parser>
8103 * is the called parser. If two section declaration have the same name,
8104 * only the first declared is used.
8105 */
8106int cfg_register_section(char *section_name,
William Lallemandd2ff56d2017-10-16 11:06:50 +02008107 int (*section_parser)(const char *, int, char **, int),
8108 int (*post_section_parser)())
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01008109{
8110 struct cfg_section *cs;
8111
Willy Tarreau5e4261b2016-05-17 16:16:09 +02008112 list_for_each_entry(cs, &sections, list) {
8113 if (strcmp(cs->section_name, section_name) == 0) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008114 ha_alert("register section '%s': already registered.\n", section_name);
Willy Tarreau5e4261b2016-05-17 16:16:09 +02008115 return 0;
8116 }
8117 }
8118
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01008119 cs = calloc(1, sizeof(*cs));
8120 if (!cs) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008121 ha_alert("register section '%s': out of memory.\n", section_name);
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01008122 return 0;
8123 }
8124
8125 cs->section_name = section_name;
8126 cs->section_parser = section_parser;
William Lallemandd2ff56d2017-10-16 11:06:50 +02008127 cs->post_section_parser = post_section_parser;
Thierry FOURNIERfa45f1d2014-03-18 13:54:18 +01008128
8129 LIST_ADDQ(&sections, &cs->list);
8130
8131 return 1;
8132}
8133
William Lallemand48b4bb42017-10-23 14:36:34 +02008134/* this function register a new function which will be called once the haproxy
8135 * configuration file has been parsed. It's useful to check dependencies
8136 * between sections or to resolve items once everything is parsed.
8137 */
8138int cfg_register_postparser(char *name, int (*func)())
8139{
8140 struct cfg_postparser *cp;
8141
8142 cp = calloc(1, sizeof(*cp));
8143 if (!cp) {
Christopher Faulet767a84b2017-11-24 16:50:31 +01008144 ha_alert("register postparser '%s': out of memory.\n", name);
William Lallemand48b4bb42017-10-23 14:36:34 +02008145 return 0;
8146 }
8147 cp->name = name;
8148 cp->func = func;
8149
8150 LIST_ADDQ(&postparsers, &cp->list);
8151
8152 return 1;
8153}
8154
Willy Tarreaubaaee002006-06-26 02:48:02 +02008155/*
David Carlier845efb52015-09-25 11:49:18 +01008156 * free all config section entries
8157 */
8158void cfg_unregister_sections(void)
8159{
8160 struct cfg_section *cs, *ics;
8161
8162 list_for_each_entry_safe(cs, ics, &sections, list) {
8163 LIST_DEL(&cs->list);
8164 free(cs);
8165 }
8166}
8167
Christopher Faulet7110b402016-10-26 11:09:44 +02008168void cfg_backup_sections(struct list *backup_sections)
8169{
8170 struct cfg_section *cs, *ics;
8171
8172 list_for_each_entry_safe(cs, ics, &sections, list) {
8173 LIST_DEL(&cs->list);
8174 LIST_ADDQ(backup_sections, &cs->list);
8175 }
8176}
8177
8178void cfg_restore_sections(struct list *backup_sections)
8179{
8180 struct cfg_section *cs, *ics;
8181
8182 list_for_each_entry_safe(cs, ics, backup_sections, list) {
8183 LIST_DEL(&cs->list);
8184 LIST_ADDQ(&sections, &cs->list);
8185 }
8186}
8187
Willy Tarreau659fbf02016-05-26 17:55:28 +02008188__attribute__((constructor))
8189static void cfgparse_init(void)
8190{
8191 /* Register internal sections */
William Lallemandd2ff56d2017-10-16 11:06:50 +02008192 cfg_register_section("listen", cfg_parse_listen, NULL);
8193 cfg_register_section("frontend", cfg_parse_listen, NULL);
8194 cfg_register_section("backend", cfg_parse_listen, NULL);
8195 cfg_register_section("defaults", cfg_parse_listen, NULL);
8196 cfg_register_section("global", cfg_parse_global, NULL);
8197 cfg_register_section("userlist", cfg_parse_users, NULL);
8198 cfg_register_section("peers", cfg_parse_peers, NULL);
8199 cfg_register_section("mailers", cfg_parse_mailers, NULL);
8200 cfg_register_section("namespace_list", cfg_parse_netns, NULL);
8201 cfg_register_section("resolvers", cfg_parse_resolvers, NULL);
Willy Tarreau659fbf02016-05-26 17:55:28 +02008202}
8203
David Carlier845efb52015-09-25 11:49:18 +01008204/*
Willy Tarreaubaaee002006-06-26 02:48:02 +02008205 * Local variables:
8206 * c-indent-level: 8
8207 * c-basic-offset: 8
8208 * End:
8209 */