blob: ebb07139846a1bae9f6292f8b1faf68c63110ce7 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Configuration parser
3 *
Willy Tarreau7c669d72008-06-20 15:04:11 +02004 * Copyright 2000-2008 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
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <netdb.h>
17#include <ctype.h>
Willy Tarreau95c20ac2007-03-25 15:39:23 +020018#include <pwd.h>
19#include <grp.h>
Willy Tarreau0b4ed902007-03-26 00:18:40 +020020#include <errno.h>
Willy Tarreau3f49b302007-06-11 00:29:26 +020021#include <sys/types.h>
22#include <sys/stat.h>
23#include <fcntl.h>
24#include <unistd.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020025
Willy Tarreaube1b9182009-06-14 18:48:19 +020026#include <netinet/tcp.h>
27
Willy Tarreau2dd0d472006-06-29 17:53:05 +020028#include <common/cfgparse.h>
29#include <common/config.h>
Willy Tarreau058e9072009-07-20 09:30:05 +020030#include <common/errors.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020031#include <common/memory.h>
32#include <common/standard.h>
33#include <common/time.h>
34#include <common/uri_auth.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035
36#include <types/capture.h>
37#include <types/global.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020038
Willy Tarreaueb0c6142007-05-07 00:53:22 +020039#include <proto/acl.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020040#include <proto/backend.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010041#include <proto/buffers.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020042#include <proto/checks.h>
Willy Tarreaufbee7132007-10-18 13:53:22 +020043#include <proto/dumpstats.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010044#include <proto/httperr.h>
Willy Tarreauf89c1872009-10-01 11:19:37 +020045#include <proto/lb_fwlc.h>
46#include <proto/lb_fwrr.h>
47#include <proto/lb_map.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020048#include <proto/log.h>
Willy Tarreauc6f4ce82009-06-10 11:09:37 +020049#include <proto/port_range.h>
Willy Tarreaue6b98942007-10-29 01:09:36 +010050#include <proto/protocols.h>
51#include <proto/proto_tcp.h>
52#include <proto/proto_http.h>
Willy Tarreau2b5652f2006-12-31 17:46:05 +010053#include <proto/proxy.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020054#include <proto/server.h>
Willy Tarreau3bc13772008-12-07 11:50:35 +010055#include <proto/session.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020056#include <proto/task.h>
57
58
Willy Tarreauf3c69202006-07-09 16:42:34 +020059/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
60 * ssl-hello-chk option to ensure that the remote server speaks SSL.
61 *
62 * Check RFC 2246 (TLSv1.0) sections A.3 and A.4 for details.
63 */
64const char sslv3_client_hello_pkt[] = {
65 "\x16" /* ContentType : 0x16 = Hanshake */
66 "\x03\x00" /* ProtocolVersion : 0x0300 = SSLv3 */
67 "\x00\x79" /* ContentLength : 0x79 bytes after this one */
68 "\x01" /* HanshakeType : 0x01 = CLIENT HELLO */
69 "\x00\x00\x75" /* HandshakeLength : 0x75 bytes after this one */
70 "\x03\x00" /* Hello Version : 0x0300 = v3 */
71 "\x00\x00\x00\x00" /* Unix GMT Time (s) : filled with <now> (@0x0B) */
72 "HAPROXYSSLCHK\nHAPROXYSSLCHK\n" /* Random : must be exactly 28 bytes */
73 "\x00" /* Session ID length : empty (no session ID) */
74 "\x00\x4E" /* Cipher Suite Length : 78 bytes after this one */
75 "\x00\x01" "\x00\x02" "\x00\x03" "\x00\x04" /* 39 most common ciphers : */
76 "\x00\x05" "\x00\x06" "\x00\x07" "\x00\x08" /* 0x01...0x1B, 0x2F...0x3A */
77 "\x00\x09" "\x00\x0A" "\x00\x0B" "\x00\x0C" /* This covers RSA/DH, */
78 "\x00\x0D" "\x00\x0E" "\x00\x0F" "\x00\x10" /* various bit lengths, */
79 "\x00\x11" "\x00\x12" "\x00\x13" "\x00\x14" /* SHA1/MD5, DES/3DES/AES... */
80 "\x00\x15" "\x00\x16" "\x00\x17" "\x00\x18"
81 "\x00\x19" "\x00\x1A" "\x00\x1B" "\x00\x2F"
82 "\x00\x30" "\x00\x31" "\x00\x32" "\x00\x33"
83 "\x00\x34" "\x00\x35" "\x00\x36" "\x00\x37"
84 "\x00\x38" "\x00\x39" "\x00\x3A"
85 "\x01" /* Compression Length : 0x01 = 1 byte for types */
86 "\x00" /* Compression Type : 0x00 = NULL compression */
87};
88
Willy Tarreau3842f002009-06-14 11:39:52 +020089/* various keyword modifiers */
90enum kw_mod {
91 KWM_STD = 0, /* normal */
92 KWM_NO, /* "no" prefixed before the keyword */
93 KWM_DEF, /* "default" prefixed before the keyword */
94};
95
Willy Tarreau13943ab2006-12-31 00:24:10 +010096/* some of the most common options which are also the easiest to handle */
Willy Tarreau66aa61f2009-01-18 21:44:07 +010097struct cfg_opt {
Willy Tarreau13943ab2006-12-31 00:24:10 +010098 const char *name;
99 unsigned int val;
100 unsigned int cap;
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100101 unsigned int checks;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100102};
103
104/* proxy->options */
105static const struct cfg_opt cfg_opts[] =
Willy Tarreau13943ab2006-12-31 00:24:10 +0100106{
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100107 { "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100108 { "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0 },
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100109 { "checkcache", PR_O_CHK_CACHE, PR_CAP_BE, 0 },
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100110 { "clitcpka", PR_O_TCP_CLI_KA, PR_CAP_FE, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100111 { "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0 },
112 { "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0 },
113 { "forceclose", PR_O_FORCE_CLO, PR_CAP_BE, 0 },
114 { "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0 },
115 { "httpclose", PR_O_HTTP_CLOSE, PR_CAP_FE | PR_CAP_BE, 0 },
116 { "keepalive", PR_O_KEEPALIVE, PR_CAP_NONE, 0 },
117 { "logasap", PR_O_LOGASAP, PR_CAP_FE, 0 },
118 { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0 },
Willy Tarreau4fee4e92007-01-06 21:09:17 +0100119 { "persist", PR_O_PERSIST, PR_CAP_BE, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100120 { "redispatch", PR_O_REDISP, PR_CAP_BE, 0 },
121 { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0 },
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100122#ifdef TPROXY
Willy Tarreau4b1f8592008-12-23 23:13:55 +0100123 { "transparent", PR_O_TRANSP, PR_CAP_BE, 0 },
Willy Tarreau8f922fc2007-01-06 21:11:49 +0100124#endif
125
Krzysztof Oledzki336d4752007-12-25 02:40:22 +0100126 { NULL, 0, 0, 0 }
Willy Tarreau13943ab2006-12-31 00:24:10 +0100127};
128
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100129/* proxy->options2 */
130static const struct cfg_opt cfg_opts2[] =
131{
132#ifdef CONFIG_HAP_LINUX_SPLICE
133 { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0 },
134 { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0 },
135 { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0 },
136#endif
Willy Tarreau32a4ec02009-04-02 11:35:18 +0200137 { "accept-invalid-http-request", PR_O2_REQBUG_OK, PR_CAP_FE, 0 },
138 { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0 },
Willy Tarreauc9bd0cc2009-05-10 11:57:02 +0200139 { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0 },
140 { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0 },
Krzysztof Piotr Oledzki213014e2009-09-27 15:50:02 +0200141 { "log-health-checks", PR_O2_LOGHCHKS, PR_CAP_BE, 0 },
Willy Tarreau9ea05a72009-06-14 12:07:01 +0200142 { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0 },
Willy Tarreaud88edf22009-06-14 15:48:17 +0200143 { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0 },
Willy Tarreauf27b5ea2009-10-03 22:01:18 +0200144 { "independant-streams", PR_O2_INDEPSTR, PR_CAP_FE|PR_CAP_BE, 0 },
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100145 { NULL, 0, 0, 0 }
146};
Willy Tarreaubaaee002006-06-26 02:48:02 +0200147
Willy Tarreau6daf3432008-01-22 16:44:08 +0100148static char *cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200149static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
150int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100151int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200152
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200153/* List head of all known configuration keywords */
154static struct cfg_kw_list cfg_keywords = {
155 .list = LIST_HEAD_INIT(cfg_keywords.list)
156};
157
Willy Tarreaubaaee002006-06-26 02:48:02 +0200158/*
159 * converts <str> to a list of listeners which are dynamically allocated.
160 * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where :
161 * - <addr> can be empty or "*" to indicate INADDR_ANY ;
162 * - <port> is a numerical port from 1 to 65535 ;
163 * - <end> indicates to use the range from <port> to <end> instead (inclusive).
164 * This can be repeated as many times as necessary, separated by a coma.
165 * The <tail> argument is a pointer to a current list which should be appended
166 * to the tail of the new list. The pointer to the new list is returned.
167 */
168static struct listener *str2listener(char *str, struct listener *tail)
169{
170 struct listener *l;
171 char *c, *next, *range, *dupstr;
172 int port, end;
173
174 next = dupstr = strdup(str);
175
176 while (next && *next) {
177 struct sockaddr_storage ss;
178
179 str = next;
180 /* 1) look for the end of the first address */
Krzysztof Piotr Oledzki52d522b2009-01-27 16:57:08 +0100181 if ((next = strchr(str, ',')) != NULL) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200182 *next++ = 0;
183 }
184
185 /* 2) look for the addr/port delimiter, it's the last colon. */
186 if ((range = strrchr(str, ':')) == NULL) {
187 Alert("Missing port number: '%s'\n", str);
188 goto fail;
189 }
190
191 *range++ = 0;
192
193 if (strrchr(str, ':') != NULL) {
194 /* IPv6 address contains ':' */
195 memset(&ss, 0, sizeof(ss));
196 ss.ss_family = AF_INET6;
197
198 if (!inet_pton(ss.ss_family, str, &((struct sockaddr_in6 *)&ss)->sin6_addr)) {
199 Alert("Invalid server address: '%s'\n", str);
200 goto fail;
201 }
202 }
203 else {
204 memset(&ss, 0, sizeof(ss));
205 ss.ss_family = AF_INET;
206
207 if (*str == '*' || *str == '\0') { /* INADDR_ANY */
208 ((struct sockaddr_in *)&ss)->sin_addr.s_addr = INADDR_ANY;
209 }
210 else if (!inet_pton(ss.ss_family, str, &((struct sockaddr_in *)&ss)->sin_addr)) {
211 struct hostent *he;
212
213 if ((he = gethostbyname(str)) == NULL) {
214 Alert("Invalid server name: '%s'\n", str);
215 goto fail;
216 }
217 else
218 ((struct sockaddr_in *)&ss)->sin_addr =
219 *(struct in_addr *) *(he->h_addr_list);
220 }
221 }
222
223 /* 3) look for the port-end delimiter */
224 if ((c = strchr(range, '-')) != NULL) {
225 *c++ = 0;
226 end = atol(c);
227 }
228 else {
229 end = atol(range);
230 }
231
232 port = atol(range);
233
234 if (port < 1 || port > 65535) {
235 Alert("Invalid port '%d' specified for address '%s'.\n", port, str);
236 goto fail;
237 }
238
239 if (end < 1 || end > 65535) {
240 Alert("Invalid port '%d' specified for address '%s'.\n", end, str);
241 goto fail;
242 }
243
244 for (; port <= end; port++) {
245 l = (struct listener *)calloc(1, sizeof(struct listener));
246 l->next = tail;
247 tail = l;
248
249 l->fd = -1;
250 l->addr = ss;
Willy Tarreaue6b98942007-10-29 01:09:36 +0100251 l->state = LI_INIT;
252
253 if (ss.ss_family == AF_INET6) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200254 ((struct sockaddr_in6 *)(&l->addr))->sin6_port = htons(port);
Willy Tarreaue6b98942007-10-29 01:09:36 +0100255 tcpv6_add_listener(l);
256 } else {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200257 ((struct sockaddr_in *)(&l->addr))->sin_port = htons(port);
Willy Tarreaue6b98942007-10-29 01:09:36 +0100258 tcpv4_add_listener(l);
259 }
260 listeners++;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200261 } /* end for(port) */
262 } /* end while(next) */
263 free(dupstr);
264 return tail;
265 fail:
266 free(dupstr);
267 return NULL;
268}
269
Willy Tarreau977b8e42006-12-29 14:19:17 +0100270/*
271 * Sends a warning if proxy <proxy> does not have at least one of the
272 * capabilities in <cap>. An optionnal <hint> may be added at the end
273 * of the warning to help the user. Returns 1 if a warning was emitted
274 * or 0 if the condition is valid.
275 */
276int warnifnotcap(struct proxy *proxy, int cap, const char *file, int line, char *arg, char *hint)
277{
278 char *msg;
279
280 switch (cap) {
281 case PR_CAP_BE: msg = "no backend"; break;
282 case PR_CAP_FE: msg = "no frontend"; break;
283 case PR_CAP_RS: msg = "no ruleset"; break;
284 case PR_CAP_BE|PR_CAP_FE: msg = "neither frontend nor backend"; break;
285 default: msg = "not enough"; break;
286 }
287
288 if (!(proxy->cap & cap)) {
289 Warning("parsing [%s:%d] : '%s' ignored because %s '%s' has %s capability.%s\n",
Willy Tarreau2b5652f2006-12-31 17:46:05 +0100290 file, line, arg, proxy_type_str(proxy), proxy->id, msg, hint ? hint : "");
Willy Tarreau977b8e42006-12-29 14:19:17 +0100291 return 1;
292 }
293 return 0;
294}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200295
Willy Tarreau61d18892009-03-31 10:49:21 +0200296/* Report a warning if a rule is placed after a 'block' rule.
297 * Return 1 if the warning has been emitted, otherwise 0.
298 */
299int warnif_rule_after_block(struct proxy *proxy, const char *file, int line, char *arg)
300{
301 if (!LIST_ISEMPTY(&proxy->block_cond)) {
302 Warning("parsing [%s:%d] : a '%s' rule placed after a 'block' rule will still be processed before.\n",
303 file, line, arg);
304 return 1;
305 }
306 return 0;
307}
308
309/* Report a warning if a rule is placed after a reqrewrite rule.
310 * Return 1 if the warning has been emitted, otherwise 0.
311 */
312int warnif_rule_after_reqxxx(struct proxy *proxy, const char *file, int line, char *arg)
313{
314 if (proxy->req_exp) {
315 Warning("parsing [%s:%d] : a '%s' rule placed after a 'reqxxx' rule will still be processed before.\n",
316 file, line, arg);
317 return 1;
318 }
319 return 0;
320}
321
322/* Report a warning if a rule is placed after a reqadd rule.
323 * Return 1 if the warning has been emitted, otherwise 0.
324 */
325int warnif_rule_after_reqadd(struct proxy *proxy, const char *file, int line, char *arg)
326{
327 if (proxy->nb_reqadd) {
328 Warning("parsing [%s:%d] : a '%s' rule placed after a 'reqadd' rule will still be processed before.\n",
329 file, line, arg);
330 return 1;
331 }
332 return 0;
333}
334
335/* Report a warning if a rule is placed after a redirect rule.
336 * Return 1 if the warning has been emitted, otherwise 0.
337 */
338int warnif_rule_after_redirect(struct proxy *proxy, const char *file, int line, char *arg)
339{
340 if (!LIST_ISEMPTY(&proxy->redirect_rules)) {
341 Warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n",
342 file, line, arg);
343 return 1;
344 }
345 return 0;
346}
347
348/* Report a warning if a rule is placed after a 'use_backend' rule.
349 * Return 1 if the warning has been emitted, otherwise 0.
350 */
351int warnif_rule_after_use_backend(struct proxy *proxy, const char *file, int line, char *arg)
352{
353 if (!LIST_ISEMPTY(&proxy->switching_rules)) {
354 Warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n",
355 file, line, arg);
356 return 1;
357 }
358 return 0;
359}
360
361/* report a warning if a block rule is dangerously placed */
362int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, char *arg)
363{
364 return warnif_rule_after_reqxxx(proxy, file, line, arg) ||
365 warnif_rule_after_reqadd(proxy, file, line, arg) ||
366 warnif_rule_after_redirect(proxy, file, line, arg) ||
367 warnif_rule_after_use_backend(proxy, file, line, arg);
368}
369
370/* report a warning if a reqxxx rule is dangerously placed */
371int warnif_misplaced_reqxxx(struct proxy *proxy, const char *file, int line, char *arg)
372{
373 return warnif_rule_after_reqadd(proxy, file, line, arg) ||
374 warnif_rule_after_redirect(proxy, file, line, arg) ||
375 warnif_rule_after_use_backend(proxy, file, line, arg);
376}
377
378/* report a warning if a reqadd rule is dangerously placed */
379int warnif_misplaced_reqadd(struct proxy *proxy, const char *file, int line, char *arg)
380{
381 return warnif_rule_after_redirect(proxy, file, line, arg) ||
382 warnif_rule_after_use_backend(proxy, file, line, arg);
383}
384
Willy Tarreaubaaee002006-06-26 02:48:02 +0200385/*
Willy Tarreau058e9072009-07-20 09:30:05 +0200386 * parse a line in a <global> section. Returns the error code, 0 if OK, or
387 * any combination of :
388 * - ERR_ABORT: must abort ASAP
389 * - ERR_FATAL: we can continue parsing but not start the service
390 * - ERR_WARN: a warning has been emitted
391 * - ERR_ALERT: an alert has been emitted
392 * Only the two first ones can stop processing, the two others are just
393 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200394 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200395int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200396{
Willy Tarreau058e9072009-07-20 09:30:05 +0200397 int err_code = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200398
399 if (!strcmp(args[0], "global")) { /* new section */
400 /* no option, nothing special to do */
Willy Tarreau058e9072009-07-20 09:30:05 +0200401 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200402 }
403 else if (!strcmp(args[0], "daemon")) {
404 global.mode |= MODE_DAEMON;
405 }
406 else if (!strcmp(args[0], "debug")) {
407 global.mode |= MODE_DEBUG;
408 }
409 else if (!strcmp(args[0], "noepoll")) {
Willy Tarreau43b78992009-01-25 15:42:27 +0100410 global.tune.options &= ~GTUNE_USE_EPOLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200411 }
Willy Tarreaude99e992007-04-16 00:53:59 +0200412 else if (!strcmp(args[0], "nosepoll")) {
Willy Tarreau43b78992009-01-25 15:42:27 +0100413 global.tune.options &= ~GTUNE_USE_SEPOLL;
Willy Tarreaude99e992007-04-16 00:53:59 +0200414 }
415 else if (!strcmp(args[0], "nokqueue")) {
Willy Tarreau43b78992009-01-25 15:42:27 +0100416 global.tune.options &= ~GTUNE_USE_KQUEUE;
Willy Tarreaude99e992007-04-16 00:53:59 +0200417 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200418 else if (!strcmp(args[0], "nopoll")) {
Willy Tarreau43b78992009-01-25 15:42:27 +0100419 global.tune.options &= ~GTUNE_USE_POLL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200420 }
Willy Tarreau3ab68cf2009-01-25 16:03:28 +0100421 else if (!strcmp(args[0], "nosplice")) {
422 global.tune.options &= ~GTUNE_USE_SPLICE;
423 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200424 else if (!strcmp(args[0], "quiet")) {
425 global.mode |= MODE_QUIET;
426 }
Willy Tarreau1db37712007-06-03 17:16:49 +0200427 else if (!strcmp(args[0], "tune.maxpollevents")) {
428 if (global.tune.maxpollevents != 0) {
429 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200430 err_code |= ERR_ALERT;
431 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200432 }
433 if (*(args[1]) == 0) {
434 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200435 err_code |= ERR_ALERT | ERR_FATAL;
436 goto out;
Willy Tarreau1db37712007-06-03 17:16:49 +0200437 }
438 global.tune.maxpollevents = atol(args[1]);
439 }
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100440 else if (!strcmp(args[0], "tune.maxaccept")) {
441 if (global.tune.maxaccept != 0) {
442 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200443 err_code |= ERR_ALERT;
444 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100445 }
446 if (*(args[1]) == 0) {
447 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200448 err_code |= ERR_ALERT | ERR_FATAL;
449 goto out;
Willy Tarreaua0250ba2008-01-06 11:22:57 +0100450 }
451 global.tune.maxaccept = atol(args[1]);
452 }
Willy Tarreau27a674e2009-08-17 07:23:33 +0200453 else if (!strcmp(args[0], "tune.bufsize")) {
454 if (*(args[1]) == 0) {
455 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
456 err_code |= ERR_ALERT | ERR_FATAL;
457 goto out;
458 }
459 global.tune.bufsize = atol(args[1]);
460 if (global.tune.maxrewrite >= global.tune.bufsize / 2)
461 global.tune.maxrewrite = global.tune.bufsize / 2;
462 }
463 else if (!strcmp(args[0], "tune.maxrewrite")) {
464 if (*(args[1]) == 0) {
465 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
466 err_code |= ERR_ALERT | ERR_FATAL;
467 goto out;
468 }
469 global.tune.maxrewrite = atol(args[1]);
470 if (global.tune.maxrewrite >= global.tune.bufsize / 2)
471 global.tune.maxrewrite = global.tune.bufsize / 2;
472 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200473 else if (!strcmp(args[0], "uid")) {
474 if (global.uid != 0) {
Willy Tarreau95c20ac2007-03-25 15:39:23 +0200475 Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +0200476 err_code |= ERR_ALERT;
477 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200478 }
479 if (*(args[1]) == 0) {
480 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200481 err_code |= ERR_ALERT | ERR_FATAL;
482 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200483 }
484 global.uid = atol(args[1]);
485 }
486 else if (!strcmp(args[0], "gid")) {
487 if (global.gid != 0) {
Willy Tarreau95c20ac2007-03-25 15:39:23 +0200488 Alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +0200489 err_code |= ERR_ALERT;
490 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200491 }
492 if (*(args[1]) == 0) {
493 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200494 err_code |= ERR_ALERT | ERR_FATAL;
495 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200496 }
497 global.gid = atol(args[1]);
498 }
Willy Tarreau95c20ac2007-03-25 15:39:23 +0200499 /* user/group name handling */
500 else if (!strcmp(args[0], "user")) {
501 struct passwd *ha_user;
502 if (global.uid != 0) {
503 Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +0200504 err_code |= ERR_ALERT;
505 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +0200506 }
507 errno = 0;
508 ha_user = getpwnam(args[1]);
509 if (ha_user != NULL) {
510 global.uid = (int)ha_user->pw_uid;
511 }
512 else {
513 Alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +0200514 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +0200515 }
516 }
517 else if (!strcmp(args[0], "group")) {
518 struct group *ha_group;
519 if (global.gid != 0) {
Willy Tarreau1772ece2009-04-03 14:49:12 +0200520 Alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +0200521 err_code |= ERR_ALERT;
522 goto out;
Willy Tarreau95c20ac2007-03-25 15:39:23 +0200523 }
524 errno = 0;
525 ha_group = getgrnam(args[1]);
526 if (ha_group != NULL) {
527 global.gid = (int)ha_group->gr_gid;
528 }
529 else {
530 Alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
Willy Tarreau058e9072009-07-20 09:30:05 +0200531 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau95c20ac2007-03-25 15:39:23 +0200532 }
533 }
534 /* end of user/group name handling*/
Willy Tarreaubaaee002006-06-26 02:48:02 +0200535 else if (!strcmp(args[0], "nbproc")) {
536 if (global.nbproc != 0) {
537 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200538 err_code |= ERR_ALERT;
539 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200540 }
541 if (*(args[1]) == 0) {
542 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200543 err_code |= ERR_ALERT | ERR_FATAL;
544 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200545 }
546 global.nbproc = atol(args[1]);
547 }
548 else if (!strcmp(args[0], "maxconn")) {
549 if (global.maxconn != 0) {
550 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200551 err_code |= ERR_ALERT;
552 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200553 }
554 if (*(args[1]) == 0) {
555 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200556 err_code |= ERR_ALERT | ERR_FATAL;
557 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200558 }
559 global.maxconn = atol(args[1]);
560#ifdef SYSTEM_MAXCONN
561 if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
562 Alert("parsing [%s:%d] : maxconn value %d too high for this system.\nLimiting to %d. Please use '-n' to force the value.\n", file, linenum, global.maxconn, DEFAULT_MAXCONN);
563 global.maxconn = DEFAULT_MAXCONN;
Willy Tarreau058e9072009-07-20 09:30:05 +0200564 err_code |= ERR_ALERT;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200565 }
566#endif /* SYSTEM_MAXCONN */
567 }
Willy Tarreau3ec79b92009-01-18 20:39:42 +0100568 else if (!strcmp(args[0], "maxpipes")) {
569 if (global.maxpipes != 0) {
570 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200571 err_code |= ERR_ALERT;
572 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +0100573 }
574 if (*(args[1]) == 0) {
575 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200576 err_code |= ERR_ALERT | ERR_FATAL;
577 goto out;
Willy Tarreau3ec79b92009-01-18 20:39:42 +0100578 }
579 global.maxpipes = atol(args[1]);
580 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200581 else if (!strcmp(args[0], "ulimit-n")) {
582 if (global.rlimit_nofile != 0) {
583 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200584 err_code |= ERR_ALERT;
585 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200586 }
587 if (*(args[1]) == 0) {
588 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200589 err_code |= ERR_ALERT | ERR_FATAL;
590 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200591 }
592 global.rlimit_nofile = atol(args[1]);
593 }
594 else if (!strcmp(args[0], "chroot")) {
595 if (global.chroot != NULL) {
596 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200597 err_code |= ERR_ALERT;
598 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200599 }
600 if (*(args[1]) == 0) {
601 Alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200602 err_code |= ERR_ALERT | ERR_FATAL;
603 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200604 }
605 global.chroot = strdup(args[1]);
606 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200607 else if (!strcmp(args[0], "description")) {
608 int i, len=0;
609 char *d;
610
611 if (!*args[1]) {
612 Alert("parsing [%s:%d]: '%s' expects a string argument.\n",
613 file, linenum, args[0]);
614 err_code |= ERR_ALERT | ERR_FATAL;
615 goto out;
616 }
617
618 for(i=1; *args[i]; i++)
619 len += strlen(args[i])+1;
620
621 if (global.desc)
622 free(global.desc);
623
624 global.desc = d = (char *)calloc(1, len);
625
626 d += sprintf(d, "%s", args[1]);
627 for(i=2; *args[i]; i++)
628 d += sprintf(d, " %s", args[i]);
629 }
630 else if (!strcmp(args[0], "node")) {
631 int i;
632 char c;
633
634 for (i=0; args[1][i]; i++) {
635 c = args[1][i];
636 if (!isupper(c) && !islower(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
637 break;
638 }
639
640 if (!i || args[1][i]) {
641 Alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
642 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
643 file, linenum, args[0]);
644 err_code |= ERR_ALERT | ERR_FATAL;
645 goto out;
646 }
647
648 if (global.node)
649 free(global.node);
650
651 global.node = strdup(args[1]);
652 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200653 else if (!strcmp(args[0], "pidfile")) {
654 if (global.pidfile != NULL) {
655 Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200656 err_code |= ERR_ALERT;
657 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200658 }
659 if (*(args[1]) == 0) {
660 Alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200661 err_code |= ERR_ALERT | ERR_FATAL;
662 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200663 }
664 global.pidfile = strdup(args[1]);
665 }
666 else if (!strcmp(args[0], "log")) { /* syslog server address */
Robert Tsai81ae1952007-12-05 10:47:29 +0100667 struct logsrv logsrv;
Willy Tarreauf7edefa2009-05-10 17:20:05 +0200668 int facility, level, minlvl;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200669
670 if (*(args[1]) == 0 || *(args[2]) == 0) {
671 Alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200672 err_code |= ERR_ALERT | ERR_FATAL;
673 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200674 }
675
676 facility = get_log_facility(args[2]);
677 if (facility < 0) {
678 Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200679 err_code |= ERR_ALERT | ERR_FATAL;
680 facility = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200681 }
682
683 level = 7; /* max syslog level = debug */
684 if (*(args[3])) {
685 level = get_log_level(args[3]);
686 if (level < 0) {
687 Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200688 err_code |= ERR_ALERT | ERR_FATAL;
689 level = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200690 }
691 }
692
Willy Tarreauf7edefa2009-05-10 17:20:05 +0200693 minlvl = 0; /* limit syslog level to this level (emerg) */
694 if (*(args[4])) {
695 minlvl = get_log_level(args[4]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200696 if (minlvl < 0) {
Willy Tarreauf7edefa2009-05-10 17:20:05 +0200697 Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200698 err_code |= ERR_ALERT | ERR_FATAL;
699 minlvl = 0;
Willy Tarreauf7edefa2009-05-10 17:20:05 +0200700 }
701 }
702
Robert Tsai81ae1952007-12-05 10:47:29 +0100703 if (args[1][0] == '/') {
704 logsrv.u.addr.sa_family = AF_UNIX;
705 logsrv.u.un = *str2sun(args[1]);
706 } else {
707 logsrv.u.addr.sa_family = AF_INET;
708 logsrv.u.in = *str2sa(args[1]);
709 if (!logsrv.u.in.sin_port)
710 logsrv.u.in.sin_port = htons(SYSLOG_PORT);
711 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200712
713 if (global.logfac1 == -1) {
Robert Tsai81ae1952007-12-05 10:47:29 +0100714 global.logsrv1 = logsrv;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200715 global.logfac1 = facility;
716 global.loglev1 = level;
Willy Tarreauf7edefa2009-05-10 17:20:05 +0200717 global.minlvl1 = minlvl;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200718 }
719 else if (global.logfac2 == -1) {
Robert Tsai81ae1952007-12-05 10:47:29 +0100720 global.logsrv2 = logsrv;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200721 global.logfac2 = facility;
722 global.loglev2 = level;
Willy Tarreauf7edefa2009-05-10 17:20:05 +0200723 global.minlvl2 = minlvl;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200724 }
725 else {
726 Alert("parsing [%s:%d] : too many syslog servers\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +0200727 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200728 }
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +0200729 }
730 else if (!strcmp(args[0], "spread-checks")) { /* random time between checks (0-50) */
731 if (global.spread_checks != 0) {
732 Alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +0200733 err_code |= ERR_ALERT;
734 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +0200735 }
736 if (*(args[1]) == 0) {
737 Alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +0200738 err_code |= ERR_ALERT | ERR_FATAL;
739 goto out;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +0200740 }
741 global.spread_checks = atol(args[1]);
742 if (global.spread_checks < 0 || global.spread_checks > 50) {
743 Alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +0200744 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzkib304dc72007-10-14 23:40:01 +0200745 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200746 }
747 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200748 struct cfg_kw_list *kwl;
749 int index;
Willy Tarreau39f23b62008-07-09 20:22:56 +0200750 int rc;
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200751
752 list_for_each_entry(kwl, &cfg_keywords.list, list) {
753 for (index = 0; kwl->kw[index].kw != NULL; index++) {
754 if (kwl->kw[index].section != CFG_GLOBAL)
755 continue;
756 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
757 /* prepare error message just in case */
758 snprintf(trash, sizeof(trash),
759 "error near '%s' in '%s' section", args[0], "global");
Willy Tarreau39f23b62008-07-09 20:22:56 +0200760 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, trash, sizeof(trash));
761 if (rc < 0) {
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200762 Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
Willy Tarreau058e9072009-07-20 09:30:05 +0200763 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200764 }
Willy Tarreau39f23b62008-07-09 20:22:56 +0200765 else if (rc > 0) {
766 Warning("parsing [%s:%d] : %s\n", file, linenum, trash);
Willy Tarreau058e9072009-07-20 09:30:05 +0200767 err_code |= ERR_WARN;
768 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +0200769 }
Willy Tarreau058e9072009-07-20 09:30:05 +0200770 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +0200771 }
772 }
773 }
774
Willy Tarreaubaaee002006-06-26 02:48:02 +0200775 Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau058e9072009-07-20 09:30:05 +0200776 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200777 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200778
Willy Tarreau058e9072009-07-20 09:30:05 +0200779 out:
780 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200781}
782
783
Willy Tarreau915e1eb2009-06-22 15:48:36 +0200784void init_default_instance()
Willy Tarreaubaaee002006-06-26 02:48:02 +0200785{
786 memset(&defproxy, 0, sizeof(defproxy));
787 defproxy.mode = PR_MODE_TCP;
788 defproxy.state = PR_STNEW;
789 defproxy.maxconn = cfg_maxpconn;
790 defproxy.conn_retries = CONN_RETRIES;
791 defproxy.logfac1 = defproxy.logfac2 = -1; /* log disabled */
Willy Tarreaub099aca2008-10-12 17:26:37 +0200792
793 LIST_INIT(&defproxy.pendconns);
794 LIST_INIT(&defproxy.acl);
795 LIST_INIT(&defproxy.block_cond);
796 LIST_INIT(&defproxy.mon_fail_cond);
797 LIST_INIT(&defproxy.switching_rules);
798
Willy Tarreau3a70f942008-02-15 11:15:34 +0100799 proxy_reset_timeouts(&defproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200800}
801
802/*
Willy Tarreau977b8e42006-12-29 14:19:17 +0100803 * Parse a line in a <listen>, <frontend>, <backend> or <ruleset> section.
Willy Tarreau93893792009-07-23 13:19:11 +0200804 * Returns the error code, 0 if OK, or any combination of :
805 * - ERR_ABORT: must abort ASAP
806 * - ERR_FATAL: we can continue parsing but not start the service
807 * - ERR_WARN: a warning has been emitted
808 * - ERR_ALERT: an alert has been emitted
809 * Only the two first ones can stop processing, the two others are just
810 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +0200811 */
Willy Tarreau3842f002009-06-14 11:39:52 +0200812int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200813{
814 static struct proxy *curproxy = NULL;
815 struct server *newsrv = NULL;
Willy Tarreaub17916e2006-10-15 15:17:57 +0200816 const char *err;
Willy Tarreaub3f32f52007-12-02 22:15:14 +0100817 int rc;
818 unsigned val;
Willy Tarreau93893792009-07-23 13:19:11 +0200819 int err_code = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200820
Willy Tarreau977b8e42006-12-29 14:19:17 +0100821 if (!strcmp(args[0], "listen"))
822 rc = PR_CAP_LISTEN;
823 else if (!strcmp(args[0], "frontend"))
824 rc = PR_CAP_FE | PR_CAP_RS;
825 else if (!strcmp(args[0], "backend"))
826 rc = PR_CAP_BE | PR_CAP_RS;
827 else if (!strcmp(args[0], "ruleset"))
828 rc = PR_CAP_RS;
829 else
830 rc = PR_CAP_NONE;
831
832 if (rc != PR_CAP_NONE) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200833 if (!*args[1]) {
834 Alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
835 " optionnally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
836 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +0200837 err_code |= ERR_ALERT | ERR_ABORT;
838 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200839 }
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +0200840
Willy Tarreau2e74c3f2007-12-02 18:45:09 +0100841 err = invalid_char(args[1]);
842 if (err) {
843 Alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
844 file, linenum, *err, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +0200845 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +0100846 }
847
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +0200848 for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {
849 /*
850 * If there are two proxies with the same name only following
851 * combinations are allowed:
852 *
853 * listen backend frontend ruleset
854 * listen - - - -
855 * backend - - OK -
856 * frontend - OK - -
857 * ruleset - - - -
858 */
859
860 if (!strcmp(curproxy->id, args[1]) &&
861 (rc!=(PR_CAP_FE|PR_CAP_RS) || curproxy->cap!=(PR_CAP_BE|PR_CAP_RS)) &&
862 (rc!=(PR_CAP_BE|PR_CAP_RS) || curproxy->cap!=(PR_CAP_FE|PR_CAP_RS))) {
Willy Tarreau816eb542007-11-04 07:04:43 +0100863 Warning("Parsing [%s:%d]: %s '%s' has same name as another %s.\n",
864 file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy));
Willy Tarreau93893792009-07-23 13:19:11 +0200865 err_code |= ERR_WARN;
Krzysztof Oledzki365d1cd2007-10-21 02:55:17 +0200866 }
867 }
868
Willy Tarreaubaaee002006-06-26 02:48:02 +0200869 if ((curproxy = (struct proxy *)calloc(1, sizeof(struct proxy))) == NULL) {
870 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +0200871 err_code |= ERR_ALERT | ERR_ABORT;
872 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200873 }
Willy Tarreau5af24ef2009-03-15 15:23:16 +0100874
Willy Tarreaubaaee002006-06-26 02:48:02 +0200875 curproxy->next = proxy;
876 proxy = curproxy;
877 LIST_INIT(&curproxy->pendconns);
Willy Tarreaueb0c6142007-05-07 00:53:22 +0200878 LIST_INIT(&curproxy->acl);
Willy Tarreau5c8e3e02007-05-07 00:58:25 +0200879 LIST_INIT(&curproxy->block_cond);
Willy Tarreaub463dfb2008-06-07 23:08:56 +0200880 LIST_INIT(&curproxy->redirect_rules);
Willy Tarreaub80c2302007-11-30 20:51:32 +0100881 LIST_INIT(&curproxy->mon_fail_cond);
Willy Tarreau55ea7572007-06-17 19:56:27 +0200882 LIST_INIT(&curproxy->switching_rules);
Willy Tarreaub6866442008-07-14 23:54:42 +0200883 LIST_INIT(&curproxy->tcp_req.inspect_rules);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200884
Willy Tarreauee991362007-05-14 14:37:50 +0200885 /* Timeouts are defined as -1, so we cannot use the zeroed area
886 * as a default value.
887 */
Willy Tarreau3a70f942008-02-15 11:15:34 +0100888 proxy_reset_timeouts(curproxy);
Krzysztof Oledzki85130942007-10-22 16:21:10 +0200889
890 curproxy->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200891 curproxy->id = strdup(args[1]);
Willy Tarreau977b8e42006-12-29 14:19:17 +0100892 curproxy->cap = rc;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200893
894 /* parse the listener address if any */
Willy Tarreau977b8e42006-12-29 14:19:17 +0100895 if ((curproxy->cap & PR_CAP_FE) && *args[2]) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200896 curproxy->listen = str2listener(args[2], curproxy->listen);
Willy Tarreau93893792009-07-23 13:19:11 +0200897 if (!curproxy->listen) {
898 err_code |= ERR_FATAL;
899 goto out;
900 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200901 global.maxsock++;
902 }
903
904 /* set default values */
905 curproxy->state = defproxy.state;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200906 curproxy->options = defproxy.options;
Willy Tarreau66aa61f2009-01-18 21:44:07 +0100907 curproxy->options2 = defproxy.options2;
Willy Tarreau84b57da2009-06-14 11:10:45 +0200908 curproxy->no_options = defproxy.no_options;
909 curproxy->no_options2 = defproxy.no_options2;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +0100910 curproxy->bind_proc = defproxy.bind_proc;
Willy Tarreau31682232007-11-29 15:38:04 +0100911 curproxy->lbprm.algo = defproxy.lbprm.algo;
Willy Tarreau7ac51f62007-03-25 16:00:04 +0200912 curproxy->except_net = defproxy.except_net;
913 curproxy->except_mask = defproxy.except_mask;
Maik Broemme36db02e2009-05-08 17:02:07 +0200914 curproxy->except_to = defproxy.except_to;
Maik Broemme2850cb42009-04-17 18:53:21 +0200915 curproxy->except_mask_to = defproxy.except_mask_to;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200916
Willy Tarreau79f5fe82008-08-23 08:18:21 +0200917 if (defproxy.fwdfor_hdr_len) {
918 curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len;
919 curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name);
920 }
921
Willy Tarreau977b8e42006-12-29 14:19:17 +0100922 if (curproxy->cap & PR_CAP_FE) {
923 curproxy->maxconn = defproxy.maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +0100924 curproxy->backlog = defproxy.backlog;
Willy Tarreau13a34bd2009-05-10 18:52:49 +0200925 curproxy->fe_sps_lim = defproxy.fe_sps_lim;
Willy Tarreau977b8e42006-12-29 14:19:17 +0100926
927 /* initialize error relocations */
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200928 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
929 chunk_dup(&curproxy->errmsg[rc], &defproxy.errmsg[rc]);
Willy Tarreau977b8e42006-12-29 14:19:17 +0100930
931 curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR;
932 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200933
Willy Tarreau977b8e42006-12-29 14:19:17 +0100934 if (curproxy->cap & PR_CAP_BE) {
935 curproxy->fullconn = defproxy.fullconn;
936 curproxy->conn_retries = defproxy.conn_retries;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200937
Willy Tarreau977b8e42006-12-29 14:19:17 +0100938 if (defproxy.check_req)
939 curproxy->check_req = strdup(defproxy.check_req);
940 curproxy->check_len = defproxy.check_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200941
Willy Tarreau977b8e42006-12-29 14:19:17 +0100942 if (defproxy.cookie_name)
943 curproxy->cookie_name = strdup(defproxy.cookie_name);
944 curproxy->cookie_len = defproxy.cookie_len;
Willy Tarreau01732802007-11-01 22:48:15 +0100945
Emeric Brun647caf12009-06-30 17:57:00 +0200946 if (defproxy.rdp_cookie_name)
947 curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name);
948 curproxy->rdp_cookie_len = defproxy.rdp_cookie_len;
949
Willy Tarreau01732802007-11-01 22:48:15 +0100950 if (defproxy.url_param_name)
951 curproxy->url_param_name = strdup(defproxy.url_param_name);
952 curproxy->url_param_len = defproxy.url_param_len;
Willy Tarreaud53f96b2009-02-04 18:46:54 +0100953
Benoitaffb4812009-03-25 13:02:10 +0100954 if (defproxy.hh_name)
955 curproxy->hh_name = strdup(defproxy.hh_name);
956 curproxy->hh_len = defproxy.hh_len;
957 curproxy->hh_match_domain = defproxy.hh_match_domain;
958
Willy Tarreaud53f96b2009-02-04 18:46:54 +0100959 if (defproxy.iface_name)
960 curproxy->iface_name = strdup(defproxy.iface_name);
961 curproxy->iface_len = defproxy.iface_len;
Willy Tarreau977b8e42006-12-29 14:19:17 +0100962 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200963
Willy Tarreau3b6b1a92009-07-23 13:24:23 +0200964 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreau977b8e42006-12-29 14:19:17 +0100965 if (defproxy.capture_name)
966 curproxy->capture_name = strdup(defproxy.capture_name);
967 curproxy->capture_namelen = defproxy.capture_namelen;
968 curproxy->capture_len = defproxy.capture_len;
Willy Tarreau0f772532006-12-23 20:51:41 +0100969 }
Willy Tarreaubaaee002006-06-26 02:48:02 +0200970
Willy Tarreau977b8e42006-12-29 14:19:17 +0100971 if (curproxy->cap & PR_CAP_FE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +0100972 curproxy->timeout.client = defproxy.timeout.client;
Willy Tarreau1fa31262007-12-03 00:36:16 +0100973 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau036fae02008-01-06 13:24:40 +0100974 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreau977b8e42006-12-29 14:19:17 +0100975 curproxy->uri_auth = defproxy.uri_auth;
976 curproxy->mon_net = defproxy.mon_net;
977 curproxy->mon_mask = defproxy.mon_mask;
978 if (defproxy.monitor_uri)
979 curproxy->monitor_uri = strdup(defproxy.monitor_uri);
980 curproxy->monitor_uri_len = defproxy.monitor_uri_len;
Willy Tarreau5fdfb912007-01-01 23:11:07 +0100981 if (defproxy.defbe.name)
982 curproxy->defbe.name = strdup(defproxy.defbe.name);
Willy Tarreau977b8e42006-12-29 14:19:17 +0100983 }
984
985 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreaud7c30f92007-12-03 01:38:36 +0100986 curproxy->timeout.connect = defproxy.timeout.connect;
987 curproxy->timeout.server = defproxy.timeout.server;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +0100988 curproxy->timeout.check = defproxy.timeout.check;
Willy Tarreau1fa31262007-12-03 00:36:16 +0100989 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau51c9bde2008-01-06 13:40:03 +0100990 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreaucd7afc02009-07-12 10:03:17 +0200991 curproxy->timeout.httpreq = defproxy.timeout.httpreq;
Willy Tarreau977b8e42006-12-29 14:19:17 +0100992 curproxy->source_addr = defproxy.source_addr;
993 }
994
Willy Tarreaubaaee002006-06-26 02:48:02 +0200995 curproxy->mode = defproxy.mode;
996 curproxy->logfac1 = defproxy.logfac1;
997 curproxy->logsrv1 = defproxy.logsrv1;
998 curproxy->loglev1 = defproxy.loglev1;
Willy Tarreauf7edefa2009-05-10 17:20:05 +0200999 curproxy->minlvl1 = defproxy.minlvl1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001000 curproxy->logfac2 = defproxy.logfac2;
1001 curproxy->logsrv2 = defproxy.logsrv2;
1002 curproxy->loglev2 = defproxy.loglev2;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02001003 curproxy->minlvl2 = defproxy.minlvl2;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001004 curproxy->grace = defproxy.grace;
Willy Tarreaudcd47712007-11-04 23:35:08 +01001005 curproxy->uuid = next_pxid++; /* generate a uuid for this proxy */
1006 curproxy->next_svid = 1; /* server id 0 is reserved */
Willy Tarreau1c47f852006-07-09 08:22:27 +02001007
Willy Tarreau93893792009-07-23 13:19:11 +02001008 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001009 }
1010 else if (!strcmp(args[0], "defaults")) { /* use this one to assign default values */
1011 /* some variables may have already been initialized earlier */
Willy Tarreau5fdfb912007-01-01 23:11:07 +01001012 /* FIXME-20070101: we should do this too at the end of the
1013 * config parsing to free all default values.
1014 */
Willy Tarreaua534fea2008-08-03 12:19:50 +02001015 free(defproxy.check_req);
1016 free(defproxy.cookie_name);
Emeric Brun647caf12009-06-30 17:57:00 +02001017 free(defproxy.rdp_cookie_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02001018 free(defproxy.url_param_name);
Benoitaffb4812009-03-25 13:02:10 +01001019 free(defproxy.hh_name);
Willy Tarreaua534fea2008-08-03 12:19:50 +02001020 free(defproxy.capture_name);
1021 free(defproxy.monitor_uri);
1022 free(defproxy.defbe.name);
Willy Tarreaud53f96b2009-02-04 18:46:54 +01001023 free(defproxy.iface_name);
Willy Tarreau79f5fe82008-08-23 08:18:21 +02001024 free(defproxy.fwdfor_hdr_name);
1025 defproxy.fwdfor_hdr_len = 0;
Willy Tarreau0f772532006-12-23 20:51:41 +01001026
Willy Tarreaua534fea2008-08-03 12:19:50 +02001027 for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02001028 chunk_destroy(&defproxy.errmsg[rc]);
Willy Tarreau0f772532006-12-23 20:51:41 +01001029
Willy Tarreaubaaee002006-06-26 02:48:02 +02001030 /* we cannot free uri_auth because it might already be used */
1031 init_default_instance();
1032 curproxy = &defproxy;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001033 defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
Willy Tarreau93893792009-07-23 13:19:11 +02001034 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001035 }
1036 else if (curproxy == NULL) {
1037 Alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001038 err_code |= ERR_ALERT | ERR_FATAL;
1039 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001040 }
1041
Willy Tarreau977b8e42006-12-29 14:19:17 +01001042
1043 /* Now let's parse the proxy-specific keywords */
Willy Tarreaubaaee002006-06-26 02:48:02 +02001044 if (!strcmp(args[0], "bind")) { /* new listen addresses */
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001045 struct listener *last_listen;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001046 int cur_arg;
1047
Willy Tarreaubaaee002006-06-26 02:48:02 +02001048 if (curproxy == &defproxy) {
1049 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001050 err_code |= ERR_ALERT | ERR_FATAL;
1051 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001052 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01001053 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001054 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001055
1056 if (strchr(args[1], ':') == NULL) {
1057 Alert("parsing [%s:%d] : '%s' expects [addr1]:port1[-end1]{,[addr]:port[-end]}... as arguments.\n",
1058 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001059 err_code |= ERR_ALERT | ERR_FATAL;
1060 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001061 }
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001062
1063 last_listen = curproxy->listen;
1064 curproxy->listen = str2listener(args[1], last_listen);
Willy Tarreau93893792009-07-23 13:19:11 +02001065 if (!curproxy->listen) {
1066 err_code |= ERR_ALERT | ERR_FATAL;
1067 goto out;
1068 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001069
1070 cur_arg = 2;
1071 while (*(args[cur_arg])) {
1072 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
1073#ifdef SO_BINDTODEVICE
1074 struct listener *l;
1075
1076 if (!*args[cur_arg + 1]) {
1077 Alert("parsing [%s:%d] : '%s' : missing interface name.\n",
1078 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001079 err_code |= ERR_ALERT | ERR_FATAL;
1080 goto out;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001081 }
1082
1083 for (l = curproxy->listen; l != last_listen; l = l->next)
1084 l->interface = strdup(args[cur_arg + 1]);
1085
1086 global.last_checks |= LSTCHK_NETADM;
1087
1088 cur_arg += 2;
1089 continue;
1090#else
1091 Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
1092 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001093 err_code |= ERR_ALERT | ERR_FATAL;
1094 goto out;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001095#endif
1096 }
Willy Tarreaube1b9182009-06-14 18:48:19 +02001097 if (!strcmp(args[cur_arg], "mss")) { /* set MSS of listening socket */
1098#ifdef TCP_MAXSEG
1099 struct listener *l;
1100 int mss;
1101
1102 if (!*args[cur_arg + 1]) {
1103 Alert("parsing [%s:%d] : '%s' : missing MSS value.\n",
1104 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001105 err_code |= ERR_ALERT | ERR_FATAL;
1106 goto out;
Willy Tarreaube1b9182009-06-14 18:48:19 +02001107 }
1108
1109 mss = str2uic(args[cur_arg + 1]);
1110 if (mss < 1 || mss > 65535) {
1111 Alert("parsing [%s:%d]: %s expects an MSS value between 1 and 65535.\n",
1112 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001113 err_code |= ERR_ALERT | ERR_FATAL;
1114 goto out;
Willy Tarreaube1b9182009-06-14 18:48:19 +02001115 }
1116
1117 for (l = curproxy->listen; l != last_listen; l = l->next)
1118 l->maxseg = mss;
1119
1120 cur_arg += 2;
1121 continue;
1122#else
1123 Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
1124 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001125 err_code |= ERR_ALERT | ERR_FATAL;
1126 goto out;
Willy Tarreaube1b9182009-06-14 18:48:19 +02001127#endif
1128 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001129 if (!strcmp(args[cur_arg], "transparent")) { /* transparently bind to these addresses */
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001130#ifdef CONFIG_HAP_LINUX_TPROXY
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001131 struct listener *l;
1132
1133 for (l = curproxy->listen; l != last_listen; l = l->next)
1134 l->options |= LI_O_FOREIGN;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001135
1136 cur_arg ++;
1137 continue;
1138#else
1139 Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
1140 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001141 err_code |= ERR_ALERT | ERR_FATAL;
1142 goto out;
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001143#endif
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001144 }
Willy Tarreau5e6e2042009-02-04 17:19:29 +01001145 Alert("parsing [%s:%d] : '%s' only supports the 'transparent' and 'interface' options.\n",
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001146 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001147 err_code |= ERR_ALERT | ERR_FATAL;
1148 goto out;
Willy Tarreaub1e52e82008-01-13 14:49:51 +01001149 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001150 global.maxsock++;
Willy Tarreau93893792009-07-23 13:19:11 +02001151 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001152 }
1153 else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
1154 if (!*args[1] || !str2net(args[1], &curproxy->mon_net, &curproxy->mon_mask)) {
1155 Alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
1156 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001157 err_code |= ERR_ALERT | ERR_FATAL;
1158 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001159 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01001160 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001161 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001162
Willy Tarreaubaaee002006-06-26 02:48:02 +02001163 /* flush useless bits */
1164 curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
Willy Tarreau93893792009-07-23 13:19:11 +02001165 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001166 }
Willy Tarreau1c47f852006-07-09 08:22:27 +02001167 else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
Willy Tarreau977b8e42006-12-29 14:19:17 +01001168 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001169 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001170
Willy Tarreau1c47f852006-07-09 08:22:27 +02001171 if (!*args[1]) {
1172 Alert("parsing [%s:%d] : '%s' expects an URI.\n",
1173 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001174 err_code |= ERR_ALERT | ERR_FATAL;
1175 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02001176 }
1177
Willy Tarreaua534fea2008-08-03 12:19:50 +02001178 free(curproxy->monitor_uri);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01001179 curproxy->monitor_uri_len = strlen(args[1]);
Willy Tarreau1c47f852006-07-09 08:22:27 +02001180 curproxy->monitor_uri = (char *)calloc(1, curproxy->monitor_uri_len + 1);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +01001181 memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
Willy Tarreau1c47f852006-07-09 08:22:27 +02001182 curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
1183
Willy Tarreau93893792009-07-23 13:19:11 +02001184 goto out;
Willy Tarreau1c47f852006-07-09 08:22:27 +02001185 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001186 else if (!strcmp(args[0], "mode")) { /* sets the proxy mode */
1187 if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
1188 else if (!strcmp(args[1], "tcp")) curproxy->mode = PR_MODE_TCP;
1189 else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
1190 else {
1191 Alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001192 err_code |= ERR_ALERT | ERR_FATAL;
1193 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001194 }
1195 }
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01001196 else if (!strcmp(args[0], "id")) {
1197 struct proxy *target;
1198
1199 if (curproxy == &defproxy) {
1200 Alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
1201 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001202 err_code |= ERR_ALERT | ERR_FATAL;
1203 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01001204 }
1205
1206 if (!*args[1]) {
1207 Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
1208 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001209 err_code |= ERR_ALERT | ERR_FATAL;
1210 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01001211 }
1212
1213 curproxy->uuid = atol(args[1]);
1214
1215 if (curproxy->uuid < 1001) {
Krzysztof Piotr Oledzki08ff9592009-09-27 16:17:31 +02001216 Alert("parsing [%s:%d]: custom id has to be > 1000.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01001217 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001218 err_code |= ERR_ALERT | ERR_FATAL;
1219 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01001220 }
1221
1222 for (target = proxy; target; target = target->next)
1223 if (curproxy != target && curproxy->uuid == target->uuid) {
1224 Alert("parsing [%s:%d]: custom id has to be unique but is duplicated in %s and %s.\n",
1225 file, linenum, curproxy->id, target->id);
Willy Tarreau93893792009-07-23 13:19:11 +02001226 err_code |= ERR_ALERT | ERR_FATAL;
1227 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01001228 }
1229 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001230 else if (!strcmp(args[0], "description")) {
1231 int i, len=0;
1232 char *d;
1233
1234 if (!*args[1]) {
1235 Alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1236 file, linenum, args[0]);
1237 return -1;
1238 }
1239
1240 for(i=1; *args[i]; i++)
1241 len += strlen(args[i])+1;
1242
1243 d = (char *)calloc(1, len);
1244 curproxy->desc = d;
1245
1246 d += sprintf(d, "%s", args[1]);
1247 for(i=2; *args[i]; i++)
1248 d += sprintf(d, " %s", args[i]);
1249
1250 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001251 else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
1252 curproxy->state = PR_STSTOPPED;
1253 }
1254 else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
1255 curproxy->state = PR_STNEW;
1256 }
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01001257 else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
1258 int cur_arg = 1;
1259 unsigned int set = 0;
1260
1261 while (*args[cur_arg]) {
1262 int u;
1263 if (strcmp(args[cur_arg], "all") == 0) {
1264 set = 0;
1265 break;
1266 }
1267 else if (strcmp(args[cur_arg], "odd") == 0) {
1268 set |= 0x55555555;
1269 }
1270 else if (strcmp(args[cur_arg], "even") == 0) {
1271 set |= 0xAAAAAAAA;
1272 }
1273 else {
1274 u = str2uic(args[cur_arg]);
1275 if (u < 1 || u > 32) {
1276 Alert("parsing [%s:%d]: %s expects 'all', 'odd', 'even', or process numbers from 1 to 32.\n",
1277 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001278 err_code |= ERR_ALERT | ERR_FATAL;
1279 goto out;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01001280 }
1281 if (u > global.nbproc) {
1282 Warning("parsing [%s:%d]: %s references process number higher than global.nbproc.\n",
1283 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001284 err_code |= ERR_WARN;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01001285 }
1286 set |= 1 << (u - 1);
1287 }
1288 cur_arg++;
1289 }
1290 curproxy->bind_proc = set;
1291 }
Willy Tarreaueb0c6142007-05-07 00:53:22 +02001292 else if (!strcmp(args[0], "acl")) { /* add an ACL */
Willy Tarreaub099aca2008-10-12 17:26:37 +02001293 if (curproxy == &defproxy) {
1294 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001295 err_code |= ERR_ALERT | ERR_FATAL;
1296 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02001297 }
1298
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01001299 err = invalid_char(args[1]);
1300 if (err) {
1301 Alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
1302 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001303 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01001304 }
1305
Willy Tarreaueb0c6142007-05-07 00:53:22 +02001306 if (parse_acl((const char **)args + 1, &curproxy->acl) == NULL) {
1307 Alert("parsing [%s:%d] : error detected while parsing ACL '%s'.\n",
1308 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001309 err_code |= ERR_ALERT | ERR_FATAL;
1310 goto out;
Willy Tarreaueb0c6142007-05-07 00:53:22 +02001311 }
1312 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001313 else if (!strcmp(args[0], "cookie")) { /* cookie name */
1314 int cur_arg;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001315
Willy Tarreau977b8e42006-12-29 14:19:17 +01001316 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001317 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001318
Willy Tarreaubaaee002006-06-26 02:48:02 +02001319 if (*(args[1]) == 0) {
1320 Alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
1321 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001322 err_code |= ERR_ALERT | ERR_FATAL;
1323 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001324 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02001325
1326 free(curproxy->cookie_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001327 curproxy->cookie_name = strdup(args[1]);
1328 curproxy->cookie_len = strlen(curproxy->cookie_name);
1329
1330 cur_arg = 2;
1331 while (*(args[cur_arg])) {
1332 if (!strcmp(args[cur_arg], "rewrite")) {
1333 curproxy->options |= PR_O_COOK_RW;
1334 }
1335 else if (!strcmp(args[cur_arg], "indirect")) {
1336 curproxy->options |= PR_O_COOK_IND;
1337 }
1338 else if (!strcmp(args[cur_arg], "insert")) {
1339 curproxy->options |= PR_O_COOK_INS;
1340 }
1341 else if (!strcmp(args[cur_arg], "nocache")) {
1342 curproxy->options |= PR_O_COOK_NOC;
1343 }
1344 else if (!strcmp(args[cur_arg], "postonly")) {
1345 curproxy->options |= PR_O_COOK_POST;
1346 }
1347 else if (!strcmp(args[cur_arg], "prefix")) {
1348 curproxy->options |= PR_O_COOK_PFX;
1349 }
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02001350 else if (!strcmp(args[cur_arg], "domain")) {
1351 if (!*args[cur_arg + 1]) {
1352 Alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
1353 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001354 err_code |= ERR_ALERT | ERR_FATAL;
1355 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02001356 }
1357
1358 if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
1359 /* rfc2109, 4.3.2 Rejecting Cookies */
1360 Alert("parsing [%s:%d]: domain '%s' contains no embedded"
1361 " dots or does not start with a dot.\n",
1362 file, linenum, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001363 err_code |= ERR_ALERT | ERR_FATAL;
1364 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02001365 }
1366
1367 err = invalid_domainchar(args[cur_arg + 1]);
1368 if (err) {
1369 Alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
1370 file, linenum, *err, args[cur_arg + 1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001371 err_code |= ERR_ALERT | ERR_FATAL;
1372 goto out;
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02001373 }
1374
Krzysztof Piotr Oledzki1acf2172008-05-29 23:03:34 +02001375 curproxy->cookie_domain = strdup(args[cur_arg + 1]);
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02001376 cur_arg++;
1377 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001378 else {
Krzysztof Piotr Oledzkiefe3b6f2008-05-23 23:49:32 +02001379 Alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache' and 'postonly', 'domain' options.\n",
Willy Tarreaubaaee002006-06-26 02:48:02 +02001380 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001381 err_code |= ERR_ALERT | ERR_FATAL;
1382 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001383 }
1384 cur_arg++;
1385 }
1386 if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_IND))) {
1387 Alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
1388 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001389 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001390 }
1391
1392 if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_INS|PR_O_COOK_PFX))) {
1393 Alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
1394 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001395 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001396 }
1397 }/* end else if (!strcmp(args[0], "cookie")) */
Emeric Brun647caf12009-06-30 17:57:00 +02001398 else if (!strcmp(args[0], "persist")) { /* persist */
1399 if (*(args[1]) == 0) {
1400 Alert("parsing [%s:%d] : missing persist method.\n",
1401 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001402 err_code |= ERR_ALERT | ERR_FATAL;
1403 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02001404 }
1405
1406 if (!strncmp(args[1], "rdp-cookie", 10)) {
1407 curproxy->options2 |= PR_O2_RDPC_PRST;
1408
1409 if (*(args[1] + 10 ) == '(') { /* cookie name */
1410 const char *beg, *end;
1411
1412 beg = args[1] + 11;
1413 end = strchr(beg, ')');
1414
1415 if (!end || end == beg) {
1416 Alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
1417 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001418 err_code |= ERR_ALERT | ERR_FATAL;
1419 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02001420 }
1421
1422 free(curproxy->rdp_cookie_name);
1423 curproxy->rdp_cookie_name = my_strndup(beg, end - beg);
1424 curproxy->rdp_cookie_len = end-beg;
1425 }
1426 else if (*(args[1] + 10 ) == '\0') { /* default cookie name 'msts' */
1427 free(curproxy->rdp_cookie_name);
1428 curproxy->rdp_cookie_name = strdup("msts");
1429 curproxy->rdp_cookie_len = strlen(curproxy->rdp_cookie_name);
1430 }
1431 else { /* syntax */
1432 Alert("parsing [%s:%d] : persist rdp-cookie(name)' requires an rdp cookie name.\n",
1433 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001434 err_code |= ERR_ALERT | ERR_FATAL;
1435 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02001436 }
1437 }
1438 else {
1439 Alert("parsing [%s:%d] : unknown persist method.\n",
1440 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001441 err_code |= ERR_ALERT | ERR_FATAL;
1442 goto out;
Emeric Brun647caf12009-06-30 17:57:00 +02001443 }
1444 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001445 else if (!strcmp(args[0], "appsession")) { /* cookie name */
Willy Tarreaubaaee002006-06-26 02:48:02 +02001446
Willy Tarreau977b8e42006-12-29 14:19:17 +01001447 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001448 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001449
Willy Tarreaubaaee002006-06-26 02:48:02 +02001450 if (*(args[5]) == 0) {
1451 Alert("parsing [%s:%d] : '%s' expects 'appsession' <cookie_name> 'len' <len> 'timeout' <timeout>.\n",
1452 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001453 err_code |= ERR_ALERT | ERR_FATAL;
1454 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001455 }
1456 have_appsession = 1;
Willy Tarreaua534fea2008-08-03 12:19:50 +02001457 free(curproxy->appsession_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001458 curproxy->appsession_name = strdup(args[1]);
1459 curproxy->appsession_name_len = strlen(curproxy->appsession_name);
1460 curproxy->appsession_len = atoi(args[3]);
Willy Tarreaub3f32f52007-12-02 22:15:14 +01001461 err = parse_time_err(args[5], &val, TIME_UNIT_MS);
1462 if (err) {
1463 Alert("parsing [%s:%d] : unexpected character '%c' in %s timeout.\n",
1464 file, linenum, *err, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001465 err_code |= ERR_ALERT | ERR_FATAL;
1466 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01001467 }
Willy Tarreau0c303ee2008-07-07 00:09:58 +02001468 curproxy->timeout.appsession = val;
Willy Tarreauee991362007-05-14 14:37:50 +02001469
Willy Tarreau51041c72007-09-09 21:56:53 +02001470 if (appsession_hash_init(&(curproxy->htbl_proxy), destroy) == 0) {
1471 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001472 err_code |= ERR_ALERT | ERR_ABORT;
1473 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001474 }
1475 } /* Url App Session */
1476 else if (!strcmp(args[0], "capture")) {
Willy Tarreau3b6b1a92009-07-23 13:24:23 +02001477 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001478 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001479
Willy Tarreaubaaee002006-06-26 02:48:02 +02001480 if (!strcmp(args[1], "cookie")) { /* name of a cookie to capture */
Willy Tarreaubaaee002006-06-26 02:48:02 +02001481 if (*(args[4]) == 0) {
1482 Alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
1483 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001484 err_code |= ERR_ALERT | ERR_FATAL;
1485 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001486 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02001487 free(curproxy->capture_name);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001488 curproxy->capture_name = strdup(args[2]);
1489 curproxy->capture_namelen = strlen(curproxy->capture_name);
1490 curproxy->capture_len = atol(args[4]);
1491 if (curproxy->capture_len >= CAPTURE_LEN) {
1492 Warning("parsing [%s:%d] : truncating capture length to %d bytes.\n",
1493 file, linenum, CAPTURE_LEN - 1);
Willy Tarreau93893792009-07-23 13:19:11 +02001494 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001495 curproxy->capture_len = CAPTURE_LEN - 1;
1496 }
1497 curproxy->to_log |= LW_COOKIE;
1498 }
1499 else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) {
1500 struct cap_hdr *hdr;
1501
1502 if (curproxy == &defproxy) {
1503 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 +02001504 err_code |= ERR_ALERT | ERR_FATAL;
1505 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001506 }
1507
1508 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
1509 Alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
1510 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001511 err_code |= ERR_ALERT | ERR_FATAL;
1512 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001513 }
1514
1515 hdr = calloc(sizeof(struct cap_hdr), 1);
1516 hdr->next = curproxy->req_cap;
1517 hdr->name = strdup(args[3]);
1518 hdr->namelen = strlen(args[3]);
1519 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02001520 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001521 hdr->index = curproxy->nb_req_cap++;
1522 curproxy->req_cap = hdr;
1523 curproxy->to_log |= LW_REQHDR;
1524 }
1525 else if (!strcmp(args[1], "response") && !strcmp(args[2], "header")) {
1526 struct cap_hdr *hdr;
1527
1528 if (curproxy == &defproxy) {
1529 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 +02001530 err_code |= ERR_ALERT | ERR_FATAL;
1531 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001532 }
1533
1534 if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
1535 Alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
1536 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02001537 err_code |= ERR_ALERT | ERR_FATAL;
1538 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001539 }
1540 hdr = calloc(sizeof(struct cap_hdr), 1);
1541 hdr->next = curproxy->rsp_cap;
1542 hdr->name = strdup(args[3]);
1543 hdr->namelen = strlen(args[3]);
1544 hdr->len = atol(args[5]);
Willy Tarreaucf7f3202007-05-13 22:46:04 +02001545 hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
Willy Tarreaubaaee002006-06-26 02:48:02 +02001546 hdr->index = curproxy->nb_rsp_cap++;
1547 curproxy->rsp_cap = hdr;
1548 curproxy->to_log |= LW_RSPHDR;
1549 }
1550 else {
1551 Alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
1552 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001553 err_code |= ERR_ALERT | ERR_FATAL;
1554 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001555 }
1556 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001557 else if (!strcmp(args[0], "retries")) { /* connection retries */
Willy Tarreau977b8e42006-12-29 14:19:17 +01001558 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001559 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001560
Willy Tarreaubaaee002006-06-26 02:48:02 +02001561 if (*(args[1]) == 0) {
1562 Alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
1563 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001564 err_code |= ERR_ALERT | ERR_FATAL;
1565 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001566 }
1567 curproxy->conn_retries = atol(args[1]);
1568 }
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02001569 else if (!strcmp(args[0], "block")) { /* early blocking based on ACLs */
1570 int pol = ACL_COND_NONE;
1571 struct acl_cond *cond;
1572
Willy Tarreaub099aca2008-10-12 17:26:37 +02001573 if (curproxy == &defproxy) {
1574 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001575 err_code |= ERR_ALERT | ERR_FATAL;
1576 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02001577 }
1578
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02001579 if (!strcmp(args[1], "if"))
1580 pol = ACL_COND_IF;
1581 else if (!strcmp(args[1], "unless"))
1582 pol = ACL_COND_UNLESS;
1583
1584 if (pol == ACL_COND_NONE) {
1585 Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
1586 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001587 err_code |= ERR_ALERT | ERR_FATAL;
1588 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02001589 }
1590
1591 if ((cond = parse_acl_cond((const char **)args + 2, &curproxy->acl, pol)) == NULL) {
1592 Alert("parsing [%s:%d] : error detected while parsing blocking condition.\n",
1593 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001594 err_code |= ERR_ALERT | ERR_FATAL;
1595 goto out;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02001596 }
Willy Tarreaua9802632008-07-25 19:13:19 +02001597 cond->line = linenum;
Willy Tarreaua9fb0832009-07-10 20:53:53 +02001598 curproxy->acl_requires |= cond->requires;
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02001599 LIST_ADDQ(&curproxy->block_cond, &cond->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02001600 warnif_misplaced_block(curproxy, file, linenum, args[0]);
Willy Tarreau5c8e3e02007-05-07 00:58:25 +02001601 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001602 else if (!strcmp(args[0], "redirect")) {
1603 int pol = ACL_COND_NONE;
1604 struct acl_cond *cond;
1605 struct redirect_rule *rule;
1606 int cur_arg;
1607 int type = REDIRECT_TYPE_NONE;
1608 int code = 302;
1609 char *destination = NULL;
Willy Tarreau0140f252008-11-19 21:07:09 +01001610 char *cookie = NULL;
1611 int cookie_set = 0;
Willy Tarreau79da4692008-11-19 20:03:04 +01001612 unsigned int flags = REDIRECT_FLAG_NONE;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001613
1614 cur_arg = 1;
1615 while (*(args[cur_arg])) {
1616 if (!strcmp(args[cur_arg], "location")) {
1617 if (!*args[cur_arg + 1]) {
1618 Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1619 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001620 err_code |= ERR_ALERT | ERR_FATAL;
1621 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001622 }
1623
1624 type = REDIRECT_TYPE_LOCATION;
1625 cur_arg++;
1626 destination = args[cur_arg];
1627 }
1628 else if (!strcmp(args[cur_arg], "prefix")) {
1629 if (!*args[cur_arg + 1]) {
1630 Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1631 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001632 err_code |= ERR_ALERT | ERR_FATAL;
1633 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001634 }
1635
1636 type = REDIRECT_TYPE_PREFIX;
1637 cur_arg++;
1638 destination = args[cur_arg];
1639 }
Willy Tarreau0140f252008-11-19 21:07:09 +01001640 else if (!strcmp(args[cur_arg], "set-cookie")) {
1641 if (!*args[cur_arg + 1]) {
1642 Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1643 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001644 err_code |= ERR_ALERT | ERR_FATAL;
1645 goto out;
Willy Tarreau0140f252008-11-19 21:07:09 +01001646 }
1647
1648 cur_arg++;
1649 cookie = args[cur_arg];
1650 cookie_set = 1;
1651 }
1652 else if (!strcmp(args[cur_arg], "clear-cookie")) {
1653 if (!*args[cur_arg + 1]) {
1654 Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1655 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001656 err_code |= ERR_ALERT | ERR_FATAL;
1657 goto out;
Willy Tarreau0140f252008-11-19 21:07:09 +01001658 }
1659
1660 cur_arg++;
1661 cookie = args[cur_arg];
1662 cookie_set = 0;
1663 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001664 else if (!strcmp(args[cur_arg],"code")) {
1665 if (!*args[cur_arg + 1]) {
1666 Alert("parsing [%s:%d] : '%s': missing HTTP code.\n",
1667 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001668 err_code |= ERR_ALERT | ERR_FATAL;
1669 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001670 }
1671 cur_arg++;
1672 code = atol(args[cur_arg]);
1673 if (code < 301 || code > 303) {
1674 Alert("parsing [%s:%d] : '%s': unsupported HTTP code '%d'.\n",
1675 file, linenum, args[0], code);
Willy Tarreau93893792009-07-23 13:19:11 +02001676 err_code |= ERR_ALERT | ERR_FATAL;
1677 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001678 }
1679 }
Willy Tarreau79da4692008-11-19 20:03:04 +01001680 else if (!strcmp(args[cur_arg],"drop-query")) {
1681 flags |= REDIRECT_FLAG_DROP_QS;
1682 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001683 else if (!strcmp(args[cur_arg], "if")) {
1684 pol = ACL_COND_IF;
1685 cur_arg++;
1686 break;
1687 }
1688 else if (!strcmp(args[cur_arg], "unless")) {
1689 pol = ACL_COND_UNLESS;
1690 cur_arg++;
1691 break;
1692 }
1693 else {
1694 Alert("parsing [%s:%d] : '%s' expects 'code', 'prefix' or 'location' (was '%s').\n",
1695 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02001696 err_code |= ERR_ALERT | ERR_FATAL;
1697 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001698 }
1699 cur_arg++;
1700 }
1701
1702 if (type == REDIRECT_TYPE_NONE) {
1703 Alert("parsing [%s:%d] : '%s' expects a redirection type ('prefix' or 'location').\n",
1704 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001705 err_code |= ERR_ALERT | ERR_FATAL;
1706 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001707 }
1708
1709 if (pol == ACL_COND_NONE) {
1710 Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
1711 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001712 err_code |= ERR_ALERT | ERR_FATAL;
1713 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001714 }
1715
1716 if ((cond = parse_acl_cond((const char **)args + cur_arg, &curproxy->acl, pol)) == NULL) {
Jeffrey 'jf' Limaf403fc2009-04-02 21:53:56 +08001717 Alert("parsing [%s:%d] : '%s': error detected while parsing redirect condition.\n",
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001718 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001719 err_code |= ERR_ALERT | ERR_FATAL;
1720 goto out;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001721 }
1722
Willy Tarreaua9802632008-07-25 19:13:19 +02001723 cond->line = linenum;
Willy Tarreaua9fb0832009-07-10 20:53:53 +02001724 curproxy->acl_requires |= cond->requires;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001725 rule = (struct redirect_rule *)calloc(1, sizeof(*rule));
1726 rule->cond = cond;
1727 rule->rdr_str = strdup(destination);
1728 rule->rdr_len = strlen(destination);
Willy Tarreau0140f252008-11-19 21:07:09 +01001729 if (cookie) {
1730 /* depending on cookie_set, either we want to set the cookie, or to clear it.
1731 * a clear consists in appending "; Max-Age=0" at the end.
1732 */
1733 rule->cookie_len = strlen(cookie);
1734 if (cookie_set)
1735 rule->cookie_str = strdup(cookie);
1736 else {
1737 rule->cookie_str = malloc(rule->cookie_len + 12);
1738 memcpy(rule->cookie_str, cookie, rule->cookie_len);
1739 memcpy(rule->cookie_str + rule->cookie_len, "; Max-Age=0", 12);
1740 rule->cookie_len += 11;
1741 }
1742 }
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001743 rule->type = type;
1744 rule->code = code;
Willy Tarreau79da4692008-11-19 20:03:04 +01001745 rule->flags = flags;
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001746 LIST_INIT(&rule->list);
1747 LIST_ADDQ(&curproxy->redirect_rules, &rule->list);
Willy Tarreau61d18892009-03-31 10:49:21 +02001748 warnif_rule_after_use_backend(curproxy, file, linenum, args[0]);
Willy Tarreaub463dfb2008-06-07 23:08:56 +02001749 }
Krzysztof Piotr Oledzki7b723ef2009-01-27 21:09:41 +01001750 else if (!strcmp(args[0], "use_backend")) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02001751 int pol = ACL_COND_NONE;
1752 struct acl_cond *cond;
1753 struct switching_rule *rule;
1754
Willy Tarreaub099aca2008-10-12 17:26:37 +02001755 if (curproxy == &defproxy) {
1756 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001757 err_code |= ERR_ALERT | ERR_FATAL;
1758 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02001759 }
1760
Willy Tarreau55ea7572007-06-17 19:56:27 +02001761 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001762 err_code |= ERR_WARN;
Willy Tarreau55ea7572007-06-17 19:56:27 +02001763
1764 if (*(args[1]) == 0) {
1765 Alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001766 err_code |= ERR_ALERT | ERR_FATAL;
1767 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02001768 }
1769
1770 if (!strcmp(args[2], "if"))
1771 pol = ACL_COND_IF;
1772 else if (!strcmp(args[2], "unless"))
1773 pol = ACL_COND_UNLESS;
1774
1775 if (pol == ACL_COND_NONE) {
1776 Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
1777 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001778 err_code |= ERR_ALERT | ERR_FATAL;
1779 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02001780 }
1781
1782 if ((cond = parse_acl_cond((const char **)args + 3, &curproxy->acl, pol)) == NULL) {
Willy Tarreaua9802632008-07-25 19:13:19 +02001783 Alert("parsing [%s:%d] : error detected while parsing switching rule.\n",
Willy Tarreau55ea7572007-06-17 19:56:27 +02001784 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001785 err_code |= ERR_ALERT | ERR_FATAL;
1786 goto out;
Willy Tarreau55ea7572007-06-17 19:56:27 +02001787 }
1788
Willy Tarreaua9802632008-07-25 19:13:19 +02001789 cond->line = linenum;
Willy Tarreaua9fb0832009-07-10 20:53:53 +02001790 curproxy->acl_requires |= cond->requires;
Willy Tarreaua9802632008-07-25 19:13:19 +02001791 if (cond->requires & ACL_USE_RTR_ANY) {
Willy Tarreaudd64f8d2008-07-27 22:02:32 +02001792 struct acl *acl;
1793 const char *name;
1794
1795 acl = cond_find_require(cond, ACL_USE_RTR_ANY);
1796 name = acl ? acl->name : "(unknown)";
1797 Warning("parsing [%s:%d] : acl '%s' involves some response-only criteria which will be ignored.\n",
1798 file, linenum, name);
Willy Tarreau93893792009-07-23 13:19:11 +02001799 err_code |= ERR_WARN;
Willy Tarreaua9802632008-07-25 19:13:19 +02001800 }
1801
Willy Tarreau55ea7572007-06-17 19:56:27 +02001802 rule = (struct switching_rule *)calloc(1, sizeof(*rule));
1803 rule->cond = cond;
1804 rule->be.name = strdup(args[1]);
1805 LIST_INIT(&rule->list);
1806 LIST_ADDQ(&curproxy->switching_rules, &rule->list);
1807 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001808 else if (!strcmp(args[0], "stats")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01001809 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02001810 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01001811
Willy Tarreaubaaee002006-06-26 02:48:02 +02001812 if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
1813 curproxy->uri_auth = NULL; /* we must detach from the default config */
1814
1815 if (*(args[1]) == 0) {
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001816 Alert("parsing [%s:%d] : '%s' expects 'uri', 'realm', 'auth', 'scope' or 'enable', 'hide-version', 'show-node', 'show-desc'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001817 err_code |= ERR_ALERT | ERR_FATAL;
1818 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001819 } else if (!strcmp(args[1], "uri")) {
1820 if (*(args[2]) == 0) {
1821 Alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001822 err_code |= ERR_ALERT | ERR_FATAL;
1823 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001824 } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
1825 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001826 err_code |= ERR_ALERT | ERR_ABORT;
1827 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001828 }
1829 } else if (!strcmp(args[1], "realm")) {
1830 if (*(args[2]) == 0) {
1831 Alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001832 err_code |= ERR_ALERT | ERR_FATAL;
1833 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001834 } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
1835 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001836 err_code |= ERR_ALERT | ERR_ABORT;
1837 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001838 }
Willy Tarreaubbd42122007-07-25 07:26:38 +02001839 } else if (!strcmp(args[1], "refresh")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01001840 unsigned interval;
1841
1842 err = parse_time_err(args[2], &interval, TIME_UNIT_S);
1843 if (err) {
1844 Alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
1845 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02001846 err_code |= ERR_ALERT | ERR_FATAL;
1847 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02001848 } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
1849 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001850 err_code |= ERR_ALERT | ERR_ABORT;
1851 goto out;
Willy Tarreaubbd42122007-07-25 07:26:38 +02001852 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001853 } else if (!strcmp(args[1], "auth")) {
1854 if (*(args[2]) == 0) {
1855 Alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001856 err_code |= ERR_ALERT | ERR_FATAL;
1857 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001858 } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
1859 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001860 err_code |= ERR_ALERT | ERR_ABORT;
1861 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001862 }
1863 } else if (!strcmp(args[1], "scope")) {
1864 if (*(args[2]) == 0) {
1865 Alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001866 err_code |= ERR_ALERT | ERR_FATAL;
1867 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001868 } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
1869 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001870 err_code |= ERR_ALERT | ERR_ABORT;
1871 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001872 }
1873 } else if (!strcmp(args[1], "enable")) {
1874 if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
1875 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001876 err_code |= ERR_ALERT | ERR_ABORT;
1877 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001878 }
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02001879 } else if (!strcmp(args[1], "hide-version")) {
1880 if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
1881 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02001882 err_code |= ERR_ALERT | ERR_ABORT;
1883 goto out;
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02001884 }
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001885 } else if (!strcmp(args[1], "show-node")) {
1886
1887 if (*args[2]) {
1888 int i;
1889 char c;
1890
1891 for (i=0; args[2][i]; i++) {
1892 c = args[2][i];
Krzysztof Piotr Oledzki619caca2009-10-03 15:46:08 +02001893 if (!isupper(c) && !islower(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +02001894 break;
1895 }
1896
1897 if (!i || args[2][i]) {
1898 Alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
1899 "with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
1900 file, linenum, args[0], args[1]);
1901 err_code |= ERR_ALERT | ERR_FATAL;
1902 goto out;
1903 }
1904 }
1905
1906 if (!stats_set_node(&curproxy->uri_auth, args[2])) {
1907 Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
1908 err_code |= ERR_ALERT | ERR_ABORT;
1909 goto out;
1910 }
1911 } else if (!strcmp(args[1], "show-desc")) {
1912 char *desc = NULL;
1913
1914 if (*args[2]) {
1915 int i, len=0;
1916 char *d;
1917
1918 for(i=2; *args[i]; i++)
1919 len += strlen(args[i])+1;
1920
1921 desc = d = (char *)calloc(1, len);
1922
1923 d += sprintf(d, "%s", args[2]);
1924 for(i=3; *args[i]; i++)
1925 d += sprintf(d, " %s", args[i]);
1926 }
1927
1928 if (!*args[2] && !global.desc)
1929 Warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
1930 file, linenum, args[1]);
1931 else {
1932 if (!stats_set_desc(&curproxy->uri_auth, desc)) {
1933 free(desc);
1934 Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
1935 err_code |= ERR_ALERT | ERR_ABORT;
1936 goto out;
1937 }
1938 free(desc);
1939 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02001940 } else {
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +02001941 Alert("parsing [%s:%d] : unknown stats parameter '%s' (expects 'hide-version', 'uri', 'realm', 'auth' or 'enable').\n",
Willy Tarreaubaaee002006-06-26 02:48:02 +02001942 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001943 err_code |= ERR_ALERT | ERR_FATAL;
1944 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001945 }
1946 }
1947 else if (!strcmp(args[0], "option")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01001948 int optnum;
1949
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01001950 if (*(args[1]) == '\0') {
1951 Alert("parsing [%s:%d]: '%s' expects an option name.\n",
1952 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02001953 err_code |= ERR_ALERT | ERR_FATAL;
1954 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02001955 }
Willy Tarreau13943ab2006-12-31 00:24:10 +01001956
1957 for (optnum = 0; cfg_opts[optnum].name; optnum++) {
1958 if (!strcmp(args[1], cfg_opts[optnum].name)) {
Willy Tarreau93893792009-07-23 13:19:11 +02001959 if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
1960 err_code |= ERR_WARN;
1961 goto out;
1962 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01001963
Willy Tarreau3842f002009-06-14 11:39:52 +02001964 curproxy->no_options &= ~cfg_opts[optnum].val;
1965 curproxy->options &= ~cfg_opts[optnum].val;
1966
1967 switch (kwm) {
1968 case KWM_STD:
1969 curproxy->options |= cfg_opts[optnum].val;
1970 break;
1971 case KWM_NO:
1972 curproxy->no_options |= cfg_opts[optnum].val;
1973 break;
1974 case KWM_DEF: /* already cleared */
1975 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02001976 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01001977
Willy Tarreau93893792009-07-23 13:19:11 +02001978 goto out;
Willy Tarreau13943ab2006-12-31 00:24:10 +01001979 }
1980 }
1981
Willy Tarreau66aa61f2009-01-18 21:44:07 +01001982 for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
1983 if (!strcmp(args[1], cfg_opts2[optnum].name)) {
Willy Tarreau93893792009-07-23 13:19:11 +02001984 if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
1985 err_code |= ERR_WARN;
1986 goto out;
1987 }
Willy Tarreau66aa61f2009-01-18 21:44:07 +01001988
Willy Tarreau3842f002009-06-14 11:39:52 +02001989 curproxy->no_options2 &= ~cfg_opts2[optnum].val;
1990 curproxy->options2 &= ~cfg_opts2[optnum].val;
1991
1992 switch (kwm) {
1993 case KWM_STD:
1994 curproxy->options2 |= cfg_opts2[optnum].val;
1995 break;
1996 case KWM_NO:
1997 curproxy->no_options2 |= cfg_opts2[optnum].val;
1998 break;
1999 case KWM_DEF: /* already cleared */
2000 break;
Willy Tarreau84b57da2009-06-14 11:10:45 +02002001 }
Willy Tarreau93893792009-07-23 13:19:11 +02002002 goto out;
Willy Tarreau66aa61f2009-01-18 21:44:07 +01002003 }
2004 }
2005
Willy Tarreau3842f002009-06-14 11:39:52 +02002006 if (kwm != KWM_STD) {
2007 Alert("parsing [%s:%d]: negation/default is not supported for option '%s'.\n",
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01002008 file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002009 err_code |= ERR_ALERT | ERR_FATAL;
2010 goto out;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01002011 }
2012
Emeric Brun3a058f32009-06-30 18:26:00 +02002013 if (!strcmp(args[1], "httplog")) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02002014 /* generate a complete HTTP log */
Emeric Brun3a058f32009-06-30 18:26:00 +02002015 curproxy->options2 &= ~PR_O2_CLFLOG;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002016 curproxy->to_log |= LW_DATE | LW_CLIP | LW_SVID | LW_REQ | LW_PXID | LW_RESP | LW_BYTES;
Emeric Brun3a058f32009-06-30 18:26:00 +02002017 if (*(args[2]) != '\0') {
2018 if (!strcmp(args[2], "clf")) {
2019 curproxy->options2 |= PR_O2_CLFLOG;
2020 } else {
2021 Alert("parsing [%s:%d] : keyword '%s' only supports option 'clf'.\n", file, linenum, args[2]);
Willy Tarreau93893792009-07-23 13:19:11 +02002022 err_code |= ERR_ALERT | ERR_FATAL;
2023 goto out;
Emeric Brun3a058f32009-06-30 18:26:00 +02002024 }
2025 }
2026 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002027 else if (!strcmp(args[1], "tcplog"))
2028 /* generate a detailed TCP log */
2029 curproxy->to_log |= LW_DATE | LW_CLIP | LW_SVID | LW_PXID | LW_BYTES;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002030 else if (!strcmp(args[1], "tcpka")) {
2031 /* enable TCP keep-alives on client and server sessions */
Willy Tarreau13943ab2006-12-31 00:24:10 +01002032 if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002033 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01002034
2035 if (curproxy->cap & PR_CAP_FE)
2036 curproxy->options |= PR_O_TCP_CLI_KA;
2037 if (curproxy->cap & PR_CAP_BE)
2038 curproxy->options |= PR_O_TCP_SRV_KA;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002039 }
2040 else if (!strcmp(args[1], "httpchk")) {
Willy Tarreau13943ab2006-12-31 00:24:10 +01002041 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002042 err_code |= ERR_WARN;
2043
Willy Tarreaubaaee002006-06-26 02:48:02 +02002044 /* use HTTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02002045 free(curproxy->check_req);
Willy Tarreauf3c69202006-07-09 16:42:34 +02002046 curproxy->options &= ~PR_O_SSL3_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02002047 curproxy->options &= ~PR_O_SMTP_CHK;
2048 curproxy->options |= PR_O_HTTP_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002049 if (!*args[2]) { /* no argument */
2050 curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
2051 curproxy->check_len = strlen(DEF_CHECK_REQ);
2052 } else if (!*args[3]) { /* one argument : URI */
Willy Tarreau23677902007-05-08 23:50:35 +02002053 int reqlen = strlen(args[2]) + strlen("OPTIONS HTTP/1.0\r\n\r\n") + 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002054 curproxy->check_req = (char *)malloc(reqlen);
2055 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
2056 "OPTIONS %s HTTP/1.0\r\n\r\n", args[2]); /* URI to use */
2057 } else { /* more arguments : METHOD URI [HTTP_VER] */
2058 int reqlen = strlen(args[2]) + strlen(args[3]) + 3 + strlen("\r\n\r\n");
2059 if (*args[4])
2060 reqlen += strlen(args[4]);
2061 else
2062 reqlen += strlen("HTTP/1.0");
2063
2064 curproxy->check_req = (char *)malloc(reqlen);
2065 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
2066 "%s %s %s\r\n\r\n", args[2], args[3], *args[4]?args[4]:"HTTP/1.0");
2067 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02002068 }
2069 else if (!strcmp(args[1], "ssl-hello-chk")) {
2070 /* use SSLv3 CLIENT HELLO to check servers' health */
Willy Tarreau13943ab2006-12-31 00:24:10 +01002071 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002072 err_code |= ERR_WARN;
Willy Tarreau13943ab2006-12-31 00:24:10 +01002073
Willy Tarreaua534fea2008-08-03 12:19:50 +02002074 free(curproxy->check_req);
Willy Tarreauf3c69202006-07-09 16:42:34 +02002075 curproxy->options &= ~PR_O_HTTP_CHK;
Willy Tarreau23677902007-05-08 23:50:35 +02002076 curproxy->options &= ~PR_O_SMTP_CHK;
Willy Tarreauf3c69202006-07-09 16:42:34 +02002077 curproxy->options |= PR_O_SSL3_CHK;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002078 }
Willy Tarreau23677902007-05-08 23:50:35 +02002079 else if (!strcmp(args[1], "smtpchk")) {
2080 /* use SMTP request to check servers' health */
Willy Tarreaua534fea2008-08-03 12:19:50 +02002081 free(curproxy->check_req);
Willy Tarreau23677902007-05-08 23:50:35 +02002082 curproxy->options &= ~PR_O_HTTP_CHK;
2083 curproxy->options &= ~PR_O_SSL3_CHK;
2084 curproxy->options |= PR_O_SMTP_CHK;
2085
2086 if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
2087 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
2088 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
2089 } else { /* ESMTP EHLO, or SMTP HELO, and a hostname */
2090 if (!strcmp(args[2], "EHLO") || !strcmp(args[2], "HELO")) {
2091 int reqlen = strlen(args[2]) + strlen(args[3]) + strlen(" \r\n") + 1;
2092 curproxy->check_req = (char *)malloc(reqlen);
2093 curproxy->check_len = snprintf(curproxy->check_req, reqlen,
2094 "%s %s\r\n", args[2], args[3]); /* HELO hostname */
2095 } else {
2096 /* this just hits the default for now, but you could potentially expand it to allow for other stuff
2097 though, it's unlikely you'd want to send anything other than an EHLO or HELO */
2098 curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
2099 curproxy->check_len = strlen(DEF_SMTP_CHECK_REQ);
2100 }
2101 }
2102 }
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002103 else if (!strcmp(args[1], "forwardfor")) {
Ross Westaf72a1d2008-08-03 10:51:45 +02002104 int cur_arg;
2105
2106 /* insert x-forwarded-for field, but not for the IP address listed as an except.
2107 * set default options (ie: bitfield, header name, etc)
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002108 */
Ross Westaf72a1d2008-08-03 10:51:45 +02002109
2110 curproxy->options |= PR_O_FWDFOR;
2111
2112 free(curproxy->fwdfor_hdr_name);
2113 curproxy->fwdfor_hdr_name = strdup(DEF_XFORWARDFOR_HDR);
2114 curproxy->fwdfor_hdr_len = strlen(DEF_XFORWARDFOR_HDR);
2115
2116 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
2117 cur_arg = 2;
2118 while (*(args[cur_arg])) {
2119 if (!strcmp(args[cur_arg], "except")) {
2120 /* suboption except - needs additional argument for it */
2121 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], &curproxy->except_net, &curproxy->except_mask)) {
2122 Alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
2123 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002124 err_code |= ERR_ALERT | ERR_FATAL;
2125 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002126 }
2127 /* flush useless bits */
2128 curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
Ross Westaf72a1d2008-08-03 10:51:45 +02002129 cur_arg += 2;
2130 } else if (!strcmp(args[cur_arg], "header")) {
2131 /* suboption header - needs additional argument for it */
2132 if (*(args[cur_arg+1]) == 0) {
2133 Alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
2134 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002135 err_code |= ERR_ALERT | ERR_FATAL;
2136 goto out;
Ross Westaf72a1d2008-08-03 10:51:45 +02002137 }
2138 free(curproxy->fwdfor_hdr_name);
2139 curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
2140 curproxy->fwdfor_hdr_len = strlen(curproxy->fwdfor_hdr_name);
2141 cur_arg += 2;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002142 } else {
Ross Westaf72a1d2008-08-03 10:51:45 +02002143 /* unknown suboption - catchall */
2144 Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
2145 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002146 err_code |= ERR_ALERT | ERR_FATAL;
2147 goto out;
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002148 }
Ross Westaf72a1d2008-08-03 10:51:45 +02002149 } /* end while loop */
Willy Tarreau7ac51f62007-03-25 16:00:04 +02002150 }
Maik Broemme2850cb42009-04-17 18:53:21 +02002151 else if (!strcmp(args[1], "originalto")) {
2152 int cur_arg;
2153
2154 /* insert x-original-to field, but not for the IP address listed as an except.
2155 * set default options (ie: bitfield, header name, etc)
2156 */
2157
2158 curproxy->options |= PR_O_ORGTO;
2159
2160 free(curproxy->orgto_hdr_name);
2161 curproxy->orgto_hdr_name = strdup(DEF_XORIGINALTO_HDR);
2162 curproxy->orgto_hdr_len = strlen(DEF_XORIGINALTO_HDR);
2163
2164 /* loop to go through arguments - start at 2, since 0+1 = "option" "forwardfor" */
2165 cur_arg = 2;
2166 while (*(args[cur_arg])) {
2167 if (!strcmp(args[cur_arg], "except")) {
2168 /* suboption except - needs additional argument for it */
2169 if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], &curproxy->except_to, &curproxy->except_mask_to)) {
2170 Alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
2171 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002172 err_code |= ERR_ALERT | ERR_FATAL;
2173 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02002174 }
2175 /* flush useless bits */
2176 curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
2177 cur_arg += 2;
2178 } else if (!strcmp(args[cur_arg], "header")) {
2179 /* suboption header - needs additional argument for it */
2180 if (*(args[cur_arg+1]) == 0) {
2181 Alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
2182 file, linenum, args[0], args[1], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002183 err_code |= ERR_ALERT | ERR_FATAL;
2184 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02002185 }
2186 free(curproxy->orgto_hdr_name);
2187 curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
2188 curproxy->orgto_hdr_len = strlen(curproxy->orgto_hdr_name);
2189 cur_arg += 2;
2190 } else {
2191 /* unknown suboption - catchall */
2192 Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
2193 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002194 err_code |= ERR_ALERT | ERR_FATAL;
2195 goto out;
Maik Broemme2850cb42009-04-17 18:53:21 +02002196 }
2197 } /* end while loop */
2198 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002199 else {
2200 Alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002201 err_code |= ERR_ALERT | ERR_FATAL;
2202 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002203 }
Willy Tarreau93893792009-07-23 13:19:11 +02002204 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002205 }
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002206 else if (!strcmp(args[0], "default_backend")) {
2207 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002208 err_code |= ERR_WARN;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002209
2210 if (*(args[1]) == 0) {
2211 Alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002212 err_code |= ERR_ALERT | ERR_FATAL;
2213 goto out;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002214 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02002215 free(curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01002216 curproxy->defbe.name = strdup(args[1]);
2217 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002218 else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
Willy Tarreau977b8e42006-12-29 14:19:17 +01002219 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002220 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002221
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01002222 Warning("parsing [%s:%d]: keyword '%s' is deprecated, please use 'option redispatch' instead.\n",
2223 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002224 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002225 /* enable reconnections to dispatch */
2226 curproxy->options |= PR_O_REDISP;
2227 }
Willy Tarreau48494c02007-11-30 10:41:39 +01002228 else if (!strcmp(args[0], "http-check")) {
2229 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002230 err_code |= ERR_WARN;
Willy Tarreau48494c02007-11-30 10:41:39 +01002231
2232 if (strcmp(args[1], "disable-on-404") == 0) {
2233 /* enable a graceful server shutdown on an HTTP 404 response */
2234 curproxy->options |= PR_O_DISABLE404;
2235 }
2236 else {
2237 Alert("parsing [%s:%d] : '%s' only supports 'disable-on-404'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002238 err_code |= ERR_ALERT | ERR_FATAL;
2239 goto out;
Willy Tarreau48494c02007-11-30 10:41:39 +01002240 }
2241 }
Willy Tarreaub80c2302007-11-30 20:51:32 +01002242 else if (!strcmp(args[0], "monitor")) {
Willy Tarreaub099aca2008-10-12 17:26:37 +02002243 if (curproxy == &defproxy) {
2244 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002245 err_code |= ERR_ALERT | ERR_FATAL;
2246 goto out;
Willy Tarreaub099aca2008-10-12 17:26:37 +02002247 }
2248
Willy Tarreaub80c2302007-11-30 20:51:32 +01002249 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002250 err_code |= ERR_WARN;
Willy Tarreaub80c2302007-11-30 20:51:32 +01002251
2252 if (strcmp(args[1], "fail") == 0) {
2253 /* add a condition to fail monitor requests */
2254 int pol = ACL_COND_NONE;
2255 struct acl_cond *cond;
2256
2257 if (!strcmp(args[2], "if"))
2258 pol = ACL_COND_IF;
2259 else if (!strcmp(args[2], "unless"))
2260 pol = ACL_COND_UNLESS;
2261
2262 if (pol == ACL_COND_NONE) {
2263 Alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
2264 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002265 err_code |= ERR_ALERT | ERR_FATAL;
2266 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01002267 }
2268
2269 if ((cond = parse_acl_cond((const char **)args + 3, &curproxy->acl, pol)) == NULL) {
2270 Alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition.\n",
2271 file, linenum, args[0], args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002272 err_code |= ERR_ALERT | ERR_FATAL;
2273 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01002274 }
Willy Tarreaua9802632008-07-25 19:13:19 +02002275 cond->line = linenum;
Willy Tarreaua9fb0832009-07-10 20:53:53 +02002276 curproxy->acl_requires |= cond->requires;
Willy Tarreaub80c2302007-11-30 20:51:32 +01002277 LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
2278 }
2279 else {
2280 Alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002281 err_code |= ERR_ALERT | ERR_FATAL;
2282 goto out;
Willy Tarreaub80c2302007-11-30 20:51:32 +01002283 }
2284 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002285#ifdef TPROXY
2286 else if (!strcmp(args[0], "transparent")) {
2287 /* enable transparent proxy connections */
2288 curproxy->options |= PR_O_TRANSP;
2289 }
2290#endif
2291 else if (!strcmp(args[0], "maxconn")) { /* maxconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01002292 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02002293 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002294
Willy Tarreaubaaee002006-06-26 02:48:02 +02002295 if (*(args[1]) == 0) {
2296 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002297 err_code |= ERR_ALERT | ERR_FATAL;
2298 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002299 }
2300 curproxy->maxconn = atol(args[1]);
2301 }
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002302 else if (!strcmp(args[0], "backlog")) { /* backlog */
2303 if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002304 err_code |= ERR_WARN;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002305
2306 if (*(args[1]) == 0) {
2307 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002308 err_code |= ERR_ALERT | ERR_FATAL;
2309 goto out;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01002310 }
2311 curproxy->backlog = atol(args[1]);
2312 }
Willy Tarreau86034312006-12-29 00:10:33 +01002313 else if (!strcmp(args[0], "fullconn")) { /* fullconn */
Willy Tarreau977b8e42006-12-29 14:19:17 +01002314 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
Willy Tarreau93893792009-07-23 13:19:11 +02002315 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002316
Willy Tarreau86034312006-12-29 00:10:33 +01002317 if (*(args[1]) == 0) {
2318 Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002319 err_code |= ERR_ALERT | ERR_FATAL;
2320 goto out;
Willy Tarreau86034312006-12-29 00:10:33 +01002321 }
2322 curproxy->fullconn = atol(args[1]);
2323 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002324 else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
2325 if (*(args[1]) == 0) {
2326 Alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002327 err_code |= ERR_ALERT | ERR_FATAL;
2328 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002329 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002330 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
2331 if (err) {
2332 Alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
2333 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02002334 err_code |= ERR_ALERT | ERR_FATAL;
2335 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002336 }
2337 curproxy->grace = val;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002338 }
2339 else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
2340 if (curproxy == &defproxy) {
2341 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002342 err_code |= ERR_ALERT | ERR_FATAL;
2343 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002344 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002345 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002346 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002347
Willy Tarreaubaaee002006-06-26 02:48:02 +02002348 if (strchr(args[1], ':') == NULL) {
2349 Alert("parsing [%s:%d] : '%s' expects <addr:port> as argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002350 err_code |= ERR_ALERT | ERR_FATAL;
2351 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002352 }
2353 curproxy->dispatch_addr = *str2sa(args[1]);
2354 }
2355 else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
Willy Tarreau977b8e42006-12-29 14:19:17 +01002356 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002357 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002358
Jeffrey 'jf' Lim65cb2f12008-10-04 18:07:00 +02002359 memcpy(trash, "error near 'balance'", 21);
Willy Tarreaua0cbda62007-11-01 21:39:54 +01002360 if (backend_parse_balance((const char **)args + 1, trash, sizeof(trash), curproxy) < 0) {
2361 Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
Willy Tarreau93893792009-07-23 13:19:11 +02002362 err_code |= ERR_ALERT | ERR_FATAL;
2363 goto out;
Willy Tarreau2fcb5002007-05-08 13:35:26 +02002364 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002365 }
2366 else if (!strcmp(args[0], "server")) { /* server address */
2367 int cur_arg;
2368 char *rport;
2369 char *raddr;
2370 short realport;
2371 int do_check;
2372
2373 if (curproxy == &defproxy) {
2374 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002375 err_code |= ERR_ALERT | ERR_FATAL;
2376 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002377 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002378 else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002379 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002380
2381 if (!*args[2]) {
2382 Alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
2383 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002384 err_code |= ERR_ALERT | ERR_FATAL;
2385 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002386 }
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002387
2388 err = invalid_char(args[1]);
2389 if (err) {
2390 Alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
2391 file, linenum, *err, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02002392 err_code |= ERR_ALERT | ERR_FATAL;
2393 goto out;
Willy Tarreau2e74c3f2007-12-02 18:45:09 +01002394 }
2395
Willy Tarreaubaaee002006-06-26 02:48:02 +02002396 if ((newsrv = (struct server *)calloc(1, sizeof(struct server))) == NULL) {
2397 Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002398 err_code |= ERR_ALERT | ERR_ABORT;
2399 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002400 }
2401
2402 /* the servers are linked backwards first */
2403 newsrv->next = curproxy->srv;
2404 curproxy->srv = newsrv;
2405 newsrv->proxy = curproxy;
Willy Tarreaudcd47712007-11-04 23:35:08 +01002406 newsrv->puid = curproxy->next_svid++;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002407
2408 LIST_INIT(&newsrv->pendconns);
2409 do_check = 0;
2410 newsrv->state = SRV_RUNNING; /* early server setup */
Krzysztof Oledzki85130942007-10-22 16:21:10 +02002411 newsrv->last_change = now.tv_sec;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002412 newsrv->id = strdup(args[1]);
2413
2414 /* several ways to check the port component :
2415 * - IP => port=+0, relative
2416 * - IP: => port=+0, relative
2417 * - IP:N => port=N, absolute
2418 * - IP:+N => port=+N, relative
2419 * - IP:-N => port=-N, relative
2420 */
2421 raddr = strdup(args[2]);
2422 rport = strchr(raddr, ':');
2423 if (rport) {
2424 *rport++ = 0;
2425 realport = atol(rport);
Willy Tarreau8f8e6452007-06-17 21:51:38 +02002426 if (!isdigit((unsigned char)*rport))
Willy Tarreaubaaee002006-06-26 02:48:02 +02002427 newsrv->state |= SRV_MAPPORTS;
2428 } else {
2429 realport = 0;
2430 newsrv->state |= SRV_MAPPORTS;
2431 }
2432
2433 newsrv->addr = *str2sa(raddr);
2434 newsrv->addr.sin_port = htons(realport);
2435 free(raddr);
2436
2437 newsrv->curfd = -1; /* no health-check in progress */
2438 newsrv->inter = DEF_CHKINTR;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002439 newsrv->fastinter = 0; /* 0 => use newsrv->inter instead */
2440 newsrv->downinter = 0; /* 0 => use newsrv->inter instead */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002441 newsrv->rise = DEF_RISETIME;
2442 newsrv->fall = DEF_FALLTIME;
2443 newsrv->health = newsrv->rise; /* up, but will fall down at first failure */
Willy Tarreau417fae02007-03-25 21:16:40 +02002444 newsrv->uweight = 1;
Elijah Epifanovacafc5f2007-10-25 20:15:38 +02002445 newsrv->maxqueue = 0;
Willy Tarreau9909fc12007-11-30 17:42:05 +01002446 newsrv->slowstart = 0;
Willy Tarreau0f03c6f2007-03-25 20:46:19 +02002447
Willy Tarreaubaaee002006-06-26 02:48:02 +02002448 cur_arg = 3;
2449 while (*args[cur_arg]) {
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002450 if (!strcmp(args[cur_arg], "id")) {
2451 struct server *target;
2452
2453 if (!*args[cur_arg + 1]) {
2454 Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
2455 file, linenum, args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002456 err_code |= ERR_ALERT | ERR_FATAL;
2457 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002458 }
2459
2460 newsrv->puid = atol(args[cur_arg + 1]);
2461
2462 if (newsrv->puid< 1001) {
Krzysztof Piotr Oledzki08ff9592009-09-27 16:17:31 +02002463 Alert("parsing [%s:%d]: custom id has to be > 1000.\n",
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002464 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002465 err_code |= ERR_ALERT | ERR_FATAL;
2466 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002467 }
2468
2469 for (target = proxy->srv; target; target = target->next)
2470 if (newsrv != target && newsrv->puid == target->puid) {
2471 Alert("parsing [%s:%d]: custom id has to be unique but is duplicated in %s and %s.\n",
2472 file, linenum, newsrv->id, target->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002473 err_code |= ERR_ALERT | ERR_FATAL;
2474 goto out;
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002475 }
2476 cur_arg += 2;
2477 }
2478 else if (!strcmp(args[cur_arg], "cookie")) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02002479 newsrv->cookie = strdup(args[cur_arg + 1]);
2480 newsrv->cklen = strlen(args[cur_arg + 1]);
2481 cur_arg += 2;
2482 }
Willy Tarreau21d2af32008-02-14 20:25:24 +01002483 else if (!strcmp(args[cur_arg], "redir")) {
2484 newsrv->rdr_pfx = strdup(args[cur_arg + 1]);
2485 newsrv->rdr_len = strlen(args[cur_arg + 1]);
2486 cur_arg += 2;
2487 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002488 else if (!strcmp(args[cur_arg], "rise")) {
Krzysztof Piotr Oledzki08ff9592009-09-27 16:17:31 +02002489 if (!*args[cur_arg + 1]) {
2490 Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
2491 file, linenum, args[cur_arg]);
2492 err_code |= ERR_ALERT | ERR_FATAL;
2493 goto out;
2494 }
2495
Willy Tarreaubaaee002006-06-26 02:48:02 +02002496 newsrv->rise = atol(args[cur_arg + 1]);
Krzysztof Piotr Oledzki08ff9592009-09-27 16:17:31 +02002497 if (newsrv->rise <= 0) {
2498 Alert("parsing [%s:%d]: '%s' has to be > 0.\n",
2499 file, linenum, args[cur_arg]);
2500 err_code |= ERR_ALERT | ERR_FATAL;
2501 goto out;
2502 }
2503
Willy Tarreaubaaee002006-06-26 02:48:02 +02002504 newsrv->health = newsrv->rise;
2505 cur_arg += 2;
2506 }
2507 else if (!strcmp(args[cur_arg], "fall")) {
2508 newsrv->fall = atol(args[cur_arg + 1]);
Krzysztof Piotr Oledzki08ff9592009-09-27 16:17:31 +02002509
2510 if (!*args[cur_arg + 1]) {
2511 Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
2512 file, linenum, args[cur_arg]);
2513 err_code |= ERR_ALERT | ERR_FATAL;
2514 goto out;
2515 }
2516
2517 if (newsrv->fall <= 0) {
2518 Alert("parsing [%s:%d]: '%s' has to be > 0.\n",
2519 file, linenum, args[cur_arg]);
2520 err_code |= ERR_ALERT | ERR_FATAL;
2521 goto out;
2522 }
2523
Willy Tarreaubaaee002006-06-26 02:48:02 +02002524 cur_arg += 2;
2525 }
2526 else if (!strcmp(args[cur_arg], "inter")) {
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002527 const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS);
2528 if (err) {
2529 Alert("parsing [%s:%d] : unexpected character '%c' in 'inter' argument of server %s.\n",
2530 file, linenum, *err, newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002531 err_code |= ERR_ALERT | ERR_FATAL;
2532 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002533 }
Willy Tarreaue3838802009-03-21 18:58:32 +01002534 if (val <= 0) {
2535 Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2536 file, linenum, val, args[cur_arg], newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002537 err_code |= ERR_ALERT | ERR_FATAL;
2538 goto out;
Willy Tarreaue3838802009-03-21 18:58:32 +01002539 }
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002540 newsrv->inter = val;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002541 cur_arg += 2;
2542 }
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002543 else if (!strcmp(args[cur_arg], "fastinter")) {
2544 const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS);
2545 if (err) {
2546 Alert("parsing [%s:%d]: unexpected character '%c' in 'fastinter' argument of server %s.\n",
2547 file, linenum, *err, newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002548 err_code |= ERR_ALERT | ERR_FATAL;
2549 goto out;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002550 }
Willy Tarreaue3838802009-03-21 18:58:32 +01002551 if (val <= 0) {
2552 Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2553 file, linenum, val, args[cur_arg], newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002554 err_code |= ERR_ALERT | ERR_FATAL;
2555 goto out;
Willy Tarreaue3838802009-03-21 18:58:32 +01002556 }
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002557 newsrv->fastinter = val;
2558 cur_arg += 2;
2559 }
2560 else if (!strcmp(args[cur_arg], "downinter")) {
2561 const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS);
2562 if (err) {
2563 Alert("parsing [%s:%d]: unexpected character '%c' in 'downinter' argument of server %s.\n",
2564 file, linenum, *err, newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002565 err_code |= ERR_ALERT | ERR_FATAL;
2566 goto out;
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002567 }
Willy Tarreaue3838802009-03-21 18:58:32 +01002568 if (val <= 0) {
2569 Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2570 file, linenum, val, args[cur_arg], newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002571 err_code |= ERR_ALERT | ERR_FATAL;
2572 goto out;
Willy Tarreaue3838802009-03-21 18:58:32 +01002573 }
Krzysztof Piotr Oledzki5259dfe2008-01-21 01:54:06 +01002574 newsrv->downinter = val;
2575 cur_arg += 2;
2576 }
Willy Tarreau2ea3abb2007-03-25 16:45:16 +02002577 else if (!strcmp(args[cur_arg], "addr")) {
2578 newsrv->check_addr = *str2sa(args[cur_arg + 1]);
Willy Tarreau2ea3abb2007-03-25 16:45:16 +02002579 cur_arg += 2;
2580 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002581 else if (!strcmp(args[cur_arg], "port")) {
2582 newsrv->check_port = atol(args[cur_arg + 1]);
2583 cur_arg += 2;
2584 }
2585 else if (!strcmp(args[cur_arg], "backup")) {
2586 newsrv->state |= SRV_BACKUP;
2587 cur_arg ++;
2588 }
2589 else if (!strcmp(args[cur_arg], "weight")) {
2590 int w;
2591 w = atol(args[cur_arg + 1]);
Willy Tarreau6704d672009-06-15 10:56:05 +02002592 if (w < 0 || w > 256) {
2593 Alert("parsing [%s:%d] : weight of server %s is not within 0 and 256 (%d).\n",
Willy Tarreaubaaee002006-06-26 02:48:02 +02002594 file, linenum, newsrv->id, w);
Willy Tarreau93893792009-07-23 13:19:11 +02002595 err_code |= ERR_ALERT | ERR_FATAL;
2596 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002597 }
Willy Tarreau417fae02007-03-25 21:16:40 +02002598 newsrv->uweight = w;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002599 cur_arg += 2;
2600 }
2601 else if (!strcmp(args[cur_arg], "minconn")) {
2602 newsrv->minconn = atol(args[cur_arg + 1]);
2603 cur_arg += 2;
2604 }
2605 else if (!strcmp(args[cur_arg], "maxconn")) {
2606 newsrv->maxconn = atol(args[cur_arg + 1]);
2607 cur_arg += 2;
2608 }
Elijah Epifanovacafc5f2007-10-25 20:15:38 +02002609 else if (!strcmp(args[cur_arg], "maxqueue")) {
2610 newsrv->maxqueue = atol(args[cur_arg + 1]);
2611 cur_arg += 2;
2612 }
Willy Tarreau9909fc12007-11-30 17:42:05 +01002613 else if (!strcmp(args[cur_arg], "slowstart")) {
2614 /* slowstart is stored in seconds */
Willy Tarreau3259e332007-12-03 01:51:45 +01002615 const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS);
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002616 if (err) {
2617 Alert("parsing [%s:%d] : unexpected character '%c' in 'slowstart' argument of server %s.\n",
2618 file, linenum, *err, newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002619 err_code |= ERR_ALERT | ERR_FATAL;
2620 goto out;
Willy Tarreaub3f32f52007-12-02 22:15:14 +01002621 }
Willy Tarreaue3838802009-03-21 18:58:32 +01002622 if (val <= 0) {
2623 Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2624 file, linenum, val, args[cur_arg], newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002625 err_code |= ERR_ALERT | ERR_FATAL;
2626 goto out;
Willy Tarreaue3838802009-03-21 18:58:32 +01002627 }
Willy Tarreau3259e332007-12-03 01:51:45 +01002628 newsrv->slowstart = (val + 999) / 1000;
Willy Tarreau9909fc12007-11-30 17:42:05 +01002629 cur_arg += 2;
2630 }
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01002631 else if (!strcmp(args[cur_arg], "track")) {
2632
2633 if (!*args[cur_arg + 1]) {
2634 Alert("parsing [%s:%d]: 'track' expects [<proxy>/]<server> as argument.\n",
2635 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002636 err_code |= ERR_ALERT | ERR_FATAL;
2637 goto out;
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01002638 }
2639
2640 newsrv->trackit = strdup(args[cur_arg + 1]);
2641
2642 cur_arg += 2;
2643 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002644 else if (!strcmp(args[cur_arg], "check")) {
2645 global.maxsock++;
2646 do_check = 1;
2647 cur_arg += 1;
2648 }
2649 else if (!strcmp(args[cur_arg], "source")) { /* address to which we bind when connecting */
Willy Tarreauc6f4ce82009-06-10 11:09:37 +02002650 int port_low, port_high;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002651 if (!*args[cur_arg + 1]) {
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002652#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
Willy Tarreauc6f4ce82009-06-10 11:09:37 +02002653 Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>[-<port>]], and optional '%s' <addr> as argument.\n",
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002654 file, linenum, "source", "usesrc");
2655#else
Willy Tarreauc6f4ce82009-06-10 11:09:37 +02002656 Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>[-<port>]] as argument.\n",
Willy Tarreaubaaee002006-06-26 02:48:02 +02002657 file, linenum, "source");
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002658#endif
Willy Tarreau93893792009-07-23 13:19:11 +02002659 err_code |= ERR_ALERT | ERR_FATAL;
2660 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002661 }
2662 newsrv->state |= SRV_BIND_SRC;
Willy Tarreauc6f4ce82009-06-10 11:09:37 +02002663 newsrv->source_addr = *str2sa_range(args[cur_arg + 1], &port_low, &port_high);
2664
2665 if (port_low != port_high) {
2666 int i;
2667 if (port_low <= 0 || port_low > 65535 ||
2668 port_high <= 0 || port_high > 65535 ||
2669 port_low > port_high) {
2670 Alert("parsing [%s:%d] : invalid source port range %d-%d.\n",
2671 file, linenum, port_low, port_high);
Willy Tarreau93893792009-07-23 13:19:11 +02002672 err_code |= ERR_ALERT | ERR_FATAL;
2673 goto out;
Willy Tarreauc6f4ce82009-06-10 11:09:37 +02002674 }
2675 newsrv->sport_range = port_range_alloc_range(port_high - port_low + 1);
2676 for (i = 0; i < newsrv->sport_range->size; i++)
2677 newsrv->sport_range->ports[i] = port_low + i;
2678 }
2679
Willy Tarreaubaaee002006-06-26 02:48:02 +02002680 cur_arg += 2;
Willy Tarreauc76721d2009-02-04 20:20:58 +01002681 while (*(args[cur_arg])) {
2682 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002683#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
2684#if !defined(CONFIG_HAP_LINUX_TPROXY)
Willy Tarreauc76721d2009-02-04 20:20:58 +01002685 if (newsrv->source_addr.sin_addr.s_addr == INADDR_ANY) {
2686 Alert("parsing [%s:%d] : '%s' requires an explicit '%s' address.\n",
2687 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02002688 err_code |= ERR_ALERT | ERR_FATAL;
2689 goto out;
Willy Tarreauc76721d2009-02-04 20:20:58 +01002690 }
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002691#endif
Willy Tarreauc76721d2009-02-04 20:20:58 +01002692 if (!*args[cur_arg + 1]) {
2693 Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
2694 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02002695 err_code |= ERR_ALERT | ERR_FATAL;
2696 goto out;
Willy Tarreauc76721d2009-02-04 20:20:58 +01002697 }
2698 if (!strcmp(args[cur_arg + 1], "client")) {
2699 newsrv->state |= SRV_TPROXY_CLI;
2700 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
2701 newsrv->state |= SRV_TPROXY_CIP;
2702 } else {
2703 newsrv->state |= SRV_TPROXY_ADDR;
2704 newsrv->tproxy_addr = *str2sa(args[cur_arg + 1]);
2705 }
2706 global.last_checks |= LSTCHK_NETADM;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002707#if !defined(CONFIG_HAP_LINUX_TPROXY)
Willy Tarreauc76721d2009-02-04 20:20:58 +01002708 global.last_checks |= LSTCHK_CTTPROXY;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002709#endif
Willy Tarreauc76721d2009-02-04 20:20:58 +01002710 cur_arg += 2;
2711 continue;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002712#else /* no TPROXY support */
Willy Tarreauc76721d2009-02-04 20:20:58 +01002713 Alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002714 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02002715 err_code |= ERR_ALERT | ERR_FATAL;
2716 goto out;
Willy Tarreauc76721d2009-02-04 20:20:58 +01002717#endif /* defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY) */
2718 } /* "usesrc" */
2719
2720 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
2721#ifdef SO_BINDTODEVICE
2722 if (!*args[cur_arg + 1]) {
2723 Alert("parsing [%s:%d] : '%s' : missing interface name.\n",
2724 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002725 err_code |= ERR_ALERT | ERR_FATAL;
2726 goto out;
Willy Tarreauc76721d2009-02-04 20:20:58 +01002727 }
2728 if (newsrv->iface_name)
2729 free(newsrv->iface_name);
2730
2731 newsrv->iface_name = strdup(args[cur_arg + 1]);
2732 newsrv->iface_len = strlen(newsrv->iface_name);
2733 global.last_checks |= LSTCHK_NETADM;
2734#else
2735 Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
2736 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002737 err_code |= ERR_ALERT | ERR_FATAL;
2738 goto out;
Willy Tarreau77074d52006-11-12 23:57:19 +01002739#endif
Willy Tarreauc76721d2009-02-04 20:20:58 +01002740 cur_arg += 2;
2741 continue;
2742 }
2743 /* this keyword in not an option of "source" */
2744 break;
2745 } /* while */
Willy Tarreaubaaee002006-06-26 02:48:02 +02002746 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002747 else if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside: needs "source" first */
2748 Alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
2749 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02002750 err_code |= ERR_ALERT | ERR_FATAL;
2751 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002752 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002753 else {
Krzysztof Piotr Oledzkif58a9622008-02-23 01:19:10 +01002754 Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'track', 'id', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
Willy Tarreaubaaee002006-06-26 02:48:02 +02002755 file, linenum, newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002756 err_code |= ERR_ALERT | ERR_FATAL;
2757 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002758 }
2759 }
2760
2761 if (do_check) {
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01002762 if (newsrv->trackit) {
2763 Alert("parsing [%s:%d]: unable to enable checks and tracking at the same time!\n",
2764 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002765 err_code |= ERR_ALERT | ERR_FATAL;
2766 goto out;
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01002767 }
2768
Willy Tarreau0f03c6f2007-03-25 20:46:19 +02002769 if (!newsrv->check_port && newsrv->check_addr.sin_port)
2770 newsrv->check_port = newsrv->check_addr.sin_port;
2771
Willy Tarreaubaaee002006-06-26 02:48:02 +02002772 if (!newsrv->check_port && !(newsrv->state & SRV_MAPPORTS))
2773 newsrv->check_port = realport; /* by default */
2774 if (!newsrv->check_port) {
Willy Tarreauef00b502007-01-07 02:40:09 +01002775 /* not yet valid, because no port was set on
2776 * the server either. We'll check if we have
2777 * a known port on the first listener.
2778 */
2779 struct listener *l;
2780 l = curproxy->listen;
2781 if (l) {
2782 int port;
2783 port = (l->addr.ss_family == AF_INET6)
2784 ? ntohs(((struct sockaddr_in6 *)(&l->addr))->sin6_port)
2785 : ntohs(((struct sockaddr_in *)(&l->addr))->sin_port);
2786 newsrv->check_port = port;
2787 }
2788 }
2789 if (!newsrv->check_port) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02002790 Alert("parsing [%s:%d] : server %s has neither service port nor check port. Check has been disabled.\n",
2791 file, linenum, newsrv->id);
Willy Tarreau93893792009-07-23 13:19:11 +02002792 err_code |= ERR_ALERT | ERR_FATAL;
2793 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002794 }
Krzysztof Piotr Oledzki09605412009-09-23 22:09:24 +02002795
2796 newsrv->check_status = HCHK_STATUS_INI;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002797 newsrv->state |= SRV_CHECKED;
2798 }
2799
2800 if (newsrv->state & SRV_BACKUP)
2801 curproxy->srv_bck++;
2802 else
2803 curproxy->srv_act++;
Willy Tarreaub625a082007-11-26 01:15:43 +01002804
2805 newsrv->prev_state = newsrv->state;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002806 }
2807 else if (!strcmp(args[0], "log")) { /* syslog server address */
Robert Tsai81ae1952007-12-05 10:47:29 +01002808 struct logsrv logsrv;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002809 int facility;
2810
2811 if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
2812 curproxy->logfac1 = global.logfac1;
2813 curproxy->logsrv1 = global.logsrv1;
2814 curproxy->loglev1 = global.loglev1;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02002815 curproxy->minlvl1 = global.minlvl1;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002816 curproxy->logfac2 = global.logfac2;
2817 curproxy->logsrv2 = global.logsrv2;
2818 curproxy->loglev2 = global.loglev2;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02002819 curproxy->minlvl2 = global.minlvl2;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002820 }
2821 else if (*(args[1]) && *(args[2])) {
Willy Tarreauf7edefa2009-05-10 17:20:05 +02002822 int level, minlvl;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002823
2824 facility = get_log_facility(args[2]);
2825 if (facility < 0) {
2826 Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
2827 exit(1);
2828 }
2829
2830 level = 7; /* max syslog level = debug */
2831 if (*(args[3])) {
2832 level = get_log_level(args[3]);
2833 if (level < 0) {
2834 Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
2835 exit(1);
2836 }
2837 }
2838
Willy Tarreauf7edefa2009-05-10 17:20:05 +02002839 minlvl = 0; /* limit syslog level to this level (emerg) */
2840 if (*(args[4])) {
2841 minlvl = get_log_level(args[4]);
2842 if (level < 0) {
2843 Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
2844 exit(1);
2845 }
2846 }
2847
Robert Tsai81ae1952007-12-05 10:47:29 +01002848 if (args[1][0] == '/') {
2849 logsrv.u.addr.sa_family = AF_UNIX;
2850 logsrv.u.un = *str2sun(args[1]);
2851 } else {
2852 logsrv.u.addr.sa_family = AF_INET;
2853 logsrv.u.in = *str2sa(args[1]);
2854 if (!logsrv.u.in.sin_port) {
2855 logsrv.u.in.sin_port =
2856 htons(SYSLOG_PORT);
2857 }
2858 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002859
2860 if (curproxy->logfac1 == -1) {
Robert Tsai81ae1952007-12-05 10:47:29 +01002861 curproxy->logsrv1 = logsrv;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002862 curproxy->logfac1 = facility;
2863 curproxy->loglev1 = level;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02002864 curproxy->minlvl1 = minlvl;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002865 }
2866 else if (curproxy->logfac2 == -1) {
Robert Tsai81ae1952007-12-05 10:47:29 +01002867 curproxy->logsrv2 = logsrv;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002868 curproxy->logfac2 = facility;
2869 curproxy->loglev2 = level;
Willy Tarreauf7edefa2009-05-10 17:20:05 +02002870 curproxy->minlvl2 = minlvl;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002871 }
2872 else {
2873 Alert("parsing [%s:%d] : too many syslog servers\n", file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002874 err_code |= ERR_ALERT | ERR_FATAL;
2875 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002876 }
2877 }
2878 else {
2879 Alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
2880 file, linenum);
Willy Tarreau93893792009-07-23 13:19:11 +02002881 err_code |= ERR_ALERT | ERR_FATAL;
2882 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002883 }
2884 }
2885 else if (!strcmp(args[0], "source")) { /* address to which we bind when connecting */
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002886 int cur_arg;
2887
Willy Tarreau977b8e42006-12-29 14:19:17 +01002888 if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002889 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002890
Willy Tarreaubaaee002006-06-26 02:48:02 +02002891 if (!*args[1]) {
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002892 Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
2893 file, linenum, "source", "usesrc", "interface");
Willy Tarreau93893792009-07-23 13:19:11 +02002894 err_code |= ERR_ALERT | ERR_FATAL;
2895 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002896 }
Willy Tarreau368480c2009-03-01 08:27:21 +01002897
2898 /* we must first clear any optional default setting */
2899 curproxy->options &= ~PR_O_TPXY_MASK;
2900 free(curproxy->iface_name);
2901 curproxy->iface_name = NULL;
2902 curproxy->iface_len = 0;
2903
Willy Tarreaubaaee002006-06-26 02:48:02 +02002904 curproxy->source_addr = *str2sa(args[1]);
2905 curproxy->options |= PR_O_BIND_SRC;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002906
2907 cur_arg = 2;
2908 while (*(args[cur_arg])) {
2909 if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002910#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
2911#if !defined(CONFIG_HAP_LINUX_TPROXY)
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002912 if (curproxy->source_addr.sin_addr.s_addr == INADDR_ANY) {
2913 Alert("parsing [%s:%d] : '%s' requires an explicit 'source' address.\n",
2914 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02002915 err_code |= ERR_ALERT | ERR_FATAL;
2916 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002917 }
2918#endif
2919 if (!*args[cur_arg + 1]) {
2920 Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
2921 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02002922 err_code |= ERR_ALERT | ERR_FATAL;
2923 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002924 }
2925
2926 if (!strcmp(args[cur_arg + 1], "client")) {
2927 curproxy->options |= PR_O_TPXY_CLI;
2928 } else if (!strcmp(args[cur_arg + 1], "clientip")) {
2929 curproxy->options |= PR_O_TPXY_CIP;
2930 } else {
2931 curproxy->options |= PR_O_TPXY_ADDR;
2932 curproxy->tproxy_addr = *str2sa(args[cur_arg + 1]);
2933 }
2934 global.last_checks |= LSTCHK_NETADM;
2935#if !defined(CONFIG_HAP_LINUX_TPROXY)
2936 global.last_checks |= LSTCHK_CTTPROXY;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002937#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002938#else /* no TPROXY support */
2939 Alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
Willy Tarreau77074d52006-11-12 23:57:19 +01002940 file, linenum, "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02002941 err_code |= ERR_ALERT | ERR_FATAL;
2942 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002943#endif
2944 cur_arg += 2;
2945 continue;
Willy Tarreau77074d52006-11-12 23:57:19 +01002946 }
2947
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002948 if (!strcmp(args[cur_arg], "interface")) { /* specifically bind to this interface */
2949#ifdef SO_BINDTODEVICE
2950 if (!*args[cur_arg + 1]) {
2951 Alert("parsing [%s:%d] : '%s' : missing interface name.\n",
2952 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002953 err_code |= ERR_ALERT | ERR_FATAL;
2954 goto out;
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002955 }
2956 if (curproxy->iface_name)
2957 free(curproxy->iface_name);
2958
2959 curproxy->iface_name = strdup(args[cur_arg + 1]);
2960 curproxy->iface_len = strlen(curproxy->iface_name);
2961 global.last_checks |= LSTCHK_NETADM;
2962#else
2963 Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
2964 file, linenum, args[0], args[cur_arg]);
Willy Tarreau93893792009-07-23 13:19:11 +02002965 err_code |= ERR_ALERT | ERR_FATAL;
2966 goto out;
Willy Tarreau5b6995c2008-01-13 16:31:17 +01002967#endif
Willy Tarreaud53f96b2009-02-04 18:46:54 +01002968 cur_arg += 2;
2969 continue;
2970 }
2971 Alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
2972 file, linenum, args[0], "inteface", "usesrc");
Willy Tarreau93893792009-07-23 13:19:11 +02002973 err_code |= ERR_ALERT | ERR_FATAL;
2974 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002975 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002976 }
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002977 else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
2978 Alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
2979 file, linenum, "usesrc", "source");
Willy Tarreau93893792009-07-23 13:19:11 +02002980 err_code |= ERR_ALERT | ERR_FATAL;
2981 goto out;
Willy Tarreau8d9246d2007-03-24 12:47:24 +01002982 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02002983 else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
2984 regex_t *preg;
2985 if (curproxy == &defproxy) {
2986 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002987 err_code |= ERR_ALERT | ERR_FATAL;
2988 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002989 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01002990 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02002991 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01002992
Willy Tarreaubaaee002006-06-26 02:48:02 +02002993 if (*(args[1]) == 0 || *(args[2]) == 0) {
2994 Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
2995 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02002996 err_code |= ERR_ALERT | ERR_FATAL;
2997 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02002998 }
2999
3000 preg = calloc(1, sizeof(regex_t));
3001 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3002 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003003 err_code |= ERR_ALERT | ERR_FATAL;
3004 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003005 }
3006
3007 err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]));
3008 if (err) {
3009 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3010 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003011 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003012 }
Willy Tarreau61d18892009-03-31 10:49:21 +02003013 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003014 }
3015 else if (!strcmp(args[0], "reqdel")) { /* delete request header from a regex */
3016 regex_t *preg;
3017 if (curproxy == &defproxy) {
3018 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003019 err_code |= ERR_ALERT | ERR_FATAL;
3020 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003021 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003022 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003023 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003024
Willy Tarreaubaaee002006-06-26 02:48:02 +02003025 if (*(args[1]) == 0) {
3026 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003027 err_code |= ERR_ALERT | ERR_FATAL;
3028 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003029 }
3030
3031 preg = calloc(1, sizeof(regex_t));
3032 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3033 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003034 err_code |= ERR_ALERT | ERR_FATAL;
3035 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003036 }
3037
3038 chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003039 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003040 }
3041 else if (!strcmp(args[0], "reqdeny")) { /* deny a request if a header matches this regex */
3042 regex_t *preg;
3043 if (curproxy == &defproxy) {
3044 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003045 err_code |= ERR_ALERT | ERR_FATAL;
3046 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003047 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003048 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003049 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003050
Willy Tarreaubaaee002006-06-26 02:48:02 +02003051 if (*(args[1]) == 0) {
3052 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003053 err_code |= ERR_ALERT | ERR_FATAL;
3054 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003055 }
3056
3057 preg = calloc(1, sizeof(regex_t));
3058 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3059 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003060 err_code |= ERR_ALERT | ERR_FATAL;
3061 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003062 }
3063
3064 chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003065 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003066 }
3067 else if (!strcmp(args[0], "reqpass")) { /* pass this header without allowing or denying the request */
3068 regex_t *preg;
3069 if (curproxy == &defproxy) {
3070 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003071 err_code |= ERR_ALERT | ERR_FATAL;
3072 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003073 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003074 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003075 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003076
Willy Tarreaubaaee002006-06-26 02:48:02 +02003077 if (*(args[1]) == 0) {
3078 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003079 err_code |= ERR_ALERT | ERR_FATAL;
3080 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003081 }
3082
3083 preg = calloc(1, sizeof(regex_t));
3084 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3085 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003086 err_code |= ERR_ALERT | ERR_FATAL;
3087 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003088 }
3089
3090 chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003091 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003092 }
3093 else if (!strcmp(args[0], "reqallow")) { /* allow a request if a header matches this regex */
3094 regex_t *preg;
3095 if (curproxy == &defproxy) {
3096 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003097 err_code |= ERR_ALERT | ERR_FATAL;
3098 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003099 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003100 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003101 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003102
Willy Tarreaubaaee002006-06-26 02:48:02 +02003103 if (*(args[1]) == 0) {
3104 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003105 err_code |= ERR_ALERT | ERR_FATAL;
3106 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003107 }
3108
3109 preg = calloc(1, sizeof(regex_t));
3110 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3111 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003112 err_code |= ERR_ALERT | ERR_FATAL;
3113 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003114 }
3115
3116 chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003117 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003118 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02003119 else if (!strcmp(args[0], "reqtarpit")) { /* tarpit a request if a header matches this regex */
3120 regex_t *preg;
3121 if (curproxy == &defproxy) {
3122 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003123 err_code |= ERR_ALERT | ERR_FATAL;
3124 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02003125 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003126 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003127 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003128
Willy Tarreaub8750a82006-09-03 09:56:00 +02003129 if (*(args[1]) == 0) {
3130 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003131 err_code |= ERR_ALERT | ERR_FATAL;
3132 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02003133 }
3134
3135 preg = calloc(1, sizeof(regex_t));
3136 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3137 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003138 err_code |= ERR_ALERT | ERR_FATAL;
3139 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02003140 }
3141
3142 chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003143 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaub8750a82006-09-03 09:56:00 +02003144 }
Willy Tarreaua496b602006-12-17 23:15:24 +01003145 else if (!strcmp(args[0], "reqsetbe")) { /* switch the backend from a regex, respecting case */
3146 regex_t *preg;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003147 if (curproxy == &defproxy) {
Willy Tarreaua496b602006-12-17 23:15:24 +01003148 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003149 err_code |= ERR_ALERT | ERR_FATAL;
3150 goto out;
Willy Tarreaua496b602006-12-17 23:15:24 +01003151 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003152 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003153 err_code |= ERR_WARN;
Willy Tarreaua496b602006-12-17 23:15:24 +01003154
Willy Tarreau977b8e42006-12-29 14:19:17 +01003155 if (*(args[1]) == 0 || *(args[2]) == 0) {
Willy Tarreaua496b602006-12-17 23:15:24 +01003156 Alert("parsing [%s:%d] : '%s' expects <search> and <target> as arguments.\n",
3157 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003158 err_code |= ERR_ALERT | ERR_FATAL;
3159 goto out;
Willy Tarreaua496b602006-12-17 23:15:24 +01003160 }
3161
3162 preg = calloc(1, sizeof(regex_t));
Willy Tarreau977b8e42006-12-29 14:19:17 +01003163 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
Willy Tarreaua496b602006-12-17 23:15:24 +01003164 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003165 err_code |= ERR_ALERT | ERR_FATAL;
3166 goto out;
Willy Tarreaua496b602006-12-17 23:15:24 +01003167 }
3168
3169 chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2]));
Willy Tarreau61d18892009-03-31 10:49:21 +02003170 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaua496b602006-12-17 23:15:24 +01003171 }
3172 else if (!strcmp(args[0], "reqisetbe")) { /* switch the backend from a regex, ignoring case */
3173 regex_t *preg;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003174 if (curproxy == &defproxy) {
Willy Tarreaua496b602006-12-17 23:15:24 +01003175 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003176 err_code |= ERR_ALERT | ERR_FATAL;
3177 goto out;
Willy Tarreaua496b602006-12-17 23:15:24 +01003178 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003179 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003180 err_code |= ERR_WARN;
Willy Tarreaua496b602006-12-17 23:15:24 +01003181
Willy Tarreau977b8e42006-12-29 14:19:17 +01003182 if (*(args[1]) == 0 || *(args[2]) == 0) {
Willy Tarreaua496b602006-12-17 23:15:24 +01003183 Alert("parsing [%s:%d] : '%s' expects <search> and <target> as arguments.\n",
3184 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003185 err_code |= ERR_ALERT | ERR_FATAL;
3186 goto out;
Willy Tarreaua496b602006-12-17 23:15:24 +01003187 }
3188
3189 preg = calloc(1, sizeof(regex_t));
Willy Tarreau977b8e42006-12-29 14:19:17 +01003190 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
Willy Tarreaua496b602006-12-17 23:15:24 +01003191 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003192 err_code |= ERR_ALERT | ERR_FATAL;
3193 goto out;
Willy Tarreaua496b602006-12-17 23:15:24 +01003194 }
3195
3196 chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2]));
Willy Tarreau61d18892009-03-31 10:49:21 +02003197 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaua496b602006-12-17 23:15:24 +01003198 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003199 else if (!strcmp(args[0], "reqirep")) { /* replace request header from a regex, ignoring case */
3200 regex_t *preg;
3201 if (curproxy == &defproxy) {
3202 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003203 err_code |= ERR_ALERT | ERR_FATAL;
3204 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003205 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003206 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003207 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003208
Willy Tarreaubaaee002006-06-26 02:48:02 +02003209 if (*(args[1]) == 0 || *(args[2]) == 0) {
3210 Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
3211 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003212 err_code |= ERR_ALERT | ERR_FATAL;
3213 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003214 }
3215
3216 preg = calloc(1, sizeof(regex_t));
3217 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3218 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003219 err_code |= ERR_ALERT | ERR_FATAL;
3220 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003221 }
3222
3223 err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]));
3224 if (err) {
3225 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3226 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003227 err_code |= ERR_ALERT | ERR_FATAL;
3228 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003229 }
Willy Tarreau61d18892009-03-31 10:49:21 +02003230 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003231 }
3232 else if (!strcmp(args[0], "reqidel")) { /* delete request header from a regex ignoring case */
3233 regex_t *preg;
3234 if (curproxy == &defproxy) {
3235 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003236 err_code |= ERR_ALERT | ERR_FATAL;
3237 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003238 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003239 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003240 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003241
Willy Tarreaubaaee002006-06-26 02:48:02 +02003242 if (*(args[1]) == 0) {
3243 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003244 err_code |= ERR_ALERT | ERR_FATAL;
3245 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003246 }
3247
3248 preg = calloc(1, sizeof(regex_t));
3249 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3250 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003251 err_code |= ERR_ALERT | ERR_FATAL;
3252 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003253 }
3254
3255 chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003256 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003257 }
3258 else if (!strcmp(args[0], "reqideny")) { /* deny a request if a header matches this regex ignoring case */
3259 regex_t *preg;
3260 if (curproxy == &defproxy) {
3261 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003262 err_code |= ERR_ALERT | ERR_FATAL;
3263 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003264 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003265 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003266 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003267
Willy Tarreaubaaee002006-06-26 02:48:02 +02003268 if (*(args[1]) == 0) {
3269 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003270 err_code |= ERR_ALERT | ERR_FATAL;
3271 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003272 }
3273
3274 preg = calloc(1, sizeof(regex_t));
3275 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3276 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003277 err_code |= ERR_ALERT | ERR_FATAL;
3278 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003279 }
3280
3281 chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003282 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003283 }
3284 else if (!strcmp(args[0], "reqipass")) { /* pass this header without allowing or denying the request */
3285 regex_t *preg;
3286 if (curproxy == &defproxy) {
3287 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003288 err_code |= ERR_ALERT | ERR_FATAL;
3289 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003290 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003291 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003292 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003293
Willy Tarreaubaaee002006-06-26 02:48:02 +02003294 if (*(args[1]) == 0) {
3295 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003296 err_code |= ERR_ALERT | ERR_FATAL;
3297 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003298 }
3299
3300 preg = calloc(1, sizeof(regex_t));
3301 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3302 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003303 err_code |= ERR_ALERT | ERR_FATAL;
3304 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003305 }
3306
3307 chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003308 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003309 }
3310 else if (!strcmp(args[0], "reqiallow")) { /* allow a request if a header matches this regex ignoring case */
3311 regex_t *preg;
3312 if (curproxy == &defproxy) {
3313 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003314 err_code |= ERR_ALERT | ERR_FATAL;
3315 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003316 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003317 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003318 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003319
Willy Tarreaubaaee002006-06-26 02:48:02 +02003320 if (*(args[1]) == 0) {
3321 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003322 err_code |= ERR_ALERT | ERR_FATAL;
3323 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003324 }
3325
3326 preg = calloc(1, sizeof(regex_t));
3327 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3328 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003329 err_code |= ERR_ALERT | ERR_FATAL;
3330 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003331 }
3332
3333 chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003334 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003335 }
Willy Tarreaub8750a82006-09-03 09:56:00 +02003336 else if (!strcmp(args[0], "reqitarpit")) { /* tarpit a request if a header matches this regex ignoring case */
3337 regex_t *preg;
3338 if (curproxy == &defproxy) {
3339 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003340 err_code |= ERR_ALERT | ERR_FATAL;
3341 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02003342 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003343 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003344 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003345
Willy Tarreaub8750a82006-09-03 09:56:00 +02003346 if (*(args[1]) == 0) {
3347 Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003348 err_code |= ERR_ALERT | ERR_FATAL;
3349 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02003350 }
3351
3352 preg = calloc(1, sizeof(regex_t));
3353 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3354 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003355 err_code |= ERR_ALERT | ERR_FATAL;
3356 goto out;
Willy Tarreaub8750a82006-09-03 09:56:00 +02003357 }
3358
3359 chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL);
Willy Tarreau61d18892009-03-31 10:49:21 +02003360 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaub8750a82006-09-03 09:56:00 +02003361 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003362 else if (!strcmp(args[0], "reqadd")) { /* add request header */
3363 if (curproxy == &defproxy) {
3364 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003365 err_code |= ERR_ALERT | ERR_FATAL;
3366 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003367 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003368 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003369 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003370
3371 if (curproxy->nb_reqadd >= MAX_NEWHDR) {
3372 Alert("parsing [%s:%d] : too many '%s'. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003373 err_code |= ERR_ALERT | ERR_FATAL;
3374 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003375 }
3376
3377 if (*(args[1]) == 0) {
3378 Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003379 err_code |= ERR_ALERT | ERR_FATAL;
3380 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003381 }
3382
3383 curproxy->req_add[curproxy->nb_reqadd++] = strdup(args[1]);
Willy Tarreau61d18892009-03-31 10:49:21 +02003384 warnif_misplaced_reqadd(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003385 }
3386 else if (!strcmp(args[0], "srvexp") || !strcmp(args[0], "rsprep")) { /* replace response header from a regex */
3387 regex_t *preg;
3388
3389 if (*(args[1]) == 0 || *(args[2]) == 0) {
3390 Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
3391 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003392 err_code |= ERR_ALERT | ERR_FATAL;
3393 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003394 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003395 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003396 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003397
Willy Tarreaubaaee002006-06-26 02:48:02 +02003398 preg = calloc(1, sizeof(regex_t));
3399 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3400 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003401 err_code |= ERR_ALERT | ERR_FATAL;
3402 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003403 }
3404
3405 err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2]));
3406 if (err) {
3407 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3408 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003409 err_code |= ERR_ALERT | ERR_FATAL;
3410 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003411 }
Willy Tarreau61d18892009-03-31 10:49:21 +02003412 warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003413 }
3414 else if (!strcmp(args[0], "rspdel")) { /* delete response header from a regex */
3415 regex_t *preg;
3416 if (curproxy == &defproxy) {
3417 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003418 err_code |= ERR_ALERT | ERR_FATAL;
3419 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003420 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003421 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003422 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003423
Willy Tarreaubaaee002006-06-26 02:48:02 +02003424 if (*(args[1]) == 0) {
3425 Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003426 err_code |= ERR_ALERT | ERR_FATAL;
3427 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003428 }
3429
3430 preg = calloc(1, sizeof(regex_t));
3431 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3432 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003433 err_code |= ERR_ALERT | ERR_FATAL;
3434 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003435 }
3436
3437 err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]));
3438 if (err) {
3439 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3440 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003441 err_code |= ERR_ALERT | ERR_FATAL;
3442 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003443 }
3444 }
3445 else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
3446 regex_t *preg;
3447 if (curproxy == &defproxy) {
3448 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003449 err_code |= ERR_ALERT | ERR_FATAL;
3450 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003451 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003452 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003453 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003454
Willy Tarreaubaaee002006-06-26 02:48:02 +02003455 if (*(args[1]) == 0) {
3456 Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003457 err_code |= ERR_ALERT | ERR_FATAL;
3458 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003459 }
3460
3461 preg = calloc(1, sizeof(regex_t));
3462 if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
3463 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003464 err_code |= ERR_ALERT | ERR_FATAL;
3465 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003466 }
3467
3468 err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]));
3469 if (err) {
3470 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3471 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003472 err_code |= ERR_ALERT | ERR_FATAL;
3473 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003474 }
3475 }
3476 else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
3477 regex_t *preg;
3478 if (curproxy == &defproxy) {
3479 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003480 err_code |= ERR_ALERT | ERR_FATAL;
3481 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003482 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003483 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003484 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003485
3486 if (*(args[1]) == 0 || *(args[2]) == 0) {
3487 Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
3488 file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003489 err_code |= ERR_ALERT | ERR_FATAL;
3490 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003491 }
3492
3493 preg = calloc(1, sizeof(regex_t));
3494 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3495 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003496 err_code |= ERR_ALERT | ERR_FATAL;
3497 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003498 }
3499
3500 err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2]));
3501 if (err) {
3502 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3503 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003504 err_code |= ERR_ALERT | ERR_FATAL;
3505 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003506 }
3507 }
3508 else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
3509 regex_t *preg;
3510 if (curproxy == &defproxy) {
3511 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003512 err_code |= ERR_ALERT | ERR_FATAL;
3513 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003514 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003515 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003516 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003517
Willy Tarreaubaaee002006-06-26 02:48:02 +02003518 if (*(args[1]) == 0) {
3519 Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003520 err_code |= ERR_ALERT | ERR_FATAL;
3521 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003522 }
3523
3524 preg = calloc(1, sizeof(regex_t));
3525 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3526 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003527 err_code |= ERR_ALERT | ERR_FATAL;
3528 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003529 }
3530
3531 err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]));
3532 if (err) {
3533 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3534 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003535 err_code |= ERR_ALERT | ERR_FATAL;
3536 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003537 }
3538 }
3539 else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
3540 regex_t *preg;
3541 if (curproxy == &defproxy) {
3542 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003543 err_code |= ERR_ALERT | ERR_FATAL;
3544 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003545 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003546 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003547 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003548
Willy Tarreaubaaee002006-06-26 02:48:02 +02003549 if (*(args[1]) == 0) {
3550 Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003551 err_code |= ERR_ALERT | ERR_FATAL;
3552 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003553 }
3554
3555 preg = calloc(1, sizeof(regex_t));
3556 if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
3557 Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
Willy Tarreau93893792009-07-23 13:19:11 +02003558 err_code |= ERR_ALERT | ERR_FATAL;
3559 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003560 }
3561
3562 err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]));
3563 if (err) {
3564 Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
3565 file, linenum, *err);
Willy Tarreau93893792009-07-23 13:19:11 +02003566 err_code |= ERR_ALERT | ERR_FATAL;
3567 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003568 }
3569 }
3570 else if (!strcmp(args[0], "rspadd")) { /* add response header */
3571 if (curproxy == &defproxy) {
3572 Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003573 err_code |= ERR_ALERT | ERR_FATAL;
3574 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003575 }
Willy Tarreau977b8e42006-12-29 14:19:17 +01003576 else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003577 err_code |= ERR_WARN;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003578
3579 if (curproxy->nb_rspadd >= MAX_NEWHDR) {
3580 Alert("parsing [%s:%d] : too many '%s'. Continuing.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003581 err_code |= ERR_ALERT | ERR_FATAL;
3582 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003583 }
3584
3585 if (*(args[1]) == 0) {
3586 Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003587 err_code |= ERR_ALERT | ERR_FATAL;
3588 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003589 }
3590
3591 curproxy->rsp_add[curproxy->nb_rspadd++] = strdup(args[1]);
3592 }
3593 else if (!strcmp(args[0], "errorloc") ||
3594 !strcmp(args[0], "errorloc302") ||
3595 !strcmp(args[0], "errorloc303")) { /* error location */
3596 int errnum, errlen;
3597 char *err;
3598
Willy Tarreau977b8e42006-12-29 14:19:17 +01003599 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003600 err_code |= ERR_WARN;
Willy Tarreau977b8e42006-12-29 14:19:17 +01003601
Willy Tarreaubaaee002006-06-26 02:48:02 +02003602 if (*(args[2]) == 0) {
Willy Tarreau1772ece2009-04-03 14:49:12 +02003603 Alert("parsing [%s:%d] : <%s> expects <status_code> and <url> as arguments.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003604 err_code |= ERR_ALERT | ERR_FATAL;
3605 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003606 }
3607
3608 errnum = atol(args[1]);
3609 if (!strcmp(args[0], "errorloc303")) {
3610 err = malloc(strlen(HTTP_303) + strlen(args[2]) + 5);
3611 errlen = sprintf(err, "%s%s\r\n\r\n", HTTP_303, args[2]);
3612 } else {
3613 err = malloc(strlen(HTTP_302) + strlen(args[2]) + 5);
3614 errlen = sprintf(err, "%s%s\r\n\r\n", HTTP_302, args[2]);
3615 }
3616
Willy Tarreau0f772532006-12-23 20:51:41 +01003617 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
3618 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003619 chunk_destroy(&curproxy->errmsg[rc]);
3620 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau0f772532006-12-23 20:51:41 +01003621 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003622 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003623 }
Willy Tarreau0f772532006-12-23 20:51:41 +01003624
3625 if (rc >= HTTP_ERR_SIZE) {
3626 Warning("parsing [%s:%d] : status code %d not handled, error relocation will be ignored.\n",
3627 file, linenum, errnum);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003628 free(err);
3629 }
3630 }
Willy Tarreau3f49b302007-06-11 00:29:26 +02003631 else if (!strcmp(args[0], "errorfile")) { /* error message from a file */
3632 int errnum, errlen, fd;
3633 char *err;
3634 struct stat stat;
3635
3636 if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
Willy Tarreau93893792009-07-23 13:19:11 +02003637 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02003638
3639 if (*(args[2]) == 0) {
Willy Tarreau1772ece2009-04-03 14:49:12 +02003640 Alert("parsing [%s:%d] : <%s> expects <status_code> and <file> as arguments.\n", file, linenum, args[0]);
Willy Tarreau93893792009-07-23 13:19:11 +02003641 err_code |= ERR_ALERT | ERR_FATAL;
3642 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02003643 }
3644
3645 fd = open(args[2], O_RDONLY);
3646 if ((fd < 0) || (fstat(fd, &stat) < 0)) {
3647 Alert("parsing [%s:%d] : error opening file <%s> for custom error message <%s>.\n",
3648 file, linenum, args[2], args[1]);
3649 if (fd >= 0)
3650 close(fd);
Willy Tarreau93893792009-07-23 13:19:11 +02003651 err_code |= ERR_ALERT | ERR_FATAL;
3652 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02003653 }
3654
Willy Tarreau27a674e2009-08-17 07:23:33 +02003655 if (stat.st_size <= global.tune.bufsize) {
Willy Tarreau3f49b302007-06-11 00:29:26 +02003656 errlen = stat.st_size;
3657 } else {
3658 Warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
Willy Tarreau27a674e2009-08-17 07:23:33 +02003659 file, linenum, args[2], global.tune.bufsize);
Willy Tarreau93893792009-07-23 13:19:11 +02003660 err_code |= ERR_WARN;
Willy Tarreau27a674e2009-08-17 07:23:33 +02003661 errlen = global.tune.bufsize;
Willy Tarreau3f49b302007-06-11 00:29:26 +02003662 }
3663
3664 err = malloc(errlen); /* malloc() must succeed during parsing */
3665 errnum = read(fd, err, errlen);
3666 if (errnum != errlen) {
3667 Alert("parsing [%s:%d] : error reading file <%s> for custom error message <%s>.\n",
3668 file, linenum, args[2], args[1]);
3669 close(fd);
3670 free(err);
Willy Tarreau93893792009-07-23 13:19:11 +02003671 err_code |= ERR_ALERT | ERR_FATAL;
3672 goto out;
Willy Tarreau3f49b302007-06-11 00:29:26 +02003673 }
3674 close(fd);
3675
3676 errnum = atol(args[1]);
3677 for (rc = 0; rc < HTTP_ERR_SIZE; rc++) {
3678 if (http_err_codes[rc] == errnum) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +02003679 chunk_destroy(&curproxy->errmsg[rc]);
3680 chunk_initlen(&curproxy->errmsg[rc], err, errlen, errlen);
Willy Tarreau3f49b302007-06-11 00:29:26 +02003681 break;
3682 }
3683 }
3684
3685 if (rc >= HTTP_ERR_SIZE) {
3686 Warning("parsing [%s:%d] : status code %d not handled, error customization will be ignored.\n",
3687 file, linenum, errnum);
Willy Tarreau93893792009-07-23 13:19:11 +02003688 err_code |= ERR_WARN;
Willy Tarreau3f49b302007-06-11 00:29:26 +02003689 free(err);
3690 }
3691 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003692 else {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02003693 struct cfg_kw_list *kwl;
3694 int index;
3695
3696 list_for_each_entry(kwl, &cfg_keywords.list, list) {
3697 for (index = 0; kwl->kw[index].kw != NULL; index++) {
3698 if (kwl->kw[index].section != CFG_LISTEN)
3699 continue;
3700 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
3701 /* prepare error message just in case */
3702 snprintf(trash, sizeof(trash),
3703 "error near '%s' in %s section", args[0], cursection);
Willy Tarreau39f23b62008-07-09 20:22:56 +02003704 rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, sizeof(trash));
3705 if (rc < 0) {
Willy Tarreau5b2c3362008-07-09 19:39:06 +02003706 Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
Willy Tarreau93893792009-07-23 13:19:11 +02003707 err_code |= ERR_ALERT | ERR_FATAL;
3708 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02003709 }
Willy Tarreau39f23b62008-07-09 20:22:56 +02003710 else if (rc > 0) {
3711 Warning("parsing [%s:%d] : %s\n", file, linenum, trash);
Willy Tarreau93893792009-07-23 13:19:11 +02003712 err_code |= ERR_WARN;
3713 goto out;
Willy Tarreau39f23b62008-07-09 20:22:56 +02003714 }
Willy Tarreau93893792009-07-23 13:19:11 +02003715 goto out;
Willy Tarreau5b2c3362008-07-09 19:39:06 +02003716 }
3717 }
3718 }
3719
Willy Tarreau6daf3432008-01-22 16:44:08 +01003720 Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
Willy Tarreau93893792009-07-23 13:19:11 +02003721 err_code |= ERR_ALERT | ERR_FATAL;
3722 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003723 }
Willy Tarreau93893792009-07-23 13:19:11 +02003724 out:
3725 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003726}
3727
3728
3729/*
3730 * This function reads and parses the configuration file given in the argument.
Willy Tarreau058e9072009-07-20 09:30:05 +02003731 * Returns the error code, 0 if OK, or any combination of :
3732 * - ERR_ABORT: must abort ASAP
3733 * - ERR_FATAL: we can continue parsing but not start the service
3734 * - ERR_WARN: a warning has been emitted
3735 * - ERR_ALERT: an alert has been emitted
3736 * Only the two first ones can stop processing, the two others are just
3737 * indicators.
Willy Tarreaubaaee002006-06-26 02:48:02 +02003738 */
Willy Tarreaub17916e2006-10-15 15:17:57 +02003739int readcfgfile(const char *file)
Willy Tarreaubaaee002006-06-26 02:48:02 +02003740{
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01003741 char thisline[LINESIZE];
Willy Tarreaubaaee002006-06-26 02:48:02 +02003742 FILE *f;
3743 int linenum = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003744 int confsect = CFG_NONE;
Willy Tarreau058e9072009-07-20 09:30:05 +02003745 int err_code = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003746
Willy Tarreaubaaee002006-06-26 02:48:02 +02003747 if ((f=fopen(file,"r")) == NULL)
3748 return -1;
3749
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01003750 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Willy Tarreau3842f002009-06-14 11:39:52 +02003751 int arg, kwm = KWM_STD;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01003752 char *end;
3753 char *args[MAX_LINE_ARGS + 1];
3754 char *line = thisline;
3755
Willy Tarreaubaaee002006-06-26 02:48:02 +02003756 linenum++;
3757
3758 end = line + strlen(line);
3759
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01003760 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3761 /* Check if we reached the limit and the last char is not \n.
3762 * Watch out for the last line without the terminating '\n'!
3763 */
3764 Alert("parsing [%s:%d]: line too long, limit: %d.\n",
Willy Tarreau5e4a6f12009-04-11 19:42:49 +02003765 file, linenum, (int)sizeof(thisline)-1);
Willy Tarreau058e9072009-07-20 09:30:05 +02003766 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01003767 }
3768
Willy Tarreaubaaee002006-06-26 02:48:02 +02003769 /* skip leading spaces */
Willy Tarreau8f8e6452007-06-17 21:51:38 +02003770 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02003771 line++;
3772
3773 arg = 0;
3774 args[arg] = line;
3775
3776 while (*line && arg < MAX_LINE_ARGS) {
3777 /* first, we'll replace \\, \<space>, \#, \r, \n, \t, \xXX with their
3778 * C equivalent value. Other combinations left unchanged (eg: \1).
3779 */
3780 if (*line == '\\') {
3781 int skip = 0;
3782 if (line[1] == ' ' || line[1] == '\\' || line[1] == '#') {
3783 *line = line[1];
3784 skip = 1;
3785 }
3786 else if (line[1] == 'r') {
3787 *line = '\r';
3788 skip = 1;
3789 }
3790 else if (line[1] == 'n') {
3791 *line = '\n';
3792 skip = 1;
3793 }
3794 else if (line[1] == 't') {
3795 *line = '\t';
3796 skip = 1;
3797 }
3798 else if (line[1] == 'x') {
3799 if ((line + 3 < end ) && ishex(line[2]) && ishex(line[3])) {
3800 unsigned char hex1, hex2;
3801 hex1 = toupper(line[2]) - '0';
3802 hex2 = toupper(line[3]) - '0';
3803 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
3804 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
3805 *line = (hex1<<4) + hex2;
3806 skip = 3;
3807 }
3808 else {
3809 Alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02003810 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003811 }
3812 }
3813 if (skip) {
3814 memmove(line + 1, line + 1 + skip, end - (line + skip + 1));
3815 end -= skip;
3816 }
3817 line++;
3818 }
3819 else if (*line == '#' || *line == '\n' || *line == '\r') {
3820 /* end of string, end of loop */
3821 *line = 0;
3822 break;
3823 }
Willy Tarreau8f8e6452007-06-17 21:51:38 +02003824 else if (isspace((unsigned char)*line)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02003825 /* a non-escaped space is an argument separator */
Krzysztof Piotr Oledzkie6bbd742007-11-01 00:33:12 +01003826 *line++ = '\0';
Willy Tarreau8f8e6452007-06-17 21:51:38 +02003827 while (isspace((unsigned char)*line))
Willy Tarreaubaaee002006-06-26 02:48:02 +02003828 line++;
3829 args[++arg] = line;
3830 }
3831 else {
3832 line++;
3833 }
3834 }
3835
3836 /* empty line */
3837 if (!**args)
3838 continue;
3839
Willy Tarreau540abe42007-05-02 20:50:16 +02003840 /* zero out remaining args and ensure that at least one entry
3841 * is zeroed out.
3842 */
3843 while (++arg <= MAX_LINE_ARGS) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02003844 args[arg] = line;
3845 }
3846
Willy Tarreau3842f002009-06-14 11:39:52 +02003847 /* check for keyword modifiers "no" and "default" */
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003848 if (!strcmp(args[0], "no")) {
Willy Tarreau3842f002009-06-14 11:39:52 +02003849 kwm = KWM_NO;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003850 for (arg=0; *args[arg+1]; arg++)
3851 args[arg] = args[arg+1]; // shift args after inversion
3852 }
Willy Tarreau3842f002009-06-14 11:39:52 +02003853 else if (!strcmp(args[0], "default")) {
3854 kwm = KWM_DEF;
3855 for (arg=0; *args[arg+1]; arg++)
3856 args[arg] = args[arg+1]; // shift args after inversion
3857 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003858
Willy Tarreau3842f002009-06-14 11:39:52 +02003859 if (kwm != KWM_STD && strcmp(args[0], "option") != 0) {
3860 Alert("parsing [%s:%d]: negation/default currently supported only for options.\n", file, linenum);
Willy Tarreau058e9072009-07-20 09:30:05 +02003861 err_code |= ERR_ALERT | ERR_FATAL;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01003862 }
3863
Willy Tarreau977b8e42006-12-29 14:19:17 +01003864 if (!strcmp(args[0], "listen") ||
3865 !strcmp(args[0], "frontend") ||
3866 !strcmp(args[0], "backend") ||
3867 !strcmp(args[0], "ruleset") ||
Willy Tarreau6daf3432008-01-22 16:44:08 +01003868 !strcmp(args[0], "defaults")) { /* new proxy */
Willy Tarreaubaaee002006-06-26 02:48:02 +02003869 confsect = CFG_LISTEN;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003870 free(cursection);
Willy Tarreau6daf3432008-01-22 16:44:08 +01003871 cursection = strdup(args[0]);
3872 }
3873 else if (!strcmp(args[0], "global")) { /* global config */
Willy Tarreaubaaee002006-06-26 02:48:02 +02003874 confsect = CFG_GLOBAL;
Willy Tarreaua534fea2008-08-03 12:19:50 +02003875 free(cursection);
Willy Tarreau6daf3432008-01-22 16:44:08 +01003876 cursection = strdup(args[0]);
3877 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003878 /* else it's a section keyword */
3879
3880 switch (confsect) {
3881 case CFG_LISTEN:
Willy Tarreau93893792009-07-23 13:19:11 +02003882 err_code |= cfg_parse_listen(file, linenum, args, kwm);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003883 break;
3884 case CFG_GLOBAL:
Willy Tarreau058e9072009-07-20 09:30:05 +02003885 err_code |= cfg_parse_global(file, linenum, args, kwm);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003886 break;
3887 default:
3888 Alert("parsing [%s:%d] : unknown keyword '%s' out of section.\n", file, linenum, args[0]);
Willy Tarreau058e9072009-07-20 09:30:05 +02003889 err_code |= ERR_ALERT | ERR_FATAL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003890 }
Willy Tarreau058e9072009-07-20 09:30:05 +02003891
3892 if (err_code & ERR_ABORT)
3893 break;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003894 }
Willy Tarreaua534fea2008-08-03 12:19:50 +02003895 free(cursection);
Willy Tarreau6daf3432008-01-22 16:44:08 +01003896 cursection = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003897 fclose(f);
Willy Tarreau058e9072009-07-20 09:30:05 +02003898 return err_code;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003899}
3900
Willy Tarreaubb925012009-07-23 13:36:36 +02003901/*
3902 * Returns the error code, 0 if OK, or any combination of :
3903 * - ERR_ABORT: must abort ASAP
3904 * - ERR_FATAL: we can continue parsing but not start the service
3905 * - ERR_WARN: a warning has been emitted
3906 * - ERR_ALERT: an alert has been emitted
3907 * Only the two first ones can stop processing, the two others are just
3908 * indicators.
3909 */
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003910int check_config_validity()
3911{
3912 int cfgerr = 0;
3913 struct proxy *curproxy = NULL;
3914 struct server *newsrv = NULL;
Willy Tarreaubb925012009-07-23 13:36:36 +02003915 int err_code = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003916
3917 /*
3918 * Now, check for the integrity of all that we have collected.
3919 */
3920
3921 /* will be needed further to delay some tasks */
Willy Tarreaub0b37bc2008-06-23 14:00:57 +02003922 tv_update_date(0,1);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003923
Willy Tarreau55bc0f82009-03-15 14:51:53 +01003924 /* first, we will invert the proxy list order */
3925 curproxy = NULL;
3926 while (proxy) {
3927 struct proxy *next;
3928
3929 next = proxy->next;
3930 proxy->next = curproxy;
3931 curproxy = proxy;
3932 if (!next)
3933 break;
3934 proxy = next;
3935 }
3936
Willy Tarreaubaaee002006-06-26 02:48:02 +02003937 if ((curproxy = proxy) == NULL) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003938 Alert("config : no <listen> line. Nothing to do !\n");
Willy Tarreaubb925012009-07-23 13:36:36 +02003939 err_code |= ERR_ALERT | ERR_FATAL;
3940 goto out;
Willy Tarreaubaaee002006-06-26 02:48:02 +02003941 }
3942
3943 while (curproxy != NULL) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02003944 struct switching_rule *rule;
Willy Tarreaue6b98942007-10-29 01:09:36 +01003945 struct listener *listener;
Willy Tarreau55ea7572007-06-17 19:56:27 +02003946
Willy Tarreaubaaee002006-06-26 02:48:02 +02003947 if (curproxy->state == PR_STSTOPPED) {
Willy Tarreauda250db2008-10-12 12:07:48 +02003948 /* ensure we don't keep listeners uselessly bound */
3949 stop_proxy(curproxy);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003950 curproxy = curproxy->next;
3951 continue;
3952 }
3953
Willy Tarreauff01a212009-03-15 13:46:16 +01003954 switch (curproxy->mode) {
3955 case PR_MODE_HEALTH:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003956 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01003957 if (!(curproxy->cap & PR_CAP_FE)) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003958 Alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
3959 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01003960 cfgerr++;
3961 }
3962
3963 if (curproxy->srv != NULL)
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003964 Warning("config : servers will be ignored for %s '%s'.\n",
3965 proxy_type_str(curproxy), curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01003966 break;
3967
3968 case PR_MODE_TCP:
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003969 cfgerr += proxy_cfg_ensure_no_http(curproxy);
Willy Tarreauff01a212009-03-15 13:46:16 +01003970 break;
3971
3972 case PR_MODE_HTTP:
Willy Tarreaua9fb0832009-07-10 20:53:53 +02003973 curproxy->acl_requires |= ACL_USE_L7_ANY;
Willy Tarreauff01a212009-03-15 13:46:16 +01003974 if ((curproxy->cookie_name != NULL) && (curproxy->srv == NULL)) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003975 Alert("config : HTTP proxy %s has a cookie but no server list !\n",
3976 curproxy->id);
Willy Tarreauff01a212009-03-15 13:46:16 +01003977 cfgerr++;
3978 }
3979 break;
3980 }
3981
3982 if ((curproxy->cap & PR_CAP_FE) && (curproxy->listen == NULL)) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003983 Alert("config : %s '%s' has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n",
3984 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubaaee002006-06-26 02:48:02 +02003985 cfgerr++;
3986 }
Willy Tarreauff01a212009-03-15 13:46:16 +01003987
Willy Tarreau3cd9af22009-03-15 14:06:41 +01003988 if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
Willy Tarreauf3e49f92009-10-03 12:21:20 +02003989 if (curproxy->lbprm.algo & BE_LB_KIND) {
Willy Tarreau3cd9af22009-03-15 14:06:41 +01003990 if (curproxy->options & PR_O_TRANSP) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003991 Alert("config : %s '%s' cannot use both transparent and balance mode.\n",
3992 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01003993 cfgerr++;
3994 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02003995#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
Willy Tarreau3cd9af22009-03-15 14:06:41 +01003996 else if (curproxy->srv == NULL) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02003997 Alert("config : %s '%s' needs at least 1 server in balance mode.\n",
3998 proxy_type_str(curproxy), curproxy->id);
Willy Tarreau3cd9af22009-03-15 14:06:41 +01003999 cfgerr++;
4000 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004001#endif
Willy Tarreau3cd9af22009-03-15 14:06:41 +01004002 else if (*(int *)&curproxy->dispatch_addr.sin_addr != 0) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004003 Warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
4004 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02004005 err_code |= ERR_WARN;
Willy Tarreau3cd9af22009-03-15 14:06:41 +01004006 }
4007 }
4008 else if (!(curproxy->options & (PR_O_TRANSP | PR_O_HTTP_PROXY)) &&
4009 (*(int *)&curproxy->dispatch_addr.sin_addr == 0)) {
4010 /* If no LB algo is set in a backend, and we're not in
4011 * transparent mode, dispatch mode nor proxy mode, we
4012 * want to use balance roundrobin by default.
4013 */
4014 curproxy->lbprm.algo &= ~BE_LB_ALGO;
4015 curproxy->lbprm.algo |= BE_LB_ALGO_RR;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004016 }
4017 }
Willy Tarreau193cf932007-09-17 10:17:23 +02004018
Willy Tarreau82936582007-11-30 15:20:09 +01004019 if ((curproxy->options & PR_O_DISABLE404) && !(curproxy->options & PR_O_HTTP_CHK)) {
4020 curproxy->options &= ~PR_O_DISABLE404;
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004021 Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
4022 "disable-on-404", proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02004023 err_code |= ERR_WARN;
Willy Tarreau82936582007-11-30 15:20:09 +01004024 }
4025
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004026 /* if a default backend was specified, let's find it */
4027 if (curproxy->defbe.name) {
4028 struct proxy *target;
4029
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004030 target = findproxy(curproxy->defbe.name, curproxy->mode, PR_CAP_BE);
4031 if (!target) {
4032 Alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
4033 curproxy->id, curproxy->defbe.name);
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004034 cfgerr++;
4035 } else if (target == curproxy) {
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004036 Alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
4037 curproxy->id, curproxy->defbe.name);
Willy Tarreaubb925012009-07-23 13:36:36 +02004038 cfgerr++;
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004039 } else {
4040 free(curproxy->defbe.name);
4041 curproxy->defbe.be = target;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01004042 /* we force the backend to be present on at least all of
4043 * the frontend's processes.
4044 */
4045 target->bind_proc = curproxy->bind_proc ?
4046 (target->bind_proc | curproxy->bind_proc) : 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004047 }
4048 }
4049
Willy Tarreau5fdfb912007-01-01 23:11:07 +01004050 /* find the target proxy in setbe */
Willy Tarreaua496b602006-12-17 23:15:24 +01004051 if (curproxy->mode == PR_MODE_HTTP && curproxy->req_exp != NULL) {
4052 /* map jump target for ACT_SETBE in req_rep chain */
4053 struct hdr_exp *exp;
Willy Tarreaua496b602006-12-17 23:15:24 +01004054 for (exp = curproxy->req_exp; exp != NULL; exp = exp->next) {
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004055 struct proxy *target;
4056
Willy Tarreaua496b602006-12-17 23:15:24 +01004057 if (exp->action != ACT_SETBE)
4058 continue;
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004059
4060 target = findproxy(exp->replace, PR_MODE_HTTP, PR_CAP_BE);
4061 if (!target) {
4062 Alert("Proxy '%s': unable to find required setbe: '%s'.\n",
4063 curproxy->id, exp->replace);
Willy Tarreaua496b602006-12-17 23:15:24 +01004064 cfgerr++;
4065 } else if (target == curproxy) {
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004066 Alert("Proxy '%s': loop detected for setbe: '%s'.\n",
4067 curproxy->id, exp->replace);
Willy Tarreau977b8e42006-12-29 14:19:17 +01004068 cfgerr++;
Willy Tarreaua496b602006-12-17 23:15:24 +01004069 } else {
4070 free((void *)exp->replace);
4071 exp->replace = (const char *)target;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01004072 /* we force the backend to be present on at least all of
4073 * the frontend's processes.
4074 */
4075 target->bind_proc = curproxy->bind_proc ?
4076 (target->bind_proc | curproxy->bind_proc) : 0;
Willy Tarreaua496b602006-12-17 23:15:24 +01004077 }
4078 }
4079 }
Willy Tarreau55ea7572007-06-17 19:56:27 +02004080
4081 /* find the target proxy for 'use_backend' rules */
4082 list_for_each_entry(rule, &curproxy->switching_rules, list) {
Willy Tarreau55ea7572007-06-17 19:56:27 +02004083 struct proxy *target;
4084
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004085 target = findproxy(rule->be.name, curproxy->mode, PR_CAP_BE);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004086
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004087 if (!target) {
4088 Alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
4089 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004090 cfgerr++;
4091 } else if (target == curproxy) {
Krzysztof Piotr Oledzki6eb730d2007-11-03 23:41:58 +01004092 Alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
4093 curproxy->id, rule->be.name);
Willy Tarreau55ea7572007-06-17 19:56:27 +02004094 cfgerr++;
4095 } else {
4096 free((void *)rule->be.name);
4097 rule->be.backend = target;
Willy Tarreau0b9c02c2009-02-04 22:05:05 +01004098 /* we force the backend to be present on at least all of
4099 * the frontend's processes.
4100 */
4101 target->bind_proc = curproxy->bind_proc ?
4102 (target->bind_proc | curproxy->bind_proc) : 0;
Willy Tarreau55ea7572007-06-17 19:56:27 +02004103 }
4104 }
4105
Willy Tarreau2738a142006-07-08 17:28:09 +02004106 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004107 (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
Willy Tarreaud825eef2007-05-12 22:35:00 +02004108 ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004109 (!curproxy->timeout.connect || !curproxy->timeout.server)))) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004110 Warning("config : missing timeouts for %s '%s'.\n"
Willy Tarreau2738a142006-07-08 17:28:09 +02004111 " | While not properly invalid, you will certainly encounter various problems\n"
4112 " | with such a configuration. To fix this, please ensure that all following\n"
Willy Tarreau0f68eac2008-01-20 23:25:06 +01004113 " | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004114 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02004115 err_code |= ERR_WARN;
Willy Tarreau2738a142006-07-08 17:28:09 +02004116 }
Willy Tarreauf3c69202006-07-09 16:42:34 +02004117
Willy Tarreau1fa31262007-12-03 00:36:16 +01004118 /* Historically, the tarpit and queue timeouts were inherited from contimeout.
4119 * We must still support older configurations, so let's find out whether those
4120 * parameters have been set or must be copied from contimeouts.
4121 */
4122 if (curproxy != &defproxy) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004123 if (!curproxy->timeout.tarpit ||
4124 curproxy->timeout.tarpit == defproxy.timeout.tarpit) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01004125 /* tarpit timeout not set. We search in the following order:
4126 * default.tarpit, curr.connect, default.connect.
4127 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004128 if (defproxy.timeout.tarpit)
Willy Tarreau1fa31262007-12-03 00:36:16 +01004129 curproxy->timeout.tarpit = defproxy.timeout.tarpit;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004130 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01004131 curproxy->timeout.tarpit = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004132 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01004133 curproxy->timeout.tarpit = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01004134 }
4135 if ((curproxy->cap & PR_CAP_BE) &&
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004136 (!curproxy->timeout.queue ||
4137 curproxy->timeout.queue == defproxy.timeout.queue)) {
Willy Tarreau1fa31262007-12-03 00:36:16 +01004138 /* queue timeout not set. We search in the following order:
4139 * default.queue, curr.connect, default.connect.
4140 */
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004141 if (defproxy.timeout.queue)
Willy Tarreau1fa31262007-12-03 00:36:16 +01004142 curproxy->timeout.queue = defproxy.timeout.queue;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004143 else if (curproxy->timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01004144 curproxy->timeout.queue = curproxy->timeout.connect;
Willy Tarreau0c303ee2008-07-07 00:09:58 +02004145 else if (defproxy.timeout.connect)
Willy Tarreaud7c30f92007-12-03 01:38:36 +01004146 curproxy->timeout.queue = defproxy.timeout.connect;
Willy Tarreau1fa31262007-12-03 00:36:16 +01004147 }
4148 }
4149
Willy Tarreauf3c69202006-07-09 16:42:34 +02004150 if (curproxy->options & PR_O_SSL3_CHK) {
4151 curproxy->check_len = sizeof(sslv3_client_hello_pkt);
4152 curproxy->check_req = (char *)malloc(sizeof(sslv3_client_hello_pkt));
4153 memcpy(curproxy->check_req, sslv3_client_hello_pkt, sizeof(sslv3_client_hello_pkt));
4154 }
4155
Willy Tarreaucf7f3202007-05-13 22:46:04 +02004156 /* The small pools required for the capture lists */
4157 if (curproxy->nb_req_cap)
4158 curproxy->req_cap_pool = create_pool("ptrcap",
4159 curproxy->nb_req_cap * sizeof(char *),
4160 MEM_F_SHARED);
4161 if (curproxy->nb_rsp_cap)
4162 curproxy->rsp_cap_pool = create_pool("ptrcap",
4163 curproxy->nb_rsp_cap * sizeof(char *),
4164 MEM_F_SHARED);
4165
Willy Tarreau1d4154a2007-05-13 22:57:02 +02004166 curproxy->hdr_idx_pool = create_pool("hdr_idx",
4167 MAX_HTTP_HDR * sizeof(struct hdr_idx_elem),
4168 MEM_F_SHARED);
4169
Willy Tarreau86034312006-12-29 00:10:33 +01004170 /* for backwards compatibility with "listen" instances, if
4171 * fullconn is not set but maxconn is set, then maxconn
4172 * is used.
4173 */
4174 if (!curproxy->fullconn)
4175 curproxy->fullconn = curproxy->maxconn;
4176
Willy Tarreaubaaee002006-06-26 02:48:02 +02004177 /* first, we will invert the servers list order */
4178 newsrv = NULL;
4179 while (curproxy->srv) {
4180 struct server *next;
4181
4182 next = curproxy->srv->next;
4183 curproxy->srv->next = newsrv;
4184 newsrv = curproxy->srv;
4185 if (!next)
4186 break;
4187 curproxy->srv = next;
4188 }
4189
Willy Tarreau20697042007-11-15 23:26:18 +01004190 curproxy->lbprm.wmult = 1; /* default weight multiplier */
Willy Tarreau5dc2fa62007-11-19 19:10:18 +01004191 curproxy->lbprm.wdiv = 1; /* default weight divider */
Willy Tarreaubaaee002006-06-26 02:48:02 +02004192
Willy Tarreauf3e49f92009-10-03 12:21:20 +02004193 /* We have to initialize the server lookup mechanism depending
4194 * on what LB algorithm was choosen.
4195 */
4196
4197 curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
4198 switch (curproxy->lbprm.algo & BE_LB_KIND) {
4199 case BE_LB_KIND_RR:
Willy Tarreau9757a382009-10-03 12:56:50 +02004200 if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) {
4201 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
4202 init_server_map(curproxy);
4203 } else {
4204 curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN;
4205 fwrr_init_server_groups(curproxy);
4206 }
Willy Tarreauf3e49f92009-10-03 12:21:20 +02004207 break;
4208 case BE_LB_KIND_LC:
4209 curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;
Willy Tarreau51406232008-03-10 22:04:20 +01004210 fwlc_init_server_tree(curproxy);
Willy Tarreauf3e49f92009-10-03 12:21:20 +02004211 break;
4212 case BE_LB_KIND_HI:
4213 curproxy->lbprm.algo |= BE_LB_LKUP_MAP;
Willy Tarreaub625a082007-11-26 01:15:43 +01004214 init_server_map(curproxy);
Willy Tarreauf3e49f92009-10-03 12:21:20 +02004215 break;
4216 }
Willy Tarreaubaaee002006-06-26 02:48:02 +02004217
4218 if (curproxy->options & PR_O_LOGASAP)
4219 curproxy->to_log &= ~LW_BYTES;
4220
Willy Tarreaue7ded1f2009-08-09 10:11:45 +02004221 if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
4222 (curproxy->cap & PR_CAP_FE) && curproxy->to_log && curproxy->logfac1 < 0) {
4223 Warning("config : log format ignored for %s '%s' since it has no log address.\n",
4224 proxy_type_str(curproxy), curproxy->id);
4225 err_code |= ERR_WARN;
4226 }
4227
Willy Tarreaubaaee002006-06-26 02:48:02 +02004228 /*
Willy Tarreau21d2af32008-02-14 20:25:24 +01004229 * ensure that we're not cross-dressing a TCP server into HTTP.
4230 */
4231 newsrv = curproxy->srv;
4232 while (newsrv != NULL) {
4233 if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004234 Alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
4235 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02004236 cfgerr++;
Willy Tarreau21d2af32008-02-14 20:25:24 +01004237 }
4238 newsrv = newsrv->next;
4239 }
4240
4241 /*
Willy Tarreaubaaee002006-06-26 02:48:02 +02004242 * If this server supports a maxconn parameter, it needs a dedicated
4243 * tasks to fill the emptied slots when a connection leaves.
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004244 * Also, resolve deferred tracking dependency if needed.
Willy Tarreaubaaee002006-06-26 02:48:02 +02004245 */
4246 newsrv = curproxy->srv;
4247 while (newsrv != NULL) {
Willy Tarreau86034312006-12-29 00:10:33 +01004248 if (newsrv->minconn > newsrv->maxconn) {
Willy Tarreaubaaee002006-06-26 02:48:02 +02004249 /* Only 'minconn' was specified, or it was higher than or equal
4250 * to 'maxconn'. Let's turn this into maxconn and clean it, as
4251 * this will avoid further useless expensive computations.
4252 */
4253 newsrv->maxconn = newsrv->minconn;
Willy Tarreau86034312006-12-29 00:10:33 +01004254 } else if (newsrv->maxconn && !newsrv->minconn) {
4255 /* minconn was not specified, so we set it to maxconn */
4256 newsrv->minconn = newsrv->maxconn;
Willy Tarreau977b8e42006-12-29 14:19:17 +01004257 } else if (newsrv->minconn != newsrv->maxconn && !curproxy->fullconn) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004258 Alert("config : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
4259 proxy_type_str(curproxy), curproxy->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02004260 cfgerr++;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004261 }
4262
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004263 if (newsrv->trackit) {
4264 struct proxy *px;
4265 struct server *srv;
4266 char *pname, *sname;
4267
4268 pname = newsrv->trackit;
4269 sname = strrchr(pname, '/');
4270
4271 if (sname)
4272 *sname++ = '\0';
4273 else {
4274 sname = pname;
4275 pname = NULL;
4276 }
4277
4278 if (pname) {
4279 px = findproxy(pname, curproxy->mode, PR_CAP_BE);
4280 if (!px) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004281 Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
4282 proxy_type_str(curproxy), curproxy->id,
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004283 newsrv->id, pname);
Willy Tarreaubb925012009-07-23 13:36:36 +02004284 cfgerr++;
4285 goto next_srv;
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004286 }
4287 } else
4288 px = curproxy;
4289
4290 srv = findserver(px, sname);
4291 if (!srv) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004292 Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
4293 proxy_type_str(curproxy), curproxy->id,
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004294 newsrv->id, sname);
Willy Tarreaubb925012009-07-23 13:36:36 +02004295 cfgerr++;
4296 goto next_srv;
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004297 }
4298
4299 if (!(srv->state & SRV_CHECKED)) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004300 Alert("config : %s '%s', server '%s': unable to use %s/%s for "
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004301 "tracing as it does not have checks enabled.\n",
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004302 proxy_type_str(curproxy), curproxy->id,
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004303 newsrv->id, px->id, srv->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02004304 cfgerr++;
4305 goto next_srv;
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004306 }
4307
4308 if (curproxy != px &&
4309 (curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004310 Alert("config : %s '%s', server '%s': unable to use %s/%s for"
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004311 "tracing: disable-on-404 option inconsistency.\n",
Willy Tarreau915e1eb2009-06-22 15:48:36 +02004312 proxy_type_str(curproxy), curproxy->id,
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004313 newsrv->id, px->id, srv->id);
Willy Tarreaubb925012009-07-23 13:36:36 +02004314 cfgerr++;
4315 goto next_srv;
Krzysztof Piotr Oledzkic8b16fc2008-02-18 01:26:35 +01004316 }
4317
4318 newsrv->tracked = srv;
4319 newsrv->tracknext = srv->tracknext;
4320 srv->tracknext = newsrv;
4321
4322 free(newsrv->trackit);
4323 }
Willy Tarreaubb925012009-07-23 13:36:36 +02004324 next_srv:
Willy Tarreaubaaee002006-06-26 02:48:02 +02004325 newsrv = newsrv->next;
4326 }
4327
Willy Tarreauc1a21672009-08-16 22:37:44 +02004328 if (curproxy->cap & PR_CAP_FE) {
4329 if (curproxy->tcp_req.inspect_delay ||
4330 !LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
4331 curproxy->fe_req_ana |= AN_REQ_INSPECT;
4332
Willy Tarreau4e5b8282009-08-16 22:57:50 +02004333 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02004334 curproxy->fe_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_PROCESS_FE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02004335 curproxy->fe_rsp_ana |= AN_RTR_HTTP_HDR;
4336 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02004337
4338 /* both TCP and HTTP must check switching rules */
4339 curproxy->fe_req_ana |= AN_REQ_SWITCHING_RULES;
4340 }
4341
4342 if (curproxy->cap & PR_CAP_BE) {
Willy Tarreau4e5b8282009-08-16 22:57:50 +02004343 if (curproxy->mode == PR_MODE_HTTP) {
Willy Tarreauc1a21672009-08-16 22:37:44 +02004344 curproxy->be_req_ana |= AN_REQ_WAIT_HTTP | AN_REQ_HTTP_INNER | AN_REQ_HTTP_PROCESS_BE;
Willy Tarreau4e5b8282009-08-16 22:57:50 +02004345 curproxy->be_rsp_ana |= AN_RTR_HTTP_HDR;
4346 }
Willy Tarreauc1a21672009-08-16 22:37:44 +02004347
4348 /* If the backend does requires RDP cookie persistence, we have to
4349 * enable the corresponding analyser.
4350 */
4351 if (curproxy->options2 & PR_O2_RDPC_PRST)
4352 curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
4353 }
4354
Willy Tarreaue6b98942007-10-29 01:09:36 +01004355 /* adjust this proxy's listeners */
4356 listener = curproxy->listen;
4357 while (listener) {
4358 if (curproxy->options & PR_O_TCP_NOLING)
4359 listener->options |= LI_O_NOLINGER;
4360 listener->maxconn = curproxy->maxconn;
Willy Tarreauc73ce2b2008-01-06 10:55:10 +01004361 listener->backlog = curproxy->backlog;
Willy Tarreaud7c30f92007-12-03 01:38:36 +01004362 listener->timeout = &curproxy->timeout.client;
Willy Tarreaue6b98942007-10-29 01:09:36 +01004363 listener->accept = event_accept;
4364 listener->private = curproxy;
Willy Tarreau3bc13772008-12-07 11:50:35 +01004365 listener->handler = process_session;
Willy Tarreauc1a21672009-08-16 22:37:44 +02004366 listener->analysers |= curproxy->fe_req_ana;
Willy Tarreau3bc13772008-12-07 11:50:35 +01004367
Willy Tarreau9ea05a72009-06-14 12:07:01 +02004368 /* smart accept mode is automatic in HTTP mode */
4369 if ((curproxy->options2 & PR_O2_SMARTACC) ||
4370 (curproxy->mode == PR_MODE_HTTP &&
4371 !(curproxy->no_options2 & PR_O2_SMARTACC)))
4372 listener->options |= LI_O_NOQUICKACK;
4373
Willy Tarreau1d0dfb12009-07-07 15:10:31 +02004374 /* We want the use_backend and default_backend rules to apply */
Willy Tarreaue6b98942007-10-29 01:09:36 +01004375 listener = listener->next;
4376 }
4377
Willy Tarreaubaaee002006-06-26 02:48:02 +02004378 curproxy = curproxy->next;
4379 }
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004380
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004381 /*
4382 * Recount currently required checks.
4383 */
4384
4385 for (curproxy=proxy; curproxy; curproxy=curproxy->next) {
4386 int optnum;
4387
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004388 for (optnum = 0; cfg_opts[optnum].name; optnum++)
4389 if (curproxy->options & cfg_opts[optnum].val)
4390 global.last_checks |= cfg_opts[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004391
Willy Tarreau66aa61f2009-01-18 21:44:07 +01004392 for (optnum = 0; cfg_opts2[optnum].name; optnum++)
4393 if (curproxy->options2 & cfg_opts2[optnum].val)
4394 global.last_checks |= cfg_opts2[optnum].checks;
Krzysztof Oledzki336d4752007-12-25 02:40:22 +01004395 }
4396
Willy Tarreaubb925012009-07-23 13:36:36 +02004397 if (cfgerr > 0)
4398 err_code |= ERR_ALERT | ERR_FATAL;
4399 out:
4400 return err_code;
Willy Tarreaubaaee002006-06-26 02:48:02 +02004401}
4402
Willy Tarreau5b2c3362008-07-09 19:39:06 +02004403/*
4404 * Registers the CFG keyword list <kwl> as a list of valid keywords for next
4405 * parsing sessions.
4406 */
4407void cfg_register_keywords(struct cfg_kw_list *kwl)
4408{
4409 LIST_ADDQ(&cfg_keywords.list, &kwl->list);
4410}
Willy Tarreaubaaee002006-06-26 02:48:02 +02004411
Willy Tarreau5b2c3362008-07-09 19:39:06 +02004412/*
4413 * Unregisters the CFG keyword list <kwl> from the list of valid keywords.
4414 */
4415void cfg_unregister_keywords(struct cfg_kw_list *kwl)
4416{
4417 LIST_DEL(&kwl->list);
4418 LIST_INIT(&kwl->list);
4419}
Willy Tarreaubaaee002006-06-26 02:48:02 +02004420
4421/*
4422 * Local variables:
4423 * c-indent-level: 8
4424 * c-basic-offset: 8
4425 * End:
4426 */