blob: c6eb86390fa64958b3b1150d5e86b3d977eb7bee [file] [log] [blame]
Amaury Denoyellefc6ac532021-04-27 10:46:36 +02001#define _GNU_SOURCE /* for cpu_set_t from haproxy/cpuset.h */
Willy Tarreau36b9e222018-11-11 15:19:52 +01002#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <netdb.h>
6#include <ctype.h>
7#include <pwd.h>
8#include <grp.h>
9#include <errno.h>
10#include <sys/types.h>
11#include <sys/stat.h>
Willy Tarreau36b9e222018-11-11 15:19:52 +010012#include <unistd.h>
13
Frédéric Lécaille0499db42023-09-07 18:43:52 +020014#include <import/sha1.h>
15
Eric Salama7cea6062020-10-02 11:58:19 +020016#include <haproxy/buf.h>
Willy Tarreau6be78492020-06-05 00:00:29 +020017#include <haproxy/cfgparse.h>
Amaury Denoyellea6f9c5d2021-04-23 16:58:08 +020018#ifdef USE_CPU_AFFINITY
Amaury Denoyellec90932b2021-04-14 16:16:03 +020019#include <haproxy/cpuset.h>
Amaury Denoyellea6f9c5d2021-04-23 16:58:08 +020020#endif
Willy Tarreau0a3bd392020-06-04 08:52:38 +020021#include <haproxy/compression.h>
Willy Tarreaudfd3de82020-06-04 23:46:14 +020022#include <haproxy/global.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020023#include <haproxy/log.h>
Dragan Dosen13cd54c2020-06-18 18:24:05 +020024#include <haproxy/peers.h>
Willy Tarreau785b89f2023-04-22 15:09:07 +020025#include <haproxy/protocol.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020026#include <haproxy/tools.h>
Willy Tarreau36b9e222018-11-11 15:19:52 +010027
Frédéric Lécaille0499db42023-09-07 18:43:52 +020028int cluster_secret_isset;
29
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010030/* some keywords that are still being parsed using strcmp() and are not
31 * registered anywhere. They are used as suggestions for mistyped words.
32 */
33static const char *common_kw_list[] = {
34 "global", "daemon", "master-worker", "noepoll", "nokqueue",
35 "noevports", "nopoll", "busy-polling", "set-dumpable",
36 "insecure-fork-wanted", "insecure-setuid-wanted", "nosplice",
37 "nogetaddrinfo", "noreuseport", "quiet", "zero-warning",
38 "tune.runqueue-depth", "tune.maxpollevents", "tune.maxaccept",
Willy Tarreaueb9d90a2021-06-11 15:29:31 +020039 "tune.recv_enough", "tune.buffers.limit",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010040 "tune.buffers.reserve", "tune.bufsize", "tune.maxrewrite",
41 "tune.idletimer", "tune.rcvbuf.client", "tune.rcvbuf.server",
42 "tune.sndbuf.client", "tune.sndbuf.server", "tune.pipesize",
43 "tune.http.cookielen", "tune.http.logurilen", "tune.http.maxhdr",
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +010044 "tune.comp.maxlevel", "tune.pattern.cache-size",
45 "tune.fast-forward", "uid", "gid",
Willy Tarreau51ec03a2021-09-22 11:55:22 +020046 "external-check", "user", "group", "nbproc", "maxconn",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010047 "ssl-server-verify", "maxconnrate", "maxsessrate", "maxsslrate",
48 "maxcomprate", "maxpipes", "maxzlibmem", "maxcompcpuusage", "ulimit-n",
49 "chroot", "description", "node", "pidfile", "unix-bind", "log",
50 "log-send-hostname", "server-state-base", "server-state-file",
51 "log-tag", "spread-checks", "max-spread-checks", "cpu-map", "setenv",
52 "presetenv", "unsetenv", "resetenv", "strict-limits", "localpeer",
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +010053 "numa-cpu-mapping", "defaults", "listen", "frontend", "backend",
Frédéric Lécaille12a03172023-01-12 15:23:54 +010054 "peers", "resolvers", "cluster-secret", "no-quic",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010055 NULL /* must be last */
56};
57
Willy Tarreau36b9e222018-11-11 15:19:52 +010058/*
59 * parse a line in a <global> section. Returns the error code, 0 if OK, or
60 * any combination of :
61 * - ERR_ABORT: must abort ASAP
62 * - ERR_FATAL: we can continue parsing but not start the service
63 * - ERR_WARN: a warning has been emitted
64 * - ERR_ALERT: an alert has been emitted
65 * Only the two first ones can stop processing, the two others are just
66 * indicators.
67 */
68int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
69{
70 int err_code = 0;
71 char *errmsg = NULL;
72
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010073 if (strcmp(args[0], "global") == 0) { /* new section */
Willy Tarreau36b9e222018-11-11 15:19:52 +010074 /* no option, nothing special to do */
75 alertif_too_many_args(0, file, linenum, args, &err_code);
76 goto out;
77 }
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +020078 else if (strcmp(args[0], "expose-experimental-directives") == 0) {
79 experimental_directives_allowed = 1;
80 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010081 else if (strcmp(args[0], "daemon") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010082 if (alertif_too_many_args(0, file, linenum, args, &err_code))
83 goto out;
84 global.mode |= MODE_DAEMON;
85 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010086 else if (strcmp(args[0], "master-worker") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010087 if (alertif_too_many_args(1, file, linenum, args, &err_code))
88 goto out;
89 if (*args[1]) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010090 if (strcmp(args[1], "no-exit-on-failure") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010091 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
92 } else {
93 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
94 err_code |= ERR_ALERT | ERR_FATAL;
95 goto out;
96 }
97 }
98 global.mode |= MODE_MWORKER;
99 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100100 else if (strcmp(args[0], "noepoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100101 if (alertif_too_many_args(0, file, linenum, args, &err_code))
102 goto out;
103 global.tune.options &= ~GTUNE_USE_EPOLL;
104 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100105 else if (strcmp(args[0], "nokqueue") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100106 if (alertif_too_many_args(0, file, linenum, args, &err_code))
107 goto out;
108 global.tune.options &= ~GTUNE_USE_KQUEUE;
109 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100110 else if (strcmp(args[0], "noevports") == 0) {
Emmanuel Hocdet0ba4f482019-04-08 16:53:32 +0000111 if (alertif_too_many_args(0, file, linenum, args, &err_code))
112 goto out;
113 global.tune.options &= ~GTUNE_USE_EVPORTS;
114 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100115 else if (strcmp(args[0], "nopoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100116 if (alertif_too_many_args(0, file, linenum, args, &err_code))
117 goto out;
118 global.tune.options &= ~GTUNE_USE_POLL;
119 }
Frédéric Lécaille12a03172023-01-12 15:23:54 +0100120 else if (strcmp(args[0], "no-quic") == 0) {
121 if (alertif_too_many_args(0, file, linenum, args, &err_code))
122 goto out;
123
124 global.tune.options |= GTUNE_NO_QUIC;
125 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100126 else if (strcmp(args[0], "busy-polling") == 0) { /* "no busy-polling" or "busy-polling" */
Willy Tarreaubeb859a2018-11-22 18:07:59 +0100127 if (alertif_too_many_args(0, file, linenum, args, &err_code))
128 goto out;
129 if (kwm == KWM_NO)
130 global.tune.options &= ~GTUNE_BUSY_POLLING;
131 else
132 global.tune.options |= GTUNE_BUSY_POLLING;
133 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100134 else if (strcmp(args[0], "set-dumpable") == 0) { /* "no set-dumpable" or "set-dumpable" */
Willy Tarreau636848a2019-04-15 19:38:50 +0200135 if (alertif_too_many_args(0, file, linenum, args, &err_code))
136 goto out;
137 if (kwm == KWM_NO)
138 global.tune.options &= ~GTUNE_SET_DUMPABLE;
139 else
140 global.tune.options |= GTUNE_SET_DUMPABLE;
141 }
Amaury Denoyellebefeae82021-07-09 17:14:30 +0200142 else if (strcmp(args[0], "h2-workaround-bogus-websocket-clients") == 0) { /* "no h2-workaround-bogus-websocket-clients" or "h2-workaround-bogus-websocket-clients" */
143 if (alertif_too_many_args(0, file, linenum, args, &err_code))
144 goto out;
145 if (kwm == KWM_NO)
146 global.tune.options &= ~GTUNE_DISABLE_H2_WEBSOCKET;
147 else
148 global.tune.options |= GTUNE_DISABLE_H2_WEBSOCKET;
149 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100150 else if (strcmp(args[0], "insecure-fork-wanted") == 0) { /* "no insecure-fork-wanted" or "insecure-fork-wanted" */
Willy Tarreaud96f1122019-12-03 07:07:36 +0100151 if (alertif_too_many_args(0, file, linenum, args, &err_code))
152 goto out;
153 if (kwm == KWM_NO)
154 global.tune.options &= ~GTUNE_INSECURE_FORK;
155 else
156 global.tune.options |= GTUNE_INSECURE_FORK;
157 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100158 else if (strcmp(args[0], "insecure-setuid-wanted") == 0) { /* "no insecure-setuid-wanted" or "insecure-setuid-wanted" */
Willy Tarreaua45a8b52019-12-06 16:31:45 +0100159 if (alertif_too_many_args(0, file, linenum, args, &err_code))
160 goto out;
161 if (kwm == KWM_NO)
162 global.tune.options &= ~GTUNE_INSECURE_SETUID;
163 else
164 global.tune.options |= GTUNE_INSECURE_SETUID;
165 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100166 else if (strcmp(args[0], "nosplice") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100167 if (alertif_too_many_args(0, file, linenum, args, &err_code))
168 goto out;
169 global.tune.options &= ~GTUNE_USE_SPLICE;
170 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100171 else if (strcmp(args[0], "nogetaddrinfo") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100172 if (alertif_too_many_args(0, file, linenum, args, &err_code))
173 goto out;
174 global.tune.options &= ~GTUNE_USE_GAI;
175 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100176 else if (strcmp(args[0], "noreuseport") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100177 if (alertif_too_many_args(0, file, linenum, args, &err_code))
178 goto out;
Willy Tarreau785b89f2023-04-22 15:09:07 +0200179 protocol_clrf_all(PROTO_F_REUSEPORT_SUPPORTED);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100180 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100181 else if (strcmp(args[0], "quiet") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100182 if (alertif_too_many_args(0, file, linenum, args, &err_code))
183 goto out;
184 global.mode |= MODE_QUIET;
185 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100186 else if (strcmp(args[0], "zero-warning") == 0) {
Willy Tarreau3eb10b82020-04-15 16:42:39 +0200187 if (alertif_too_many_args(0, file, linenum, args, &err_code))
188 goto out;
189 global.mode |= MODE_ZERO_WARNING;
190 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100191 else if (strcmp(args[0], "tune.runqueue-depth") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100192 if (alertif_too_many_args(1, file, linenum, args, &err_code))
193 goto out;
194 if (global.tune.runqueue_depth != 0) {
195 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
196 err_code |= ERR_ALERT;
197 goto out;
198 }
199 if (*(args[1]) == 0) {
200 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
201 err_code |= ERR_ALERT | ERR_FATAL;
202 goto out;
203 }
204 global.tune.runqueue_depth = atol(args[1]);
205
206 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100207 else if (strcmp(args[0], "tune.maxpollevents") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100208 if (alertif_too_many_args(1, file, linenum, args, &err_code))
209 goto out;
210 if (global.tune.maxpollevents != 0) {
211 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
212 err_code |= ERR_ALERT;
213 goto out;
214 }
215 if (*(args[1]) == 0) {
216 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
217 err_code |= ERR_ALERT | ERR_FATAL;
218 goto out;
219 }
220 global.tune.maxpollevents = atol(args[1]);
221 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100222 else if (strcmp(args[0], "tune.maxaccept") == 0) {
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200223 long max;
224
Willy Tarreau36b9e222018-11-11 15:19:52 +0100225 if (alertif_too_many_args(1, file, linenum, args, &err_code))
226 goto out;
227 if (global.tune.maxaccept != 0) {
228 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
229 err_code |= ERR_ALERT;
230 goto out;
231 }
232 if (*(args[1]) == 0) {
233 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
234 err_code |= ERR_ALERT | ERR_FATAL;
235 goto out;
236 }
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200237 max = atol(args[1]);
238 if (/*max < -1 || */max > INT_MAX) {
239 ha_alert("parsing [%s:%d] : '%s' expects -1 or an integer from 0 to INT_MAX.\n", file, linenum, args[0]);
240 err_code |= ERR_ALERT | ERR_FATAL;
241 goto out;
242 }
243 global.tune.maxaccept = max;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100244 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100245 else if (strcmp(args[0], "tune.chksize") == 0) {
Willy Tarreaueb9d90a2021-06-11 15:29:31 +0200246 ha_alert("parsing [%s:%d]: option '%s' is not supported any more (tune.bufsize is used instead).\n", file, linenum, args[0]);
247 err_code |= ERR_ALERT | ERR_FATAL;
248 goto out;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100249 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100250 else if (strcmp(args[0], "tune.recv_enough") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100251 if (alertif_too_many_args(1, file, linenum, args, &err_code))
252 goto out;
253 if (*(args[1]) == 0) {
254 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
255 err_code |= ERR_ALERT | ERR_FATAL;
256 goto out;
257 }
258 global.tune.recv_enough = atol(args[1]);
259 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100260 else if (strcmp(args[0], "tune.buffers.limit") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100261 if (alertif_too_many_args(1, file, linenum, args, &err_code))
262 goto out;
263 if (*(args[1]) == 0) {
264 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
265 err_code |= ERR_ALERT | ERR_FATAL;
266 goto out;
267 }
268 global.tune.buf_limit = atol(args[1]);
269 if (global.tune.buf_limit) {
270 if (global.tune.buf_limit < 3)
271 global.tune.buf_limit = 3;
272 if (global.tune.buf_limit <= global.tune.reserved_bufs)
273 global.tune.buf_limit = global.tune.reserved_bufs + 1;
274 }
275 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100276 else if (strcmp(args[0], "tune.buffers.reserve") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100277 if (alertif_too_many_args(1, file, linenum, args, &err_code))
278 goto out;
279 if (*(args[1]) == 0) {
280 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
281 err_code |= ERR_ALERT | ERR_FATAL;
282 goto out;
283 }
284 global.tune.reserved_bufs = atol(args[1]);
285 if (global.tune.reserved_bufs < 2)
286 global.tune.reserved_bufs = 2;
287 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
288 global.tune.buf_limit = global.tune.reserved_bufs + 1;
289 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100290 else if (strcmp(args[0], "tune.bufsize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100291 if (alertif_too_many_args(1, file, linenum, args, &err_code))
292 goto out;
293 if (*(args[1]) == 0) {
294 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
295 err_code |= ERR_ALERT | ERR_FATAL;
296 goto out;
297 }
298 global.tune.bufsize = atol(args[1]);
Willy Tarreauc77d3642018-12-12 06:19:42 +0100299 /* round it up to support a two-pointer alignment at the end */
300 global.tune.bufsize = (global.tune.bufsize + 2 * sizeof(void *) - 1) & -(2 * sizeof(void *));
Willy Tarreau36b9e222018-11-11 15:19:52 +0100301 if (global.tune.bufsize <= 0) {
302 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
303 err_code |= ERR_ALERT | ERR_FATAL;
304 goto out;
305 }
306 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100307 else if (strcmp(args[0], "tune.maxrewrite") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100308 if (alertif_too_many_args(1, file, linenum, args, &err_code))
309 goto out;
310 if (*(args[1]) == 0) {
311 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
312 err_code |= ERR_ALERT | ERR_FATAL;
313 goto out;
314 }
315 global.tune.maxrewrite = atol(args[1]);
316 if (global.tune.maxrewrite < 0) {
317 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
318 err_code |= ERR_ALERT | ERR_FATAL;
319 goto out;
320 }
321 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100322 else if (strcmp(args[0], "tune.idletimer") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100323 unsigned int idle;
324 const char *res;
325
326 if (alertif_too_many_args(1, file, linenum, args, &err_code))
327 goto out;
328 if (*(args[1]) == 0) {
329 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
330 err_code |= ERR_ALERT | ERR_FATAL;
331 goto out;
332 }
333
334 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +0200335 if (res == PARSE_TIME_OVER) {
336 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 65535 ms.\n",
337 file, linenum, args[1], args[0]);
338 err_code |= ERR_ALERT | ERR_FATAL;
339 goto out;
340 }
341 else if (res == PARSE_TIME_UNDER) {
342 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
343 file, linenum, args[1], args[0]);
344 err_code |= ERR_ALERT | ERR_FATAL;
345 goto out;
346 }
347 else if (res) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100348 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau9faebe32019-06-07 19:00:37 +0200349 file, linenum, *res, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100350 err_code |= ERR_ALERT | ERR_FATAL;
351 goto out;
352 }
353
354 if (idle > 65535) {
355 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
356 err_code |= ERR_ALERT | ERR_FATAL;
357 goto out;
358 }
359 global.tune.idle_timer = idle;
360 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100361 else if (strcmp(args[0], "tune.rcvbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100362 if (alertif_too_many_args(1, file, linenum, args, &err_code))
363 goto out;
364 if (global.tune.client_rcvbuf != 0) {
365 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
366 err_code |= ERR_ALERT;
367 goto out;
368 }
369 if (*(args[1]) == 0) {
370 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
371 err_code |= ERR_ALERT | ERR_FATAL;
372 goto out;
373 }
374 global.tune.client_rcvbuf = atol(args[1]);
375 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100376 else if (strcmp(args[0], "tune.rcvbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100377 if (alertif_too_many_args(1, file, linenum, args, &err_code))
378 goto out;
379 if (global.tune.server_rcvbuf != 0) {
380 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
381 err_code |= ERR_ALERT;
382 goto out;
383 }
384 if (*(args[1]) == 0) {
385 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
386 err_code |= ERR_ALERT | ERR_FATAL;
387 goto out;
388 }
389 global.tune.server_rcvbuf = atol(args[1]);
390 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100391 else if (strcmp(args[0], "tune.sndbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100392 if (alertif_too_many_args(1, file, linenum, args, &err_code))
393 goto out;
394 if (global.tune.client_sndbuf != 0) {
395 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
396 err_code |= ERR_ALERT;
397 goto out;
398 }
399 if (*(args[1]) == 0) {
400 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
401 err_code |= ERR_ALERT | ERR_FATAL;
402 goto out;
403 }
404 global.tune.client_sndbuf = atol(args[1]);
405 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100406 else if (strcmp(args[0], "tune.sndbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100407 if (alertif_too_many_args(1, file, linenum, args, &err_code))
408 goto out;
409 if (global.tune.server_sndbuf != 0) {
410 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
411 err_code |= ERR_ALERT;
412 goto out;
413 }
414 if (*(args[1]) == 0) {
415 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
416 err_code |= ERR_ALERT | ERR_FATAL;
417 goto out;
418 }
419 global.tune.server_sndbuf = atol(args[1]);
420 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100421 else if (strcmp(args[0], "tune.pipesize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100422 if (alertif_too_many_args(1, file, linenum, args, &err_code))
423 goto out;
424 if (*(args[1]) == 0) {
425 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
426 err_code |= ERR_ALERT | ERR_FATAL;
427 goto out;
428 }
429 global.tune.pipesize = atol(args[1]);
430 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100431 else if (strcmp(args[0], "tune.http.cookielen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100432 if (alertif_too_many_args(1, file, linenum, args, &err_code))
433 goto out;
434 if (*(args[1]) == 0) {
435 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
436 err_code |= ERR_ALERT | ERR_FATAL;
437 goto out;
438 }
439 global.tune.cookie_len = atol(args[1]) + 1;
440 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100441 else if (strcmp(args[0], "tune.http.logurilen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100442 if (alertif_too_many_args(1, file, linenum, args, &err_code))
443 goto out;
444 if (*(args[1]) == 0) {
445 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
446 err_code |= ERR_ALERT | ERR_FATAL;
447 goto out;
448 }
449 global.tune.requri_len = atol(args[1]) + 1;
450 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100451 else if (strcmp(args[0], "tune.http.maxhdr") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100452 if (alertif_too_many_args(1, file, linenum, args, &err_code))
453 goto out;
454 if (*(args[1]) == 0) {
455 ha_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.max_http_hdr = atoi(args[1]);
460 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
461 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
462 file, linenum, args[0]);
463 err_code |= ERR_ALERT | ERR_FATAL;
464 goto out;
465 }
466 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100467 else if (strcmp(args[0], "tune.comp.maxlevel") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100468 if (alertif_too_many_args(1, file, linenum, args, &err_code))
469 goto out;
470 if (*args[1]) {
471 global.tune.comp_maxlevel = atoi(args[1]);
472 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
473 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
474 file, linenum, args[0]);
475 err_code |= ERR_ALERT | ERR_FATAL;
476 goto out;
477 }
478 } else {
479 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
480 file, linenum, args[0]);
481 err_code |= ERR_ALERT | ERR_FATAL;
482 goto out;
483 }
484 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100485 else if (strcmp(args[0], "tune.pattern.cache-size") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100486 if (*args[1]) {
487 global.tune.pattern_cache = atoi(args[1]);
488 if (global.tune.pattern_cache < 0) {
489 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
490 file, linenum, args[0]);
491 err_code |= ERR_ALERT | ERR_FATAL;
492 goto out;
493 }
494 } else {
495 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
496 file, linenum, args[0]);
497 err_code |= ERR_ALERT | ERR_FATAL;
498 goto out;
499 }
500 }
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100501 else if (strcmp(args[0], "tune.disable-fast-forward") == 0) {
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100502 if (!experimental_directives_allowed) {
503 ha_alert("parsing [%s:%d] : '%s' directive is experimental, must be allowed via a global 'expose-experimental-directives'",
504 file, linenum, args[0]);
505 err_code |= ERR_ALERT | ERR_FATAL;
506 goto out;
507 }
508 mark_tainted(TAINTED_CONFIG_EXP_KW_DECLARED);
509
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100510 if (alertif_too_many_args(0, file, linenum, args, &err_code))
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100511 goto out;
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100512 global.tune.options &= GTUNE_USE_FAST_FWD;
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100513 }
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200514 else if (strcmp(args[0], "cluster-secret") == 0) {
Frédéric Lécaille0499db42023-09-07 18:43:52 +0200515 blk_SHA_CTX sha1_ctx;
516 unsigned char sha1_out[20];
517
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200518 if (alertif_too_many_args(1, file, linenum, args, &err_code))
519 goto out;
520 if (*args[1] == 0) {
521 ha_alert("parsing [%s:%d] : expects an ASCII string argument.\n", file, linenum);
522 err_code |= ERR_ALERT | ERR_FATAL;
523 goto out;
524 }
Frédéric Lécaille0499db42023-09-07 18:43:52 +0200525 if (cluster_secret_isset) {
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200526 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
527 err_code |= ERR_ALERT;
528 goto out;
529 }
Frédéric Lécaille0499db42023-09-07 18:43:52 +0200530
531 blk_SHA1_Init(&sha1_ctx);
532 blk_SHA1_Update(&sha1_ctx, args[1], strlen(args[1]));
533 blk_SHA1_Final(sha1_out, &sha1_ctx);
534 BUG_ON(sizeof sha1_out < sizeof global.cluster_secret);
535 memcpy(global.cluster_secret, sha1_out, sizeof global.cluster_secret);
536 cluster_secret_isset = 1;
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200537 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100538 else if (strcmp(args[0], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100539 if (alertif_too_many_args(1, file, linenum, args, &err_code))
540 goto out;
541 if (global.uid != 0) {
542 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
543 err_code |= ERR_ALERT;
544 goto out;
545 }
546 if (*(args[1]) == 0) {
547 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
548 err_code |= ERR_ALERT | ERR_FATAL;
549 goto out;
550 }
551 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
552 ha_warning("parsing [%s:%d] : uid: string '%s' is not a number.\n | You might want to use the 'user' parameter to use a system user name.\n", file, linenum, args[1]);
553 err_code |= ERR_WARN;
554 goto out;
555 }
556
557 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100558 else if (strcmp(args[0], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100559 if (alertif_too_many_args(1, file, linenum, args, &err_code))
560 goto out;
561 if (global.gid != 0) {
562 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
563 err_code |= ERR_ALERT;
564 goto out;
565 }
566 if (*(args[1]) == 0) {
567 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
568 err_code |= ERR_ALERT | ERR_FATAL;
569 goto out;
570 }
571 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
572 ha_warning("parsing [%s:%d] : gid: string '%s' is not a number.\n | You might want to use the 'group' parameter to use a system group name.\n", file, linenum, args[1]);
573 err_code |= ERR_WARN;
574 goto out;
575 }
576 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100577 else if (strcmp(args[0], "external-check") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100578 if (alertif_too_many_args(0, file, linenum, args, &err_code))
579 goto out;
580 global.external_check = 1;
581 }
582 /* user/group name handling */
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100583 else if (strcmp(args[0], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100584 struct passwd *ha_user;
585 if (alertif_too_many_args(1, file, linenum, args, &err_code))
586 goto out;
587 if (global.uid != 0) {
588 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
589 err_code |= ERR_ALERT;
590 goto out;
591 }
592 errno = 0;
593 ha_user = getpwnam(args[1]);
594 if (ha_user != NULL) {
595 global.uid = (int)ha_user->pw_uid;
596 }
597 else {
598 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
599 err_code |= ERR_ALERT | ERR_FATAL;
600 }
601 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100602 else if (strcmp(args[0], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100603 struct group *ha_group;
604 if (alertif_too_many_args(1, file, linenum, args, &err_code))
605 goto out;
606 if (global.gid != 0) {
607 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
608 err_code |= ERR_ALERT;
609 goto out;
610 }
611 errno = 0;
612 ha_group = getgrnam(args[1]);
613 if (ha_group != NULL) {
614 global.gid = (int)ha_group->gr_gid;
615 }
616 else {
617 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
618 err_code |= ERR_ALERT | ERR_FATAL;
619 }
620 }
621 /* end of user/group name handling*/
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100622 else if (strcmp(args[0], "nbproc") == 0) {
Willy Tarreaub63dbb72021-06-11 16:50:29 +0200623 ha_alert("parsing [%s:%d] : nbproc is not supported any more since HAProxy 2.5. Threads will automatically be used on multi-processor machines if available.\n", file, linenum);
624 err_code |= ERR_ALERT | ERR_FATAL;
625 goto out;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100626 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100627 else if (strcmp(args[0], "maxconn") == 0) {
Thierry Fournier3d1c3342022-10-01 10:06:59 +0200628 char *stop;
629
Willy Tarreau36b9e222018-11-11 15:19:52 +0100630 if (alertif_too_many_args(1, file, linenum, args, &err_code))
631 goto out;
632 if (global.maxconn != 0) {
633 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
634 err_code |= ERR_ALERT;
635 goto out;
636 }
637 if (*(args[1]) == 0) {
638 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
639 err_code |= ERR_ALERT | ERR_FATAL;
640 goto out;
641 }
Thierry Fournier3d1c3342022-10-01 10:06:59 +0200642 global.maxconn = strtol(args[1], &stop, 10);
643 if (*stop != '\0') {
644 ha_alert("parsing [%s:%d] : cannot parse '%s' value '%s', an integer is expected.\n", file, linenum, args[0], args[1]);
645 err_code |= ERR_ALERT | ERR_FATAL;
646 goto out;
647 }
Willy Tarreau36b9e222018-11-11 15:19:52 +0100648#ifdef SYSTEM_MAXCONN
Willy Tarreauca783d42019-03-13 10:03:07 +0100649 if (global.maxconn > SYSTEM_MAXCONN && cfg_maxconn <= SYSTEM_MAXCONN) {
650 ha_alert("parsing [%s:%d] : maxconn value %d too high for this system.\nLimiting to %d. Please use '-n' to force the value.\n", file, linenum, global.maxconn, SYSTEM_MAXCONN);
651 global.maxconn = SYSTEM_MAXCONN;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100652 err_code |= ERR_ALERT;
653 }
654#endif /* SYSTEM_MAXCONN */
655 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100656 else if (strcmp(args[0], "ssl-server-verify") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100657 if (alertif_too_many_args(1, file, linenum, args, &err_code))
658 goto out;
659 if (*(args[1]) == 0) {
660 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
661 err_code |= ERR_ALERT | ERR_FATAL;
662 goto out;
663 }
664 if (strcmp(args[1],"none") == 0)
665 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
666 else if (strcmp(args[1],"required") == 0)
667 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
668 else {
669 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
670 err_code |= ERR_ALERT | ERR_FATAL;
671 goto out;
672 }
673 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100674 else if (strcmp(args[0], "maxconnrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100675 if (alertif_too_many_args(1, file, linenum, args, &err_code))
676 goto out;
677 if (global.cps_lim != 0) {
678 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
679 err_code |= ERR_ALERT;
680 goto out;
681 }
682 if (*(args[1]) == 0) {
683 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
684 err_code |= ERR_ALERT | ERR_FATAL;
685 goto out;
686 }
687 global.cps_lim = atol(args[1]);
688 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100689 else if (strcmp(args[0], "maxsessrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100690 if (alertif_too_many_args(1, file, linenum, args, &err_code))
691 goto out;
692 if (global.sps_lim != 0) {
693 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
694 err_code |= ERR_ALERT;
695 goto out;
696 }
697 if (*(args[1]) == 0) {
698 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
699 err_code |= ERR_ALERT | ERR_FATAL;
700 goto out;
701 }
702 global.sps_lim = atol(args[1]);
703 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100704 else if (strcmp(args[0], "maxsslrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100705 if (alertif_too_many_args(1, file, linenum, args, &err_code))
706 goto out;
707 if (global.ssl_lim != 0) {
708 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
709 err_code |= ERR_ALERT;
710 goto out;
711 }
712 if (*(args[1]) == 0) {
713 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
714 err_code |= ERR_ALERT | ERR_FATAL;
715 goto out;
716 }
717 global.ssl_lim = atol(args[1]);
718 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100719 else if (strcmp(args[0], "maxcomprate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100720 if (alertif_too_many_args(1, file, linenum, args, &err_code))
721 goto out;
722 if (*(args[1]) == 0) {
723 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
724 err_code |= ERR_ALERT | ERR_FATAL;
725 goto out;
726 }
727 global.comp_rate_lim = atoi(args[1]) * 1024;
728 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100729 else if (strcmp(args[0], "maxpipes") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100730 if (alertif_too_many_args(1, file, linenum, args, &err_code))
731 goto out;
732 if (global.maxpipes != 0) {
733 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
734 err_code |= ERR_ALERT;
735 goto out;
736 }
737 if (*(args[1]) == 0) {
738 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
739 err_code |= ERR_ALERT | ERR_FATAL;
740 goto out;
741 }
742 global.maxpipes = atol(args[1]);
743 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100744 else if (strcmp(args[0], "maxzlibmem") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100745 if (alertif_too_many_args(1, file, linenum, args, &err_code))
746 goto out;
747 if (*(args[1]) == 0) {
748 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
749 err_code |= ERR_ALERT | ERR_FATAL;
750 goto out;
751 }
752 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
753 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100754 else if (strcmp(args[0], "maxcompcpuusage") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100755 if (alertif_too_many_args(1, file, linenum, args, &err_code))
756 goto out;
757 if (*(args[1]) == 0) {
758 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
759 err_code |= ERR_ALERT | ERR_FATAL;
760 goto out;
761 }
762 compress_min_idle = 100 - atoi(args[1]);
763 if (compress_min_idle > 100) {
764 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
765 err_code |= ERR_ALERT | ERR_FATAL;
766 goto out;
767 }
768 }
Willy Tarreau2df1fbf2022-04-25 18:02:03 +0200769 else if (strcmp(args[0], "fd-hard-limit") == 0) {
770 if (alertif_too_many_args(1, file, linenum, args, &err_code))
771 goto out;
772 if (global.fd_hard_limit != 0) {
773 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
774 err_code |= ERR_ALERT;
775 goto out;
776 }
777 if (*(args[1]) == 0) {
778 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
779 err_code |= ERR_ALERT | ERR_FATAL;
780 goto out;
781 }
782 global.fd_hard_limit = atol(args[1]);
783 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100784 else if (strcmp(args[0], "ulimit-n") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100785 if (alertif_too_many_args(1, file, linenum, args, &err_code))
786 goto out;
787 if (global.rlimit_nofile != 0) {
788 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
789 err_code |= ERR_ALERT;
790 goto out;
791 }
792 if (*(args[1]) == 0) {
793 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
794 err_code |= ERR_ALERT | ERR_FATAL;
795 goto out;
796 }
797 global.rlimit_nofile = atol(args[1]);
798 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100799 else if (strcmp(args[0], "chroot") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100800 if (alertif_too_many_args(1, file, linenum, args, &err_code))
801 goto out;
802 if (global.chroot != NULL) {
803 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
804 err_code |= ERR_ALERT;
805 goto out;
806 }
807 if (*(args[1]) == 0) {
808 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
809 err_code |= ERR_ALERT | ERR_FATAL;
810 goto out;
811 }
812 global.chroot = strdup(args[1]);
813 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100814 else if (strcmp(args[0], "description") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100815 int i, len=0;
816 char *d;
817
818 if (!*args[1]) {
819 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
820 file, linenum, args[0]);
821 err_code |= ERR_ALERT | ERR_FATAL;
822 goto out;
823 }
824
825 for (i = 1; *args[i]; i++)
826 len += strlen(args[i]) + 1;
827
828 if (global.desc)
829 free(global.desc);
830
831 global.desc = d = calloc(1, len);
832
833 d += snprintf(d, global.desc + len - d, "%s", args[1]);
834 for (i = 2; *args[i]; i++)
835 d += snprintf(d, global.desc + len - d, " %s", args[i]);
836 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100837 else if (strcmp(args[0], "node") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100838 int i;
839 char c;
840
841 if (alertif_too_many_args(1, file, linenum, args, &err_code))
842 goto out;
843
844 for (i=0; args[1][i]; i++) {
845 c = args[1][i];
846 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
847 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
848 break;
849 }
850
851 if (!i || args[1][i]) {
852 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
853 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
854 file, linenum, args[0]);
855 err_code |= ERR_ALERT | ERR_FATAL;
856 goto out;
857 }
858
859 if (global.node)
860 free(global.node);
861
862 global.node = strdup(args[1]);
863 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100864 else if (strcmp(args[0], "pidfile") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100865 if (alertif_too_many_args(1, file, linenum, args, &err_code))
866 goto out;
867 if (global.pidfile != NULL) {
868 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
869 err_code |= ERR_ALERT;
870 goto out;
871 }
872 if (*(args[1]) == 0) {
873 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
874 err_code |= ERR_ALERT | ERR_FATAL;
875 goto out;
876 }
877 global.pidfile = strdup(args[1]);
878 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100879 else if (strcmp(args[0], "unix-bind") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100880 int cur_arg = 1;
881 while (*(args[cur_arg])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100882 if (strcmp(args[cur_arg], "prefix") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100883 if (global.unix_bind.prefix != NULL) {
884 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
885 err_code |= ERR_ALERT;
886 cur_arg += 2;
887 continue;
888 }
889
890 if (*(args[cur_arg+1]) == 0) {
891 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
892 err_code |= ERR_ALERT | ERR_FATAL;
893 goto out;
894 }
895 global.unix_bind.prefix = strdup(args[cur_arg+1]);
896 cur_arg += 2;
897 continue;
898 }
899
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100900 if (strcmp(args[cur_arg], "mode") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100901
902 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
903 cur_arg += 2;
904 continue;
905 }
906
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100907 if (strcmp(args[cur_arg], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100908
909 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
910 cur_arg += 2;
911 continue;
912 }
913
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100914 if (strcmp(args[cur_arg], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100915
916 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
917 cur_arg += 2;
918 continue;
919 }
920
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100921 if (strcmp(args[cur_arg], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100922 struct passwd *user;
923
924 user = getpwnam(args[cur_arg + 1]);
925 if (!user) {
926 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
927 file, linenum, args[0], args[cur_arg + 1 ]);
928 err_code |= ERR_ALERT | ERR_FATAL;
929 goto out;
930 }
931
932 global.unix_bind.ux.uid = user->pw_uid;
933 cur_arg += 2;
934 continue;
935 }
936
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100937 if (strcmp(args[cur_arg], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100938 struct group *group;
939
940 group = getgrnam(args[cur_arg + 1]);
941 if (!group) {
942 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
943 file, linenum, args[0], args[cur_arg + 1 ]);
944 err_code |= ERR_ALERT | ERR_FATAL;
945 goto out;
946 }
947
948 global.unix_bind.ux.gid = group->gr_gid;
949 cur_arg += 2;
950 continue;
951 }
952
953 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
954 file, linenum, args[0]);
955 err_code |= ERR_ALERT | ERR_FATAL;
956 goto out;
957 }
958 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100959 else if (strcmp(args[0], "log") == 0) { /* "no log" or "log ..." */
Emeric Brun9533a702021-04-02 10:13:43 +0200960 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), file, linenum, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100961 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
962 err_code |= ERR_ALERT | ERR_FATAL;
963 goto out;
964 }
965 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100966 else if (strcmp(args[0], "log-send-hostname") == 0) { /* set the hostname in syslog header */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100967 char *name;
968
969 if (global.log_send_hostname != NULL) {
970 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
971 err_code |= ERR_ALERT;
972 goto out;
973 }
974
975 if (*(args[1]))
976 name = args[1];
977 else
978 name = hostname;
979
980 free(global.log_send_hostname);
981 global.log_send_hostname = strdup(name);
982 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100983 else if (strcmp(args[0], "server-state-base") == 0) { /* path base where HAProxy can find server state files */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100984 if (global.server_state_base != NULL) {
985 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
986 err_code |= ERR_ALERT;
987 goto out;
988 }
989
990 if (!*(args[1])) {
991 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
992 err_code |= ERR_FATAL;
993 goto out;
994 }
995
996 global.server_state_base = strdup(args[1]);
997 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100998 else if (strcmp(args[0], "server-state-file") == 0) { /* path to the file where HAProxy can load the server states */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100999 if (global.server_state_file != NULL) {
1000 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
1001 err_code |= ERR_ALERT;
1002 goto out;
1003 }
1004
1005 if (!*(args[1])) {
1006 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
1007 err_code |= ERR_FATAL;
1008 goto out;
1009 }
1010
1011 global.server_state_file = strdup(args[1]);
1012 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001013 else if (strcmp(args[0], "log-tag") == 0) { /* tag to report to syslog */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001014 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1015 goto out;
1016 if (*(args[1]) == 0) {
1017 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
1018 err_code |= ERR_ALERT | ERR_FATAL;
1019 goto out;
1020 }
1021 chunk_destroy(&global.log_tag);
Eric Salama7cea6062020-10-02 11:58:19 +02001022 chunk_initlen(&global.log_tag, strdup(args[1]), strlen(args[1]), strlen(args[1]));
1023 if (b_orig(&global.log_tag) == NULL) {
1024 chunk_destroy(&global.log_tag);
1025 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n", file, linenum, args[0]);
1026 err_code |= ERR_ALERT | ERR_FATAL;
1027 goto out;
1028 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001029 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001030 else if (strcmp(args[0], "spread-checks") == 0) { /* random time between checks (0-50) */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001031 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1032 goto out;
1033 if (global.spread_checks != 0) {
1034 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
1035 err_code |= ERR_ALERT;
1036 goto out;
1037 }
1038 if (*(args[1]) == 0) {
1039 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1040 err_code |= ERR_ALERT | ERR_FATAL;
1041 goto out;
1042 }
1043 global.spread_checks = atol(args[1]);
1044 if (global.spread_checks < 0 || global.spread_checks > 50) {
1045 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
1046 err_code |= ERR_ALERT | ERR_FATAL;
1047 }
1048 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001049 else if (strcmp(args[0], "max-spread-checks") == 0) { /* maximum time between first and last check */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001050 const char *err;
1051 unsigned int val;
1052
1053 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1054 goto out;
1055 if (*(args[1]) == 0) {
1056 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1057 err_code |= ERR_ALERT | ERR_FATAL;
1058 goto out;
1059 }
1060
1061 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +02001062 if (err == PARSE_TIME_OVER) {
1063 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 2147483647 ms (~24.8 days).\n",
1064 file, linenum, args[1], args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001065 err_code |= ERR_ALERT | ERR_FATAL;
1066 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001067 else if (err == PARSE_TIME_UNDER) {
1068 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
1069 file, linenum, args[1], args[0]);
1070 err_code |= ERR_ALERT | ERR_FATAL;
1071 }
1072 else if (err) {
1073 ha_alert("parsing [%s:%d]: unsupported character '%c' in '%s' (wants an integer delay).\n", file, linenum, *err, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001074 err_code |= ERR_ALERT | ERR_FATAL;
1075 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001076 global.max_spread_checks = val;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001077 }
1078 else if (strcmp(args[0], "cpu-map") == 0) {
1079 /* map a process list to a CPU set */
1080#ifdef USE_CPU_AFFINITY
1081 char *slash;
Willy Tarreau5b093412022-07-08 09:38:30 +02001082 unsigned long tgroup = 0, thread = 0;
1083 int g, j, n, autoinc;
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001084 struct hap_cpuset cpus, cpus_copy;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001085
1086 if (!*args[1] || !*args[2]) {
Willy Tarreau5b093412022-07-08 09:38:30 +02001087 ha_alert("parsing [%s:%d] : %s expects a thread group number "
Willy Tarreau36b9e222018-11-11 15:19:52 +01001088 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1089 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001090 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001091 err_code |= ERR_ALERT | ERR_FATAL;
1092 goto out;
1093 }
1094
1095 if ((slash = strchr(args[1], '/')) != NULL)
1096 *slash = 0;
1097
Willy Tarreau5b093412022-07-08 09:38:30 +02001098 /* note: we silently ignore thread group numbers over MAX_TGROUPS
1099 * and threads over MAX_THREADS so as not to make configurations a
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001100 * pain to maintain.
1101 */
Willy Tarreau5b093412022-07-08 09:38:30 +02001102 if (parse_process_number(args[1], &tgroup, LONGBITS, &autoinc, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001103 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1104 err_code |= ERR_ALERT | ERR_FATAL;
1105 goto out;
1106 }
1107
1108 if (slash) {
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001109 if (parse_process_number(slash+1, &thread, LONGBITS, NULL, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001110 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1111 err_code |= ERR_ALERT | ERR_FATAL;
1112 goto out;
1113 }
1114 *slash = '/';
Willy Tarreaueded6c12023-07-19 18:17:39 +02001115 } else
1116 thread = ~0UL; /* missing '/' = 'all' */
1117
1118 /* from now on, thread cannot be NULL anymore */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001119
Willy Tarreau615c3012023-05-05 16:10:05 +02001120 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001121 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1122 err_code |= ERR_ALERT | ERR_FATAL;
1123 goto out;
1124 }
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001125
Willy Tarreau36b9e222018-11-11 15:19:52 +01001126 if (autoinc &&
Willy Tarreau5b093412022-07-08 09:38:30 +02001127 my_popcountl(tgroup) != ha_cpuset_count(&cpus) &&
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001128 my_popcountl(thread) != ha_cpuset_count(&cpus)) {
Willy Tarreau5b093412022-07-08 09:38:30 +02001129 ha_alert("parsing [%s:%d] : %s : TGROUP/THREAD range and CPU sets "
Willy Tarreau36b9e222018-11-11 15:19:52 +01001130 "must have the same size to be automatically bound\n",
1131 file, linenum, args[0]);
1132 err_code |= ERR_ALERT | ERR_FATAL;
1133 goto out;
1134 }
1135
Willy Tarreau7764a572019-07-16 15:10:34 +02001136 /* we now have to deal with 3 real cases :
Willy Tarreau5b093412022-07-08 09:38:30 +02001137 * cpu-map P-Q => mapping for whole tgroups, numbers P to Q
1138 * cpu-map P-Q/1 => mapping of first thread of groups P to Q
1139 * cpu-map P/T-U => mapping of threads T to U of tgroup P
Willy Tarreau7764a572019-07-16 15:10:34 +02001140 */
Willy Tarreau3cd71ac2022-08-22 10:38:00 +02001141 /* first tgroup, iterate on threads. E.g. cpu-map 1/1-4 0-3 */
1142 for (g = 0; g < MAX_TGROUPS; g++) {
1143 /* No mapping for this tgroup */
1144 if (!(tgroup & (1UL << g)))
1145 continue;
Willy Tarreau81492c92019-05-03 09:41:23 +02001146
Willy Tarreau3cd71ac2022-08-22 10:38:00 +02001147 ha_cpuset_assign(&cpus_copy, &cpus);
1148
Willy Tarreaueded6c12023-07-19 18:17:39 +02001149 /* a thread set is specified, apply the
1150 * CPU set to these threads.
1151 */
1152 for (j = n = 0; j < MAX_THREADS_PER_GROUP; j++) {
1153 /* No mapping for this thread */
1154 if (!(thread & (1UL << j)))
1155 continue;
1156
Willy Tarreau36b9e222018-11-11 15:19:52 +01001157 if (!autoinc)
Willy Tarreaueded6c12023-07-19 18:17:39 +02001158 ha_cpuset_assign(&cpu_map[g].thread[j], &cpus);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001159 else {
Willy Tarreaueded6c12023-07-19 18:17:39 +02001160 ha_cpuset_zero(&cpu_map[g].thread[j]);
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001161 n = ha_cpuset_ffs(&cpus_copy) - 1;
1162 ha_cpuset_clr(&cpus_copy, n);
Willy Tarreaueded6c12023-07-19 18:17:39 +02001163 ha_cpuset_set(&cpu_map[g].thread[j], n);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001164 }
1165 }
1166 }
1167#else
1168 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1169 file, linenum, args[0]);
1170 err_code |= ERR_ALERT | ERR_FATAL;
1171 goto out;
1172#endif /* ! USE_CPU_AFFINITY */
1173 }
1174 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1175 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1176 goto out;
1177
1178 if (*(args[2]) == 0) {
1179 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
1180 err_code |= ERR_ALERT | ERR_FATAL;
1181 goto out;
1182 }
1183
1184 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1185 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
1186 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
1187 err_code |= ERR_ALERT | ERR_FATAL;
1188 goto out;
1189 }
1190 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001191 else if (strcmp(args[0], "unsetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001192 int arg;
1193
1194 if (*(args[1]) == 0) {
1195 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
1196 err_code |= ERR_ALERT | ERR_FATAL;
1197 goto out;
1198 }
1199
1200 for (arg = 1; *args[arg]; arg++) {
1201 if (unsetenv(args[arg]) != 0) {
1202 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
1203 err_code |= ERR_ALERT | ERR_FATAL;
1204 goto out;
1205 }
1206 }
1207 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001208 else if (strcmp(args[0], "resetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001209 extern char **environ;
1210 char **env = environ;
1211
1212 /* args contain variable names to keep, one per argument */
1213 while (*env) {
1214 int arg;
1215
1216 /* look for current variable in among all those we want to keep */
1217 for (arg = 1; *args[arg]; arg++) {
1218 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1219 (*env)[strlen(args[arg])] == '=')
1220 break;
1221 }
1222
1223 /* delete this variable */
1224 if (!*args[arg]) {
1225 char *delim = strchr(*env, '=');
1226
1227 if (!delim || delim - *env >= trash.size) {
1228 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
1229 err_code |= ERR_ALERT | ERR_FATAL;
1230 goto out;
1231 }
1232
1233 memcpy(trash.area, *env, delim - *env);
1234 trash.area[delim - *env] = 0;
1235
1236 if (unsetenv(trash.area) != 0) {
1237 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
1238 err_code |= ERR_ALERT | ERR_FATAL;
1239 goto out;
1240 }
1241 }
1242 else
1243 env++;
1244 }
1245 }
Willy Tarreaue98d3852022-11-15 09:34:07 +01001246 else if (strcmp(args[0], "quick-exit") == 0) {
1247 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1248 goto out;
1249 global.tune.options |= GTUNE_QUICK_EXIT;
1250 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001251 else if (strcmp(args[0], "strict-limits") == 0) { /* "no strict-limits" or "strict-limits" */
William Dauchy0fec3ab2019-10-27 20:08:11 +01001252 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1253 goto out;
1254 if (kwm == KWM_NO)
1255 global.tune.options &= ~GTUNE_STRICT_LIMITS;
William Dauchy0fec3ab2019-10-27 20:08:11 +01001256 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001257 else if (strcmp(args[0], "localpeer") == 0) {
Dragan Dosen13cd54c2020-06-18 18:24:05 +02001258 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1259 goto out;
1260
1261 if (*(args[1]) == 0) {
1262 ha_alert("parsing [%s:%d] : '%s' expects a name as an argument.\n",
1263 file, linenum, args[0]);
1264 err_code |= ERR_ALERT | ERR_FATAL;
1265 goto out;
1266 }
1267
1268 if (global.localpeer_cmdline != 0) {
1269 ha_warning("parsing [%s:%d] : '%s' ignored since it is already set by using the '-L' "
1270 "command line argument.\n", file, linenum, args[0]);
1271 err_code |= ERR_WARN;
1272 goto out;
1273 }
1274
1275 if (cfg_peers) {
1276 ha_warning("parsing [%s:%d] : '%s' ignored since it is used after 'peers' section.\n",
1277 file, linenum, args[0]);
1278 err_code |= ERR_WARN;
1279 goto out;
1280 }
1281
1282 free(localpeer);
1283 if ((localpeer = strdup(args[1])) == NULL) {
1284 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n",
1285 file, linenum, args[0]);
1286 err_code |= ERR_ALERT | ERR_FATAL;
1287 goto out;
1288 }
1289 setenv("HAPROXY_LOCALPEER", localpeer, 1);
1290 }
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +01001291 else if (strcmp(args[0], "numa-cpu-mapping") == 0) {
1292 global.numa_cpu_mapping = (kwm == KWM_NO) ? 0 : 1;
1293 }
Erwan Le Goasfad9da82022-09-14 17:24:22 +02001294 else if (strcmp(args[0], "anonkey") == 0) {
1295 long long tmp = 0;
1296
1297 if (*args[1] == 0) {
1298 ha_alert("parsing [%s:%d]: a key is expected after '%s'.\n",
1299 file, linenum, args[0]);
1300 err_code |= ERR_ALERT | ERR_FATAL;
1301 goto out;
1302 }
1303
1304 if (HA_ATOMIC_LOAD(&global.anon_key) == 0) {
1305 tmp = atoll(args[1]);
1306 if (tmp < 0 || tmp > UINT_MAX) {
1307 ha_alert("parsing [%s:%d]: '%s' value must be within range %u-%u (was '%s').\n",
1308 file, linenum, args[0], 0, UINT_MAX, args[1]);
1309 err_code |= ERR_ALERT | ERR_FATAL;
1310 goto out;
1311 }
1312
1313 HA_ATOMIC_STORE(&global.anon_key, tmp);
1314 }
1315 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001316 else {
1317 struct cfg_kw_list *kwl;
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001318 const char *best;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001319 int index;
1320 int rc;
1321
1322 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1323 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1324 if (kwl->kw[index].section != CFG_GLOBAL)
1325 continue;
1326 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001327 if (check_kw_experimental(&kwl->kw[index], file, linenum, &errmsg)) {
Amaury Denoyelle86c1d0f2021-05-07 15:07:21 +02001328 ha_alert("%s\n", errmsg);
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001329 err_code |= ERR_ALERT | ERR_FATAL;
1330 goto out;
1331 }
1332
Willy Tarreau36b9e222018-11-11 15:19:52 +01001333 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
1334 if (rc < 0) {
1335 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1336 err_code |= ERR_ALERT | ERR_FATAL;
1337 }
1338 else if (rc > 0) {
1339 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1340 err_code |= ERR_WARN;
1341 goto out;
1342 }
1343 goto out;
1344 }
1345 }
1346 }
1347
Willy Tarreau101df312021-03-15 09:12:41 +01001348 best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_GLOBAL, common_kw_list);
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001349 if (best)
1350 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best);
1351 else
1352 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau36b9e222018-11-11 15:19:52 +01001353 err_code |= ERR_ALERT | ERR_FATAL;
1354 }
1355
1356 out:
1357 free(errmsg);
1358 return err_code;
1359}
1360
Patrick Hemmer425d7ad2023-05-23 13:02:08 -04001361static int cfg_parse_prealloc_fd(char **args, int section_type, struct proxy *curpx,
1362 const struct proxy *defpx, const char *file, int line,
1363 char **err)
1364{
1365 if (too_many_args(0, args, err, NULL))
1366 return -1;
1367
1368 global.prealloc_fd = 1;
1369
1370 return 0;
1371}
1372
1373static struct cfg_kw_list cfg_kws = {ILH, {
1374 { CFG_GLOBAL, "prealloc-fd", cfg_parse_prealloc_fd },
1375 { 0, NULL, NULL },
1376}};
1377
1378INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);