blob: e46672e15961c22c7dd8d4f517be98d84f87f4c1 [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
Eric Salama7cea6062020-10-02 11:58:19 +020014#include <haproxy/buf.h>
Willy Tarreau6be78492020-06-05 00:00:29 +020015#include <haproxy/cfgparse.h>
Amaury Denoyellea6f9c5d2021-04-23 16:58:08 +020016#ifdef USE_CPU_AFFINITY
Amaury Denoyellec90932b2021-04-14 16:16:03 +020017#include <haproxy/cpuset.h>
Amaury Denoyellea6f9c5d2021-04-23 16:58:08 +020018#endif
Willy Tarreau0a3bd392020-06-04 08:52:38 +020019#include <haproxy/compression.h>
Willy Tarreaudfd3de82020-06-04 23:46:14 +020020#include <haproxy/global.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020021#include <haproxy/log.h>
Dragan Dosen13cd54c2020-06-18 18:24:05 +020022#include <haproxy/peers.h>
Willy Tarreau36979d92020-06-05 17:27:29 +020023#include <haproxy/tools.h>
Willy Tarreau36b9e222018-11-11 15:19:52 +010024
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010025/* some keywords that are still being parsed using strcmp() and are not
26 * registered anywhere. They are used as suggestions for mistyped words.
27 */
28static const char *common_kw_list[] = {
29 "global", "daemon", "master-worker", "noepoll", "nokqueue",
30 "noevports", "nopoll", "busy-polling", "set-dumpable",
31 "insecure-fork-wanted", "insecure-setuid-wanted", "nosplice",
32 "nogetaddrinfo", "noreuseport", "quiet", "zero-warning",
33 "tune.runqueue-depth", "tune.maxpollevents", "tune.maxaccept",
Willy Tarreaueb9d90a2021-06-11 15:29:31 +020034 "tune.recv_enough", "tune.buffers.limit",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010035 "tune.buffers.reserve", "tune.bufsize", "tune.maxrewrite",
36 "tune.idletimer", "tune.rcvbuf.client", "tune.rcvbuf.server",
37 "tune.sndbuf.client", "tune.sndbuf.server", "tune.pipesize",
38 "tune.http.cookielen", "tune.http.logurilen", "tune.http.maxhdr",
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +010039 "tune.comp.maxlevel", "tune.pattern.cache-size",
40 "tune.fast-forward", "uid", "gid",
Willy Tarreau51ec03a2021-09-22 11:55:22 +020041 "external-check", "user", "group", "nbproc", "maxconn",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010042 "ssl-server-verify", "maxconnrate", "maxsessrate", "maxsslrate",
43 "maxcomprate", "maxpipes", "maxzlibmem", "maxcompcpuusage", "ulimit-n",
44 "chroot", "description", "node", "pidfile", "unix-bind", "log",
45 "log-send-hostname", "server-state-base", "server-state-file",
46 "log-tag", "spread-checks", "max-spread-checks", "cpu-map", "setenv",
47 "presetenv", "unsetenv", "resetenv", "strict-limits", "localpeer",
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +010048 "numa-cpu-mapping", "defaults", "listen", "frontend", "backend",
Frédéric Lécaille12a03172023-01-12 15:23:54 +010049 "peers", "resolvers", "cluster-secret", "no-quic",
Willy Tarreaua0e8eb82021-03-12 09:30:14 +010050 NULL /* must be last */
51};
52
Willy Tarreau36b9e222018-11-11 15:19:52 +010053/*
54 * parse a line in a <global> section. Returns the error code, 0 if OK, or
55 * any combination of :
56 * - ERR_ABORT: must abort ASAP
57 * - ERR_FATAL: we can continue parsing but not start the service
58 * - ERR_WARN: a warning has been emitted
59 * - ERR_ALERT: an alert has been emitted
60 * Only the two first ones can stop processing, the two others are just
61 * indicators.
62 */
63int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
64{
65 int err_code = 0;
66 char *errmsg = NULL;
67
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010068 if (strcmp(args[0], "global") == 0) { /* new section */
Willy Tarreau36b9e222018-11-11 15:19:52 +010069 /* no option, nothing special to do */
70 alertif_too_many_args(0, file, linenum, args, &err_code);
71 goto out;
72 }
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +020073 else if (strcmp(args[0], "expose-experimental-directives") == 0) {
74 experimental_directives_allowed = 1;
75 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010076 else if (strcmp(args[0], "daemon") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010077 if (alertif_too_many_args(0, file, linenum, args, &err_code))
78 goto out;
79 global.mode |= MODE_DAEMON;
80 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010081 else if (strcmp(args[0], "master-worker") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010082 if (alertif_too_many_args(1, file, linenum, args, &err_code))
83 goto out;
84 if (*args[1]) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010085 if (strcmp(args[1], "no-exit-on-failure") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010086 global.tune.options |= GTUNE_NOEXIT_ONFAILURE;
87 } else {
88 ha_alert("parsing [%s:%d] : '%s' only supports 'no-exit-on-failure' option.\n", file, linenum, args[0]);
89 err_code |= ERR_ALERT | ERR_FATAL;
90 goto out;
91 }
92 }
93 global.mode |= MODE_MWORKER;
94 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +010095 else if (strcmp(args[0], "noepoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +010096 if (alertif_too_many_args(0, file, linenum, args, &err_code))
97 goto out;
98 global.tune.options &= ~GTUNE_USE_EPOLL;
99 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100100 else if (strcmp(args[0], "nokqueue") == 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_KQUEUE;
104 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100105 else if (strcmp(args[0], "noevports") == 0) {
Emmanuel Hocdet0ba4f482019-04-08 16:53:32 +0000106 if (alertif_too_many_args(0, file, linenum, args, &err_code))
107 goto out;
108 global.tune.options &= ~GTUNE_USE_EVPORTS;
109 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100110 else if (strcmp(args[0], "nopoll") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100111 if (alertif_too_many_args(0, file, linenum, args, &err_code))
112 goto out;
113 global.tune.options &= ~GTUNE_USE_POLL;
114 }
Frédéric Lécaille12a03172023-01-12 15:23:54 +0100115 else if (strcmp(args[0], "no-quic") == 0) {
116 if (alertif_too_many_args(0, file, linenum, args, &err_code))
117 goto out;
118
119 global.tune.options |= GTUNE_NO_QUIC;
120 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100121 else if (strcmp(args[0], "busy-polling") == 0) { /* "no busy-polling" or "busy-polling" */
Willy Tarreaubeb859a2018-11-22 18:07:59 +0100122 if (alertif_too_many_args(0, file, linenum, args, &err_code))
123 goto out;
124 if (kwm == KWM_NO)
125 global.tune.options &= ~GTUNE_BUSY_POLLING;
126 else
127 global.tune.options |= GTUNE_BUSY_POLLING;
128 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100129 else if (strcmp(args[0], "set-dumpable") == 0) { /* "no set-dumpable" or "set-dumpable" */
Willy Tarreau636848a2019-04-15 19:38:50 +0200130 if (alertif_too_many_args(0, file, linenum, args, &err_code))
131 goto out;
132 if (kwm == KWM_NO)
133 global.tune.options &= ~GTUNE_SET_DUMPABLE;
134 else
135 global.tune.options |= GTUNE_SET_DUMPABLE;
136 }
Amaury Denoyellebefeae82021-07-09 17:14:30 +0200137 else if (strcmp(args[0], "h2-workaround-bogus-websocket-clients") == 0) { /* "no h2-workaround-bogus-websocket-clients" or "h2-workaround-bogus-websocket-clients" */
138 if (alertif_too_many_args(0, file, linenum, args, &err_code))
139 goto out;
140 if (kwm == KWM_NO)
141 global.tune.options &= ~GTUNE_DISABLE_H2_WEBSOCKET;
142 else
143 global.tune.options |= GTUNE_DISABLE_H2_WEBSOCKET;
144 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100145 else if (strcmp(args[0], "insecure-fork-wanted") == 0) { /* "no insecure-fork-wanted" or "insecure-fork-wanted" */
Willy Tarreaud96f1122019-12-03 07:07:36 +0100146 if (alertif_too_many_args(0, file, linenum, args, &err_code))
147 goto out;
148 if (kwm == KWM_NO)
149 global.tune.options &= ~GTUNE_INSECURE_FORK;
150 else
151 global.tune.options |= GTUNE_INSECURE_FORK;
152 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100153 else if (strcmp(args[0], "insecure-setuid-wanted") == 0) { /* "no insecure-setuid-wanted" or "insecure-setuid-wanted" */
Willy Tarreaua45a8b52019-12-06 16:31:45 +0100154 if (alertif_too_many_args(0, file, linenum, args, &err_code))
155 goto out;
156 if (kwm == KWM_NO)
157 global.tune.options &= ~GTUNE_INSECURE_SETUID;
158 else
159 global.tune.options |= GTUNE_INSECURE_SETUID;
160 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100161 else if (strcmp(args[0], "nosplice") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100162 if (alertif_too_many_args(0, file, linenum, args, &err_code))
163 goto out;
164 global.tune.options &= ~GTUNE_USE_SPLICE;
165 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100166 else if (strcmp(args[0], "nogetaddrinfo") == 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_GAI;
170 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100171 else if (strcmp(args[0], "noreuseport") == 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_REUSEPORT;
175 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100176 else if (strcmp(args[0], "quiet") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100177 if (alertif_too_many_args(0, file, linenum, args, &err_code))
178 goto out;
179 global.mode |= MODE_QUIET;
180 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100181 else if (strcmp(args[0], "zero-warning") == 0) {
Willy Tarreau3eb10b82020-04-15 16:42:39 +0200182 if (alertif_too_many_args(0, file, linenum, args, &err_code))
183 goto out;
184 global.mode |= MODE_ZERO_WARNING;
185 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100186 else if (strcmp(args[0], "tune.runqueue-depth") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100187 if (alertif_too_many_args(1, file, linenum, args, &err_code))
188 goto out;
189 if (global.tune.runqueue_depth != 0) {
190 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
191 err_code |= ERR_ALERT;
192 goto out;
193 }
194 if (*(args[1]) == 0) {
195 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
196 err_code |= ERR_ALERT | ERR_FATAL;
197 goto out;
198 }
199 global.tune.runqueue_depth = atol(args[1]);
200
201 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100202 else if (strcmp(args[0], "tune.maxpollevents") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100203 if (alertif_too_many_args(1, file, linenum, args, &err_code))
204 goto out;
205 if (global.tune.maxpollevents != 0) {
206 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
207 err_code |= ERR_ALERT;
208 goto out;
209 }
210 if (*(args[1]) == 0) {
211 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
212 err_code |= ERR_ALERT | ERR_FATAL;
213 goto out;
214 }
215 global.tune.maxpollevents = atol(args[1]);
216 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100217 else if (strcmp(args[0], "tune.maxaccept") == 0) {
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200218 long max;
219
Willy Tarreau36b9e222018-11-11 15:19:52 +0100220 if (alertif_too_many_args(1, file, linenum, args, &err_code))
221 goto out;
222 if (global.tune.maxaccept != 0) {
223 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
224 err_code |= ERR_ALERT;
225 goto out;
226 }
227 if (*(args[1]) == 0) {
228 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
229 err_code |= ERR_ALERT | ERR_FATAL;
230 goto out;
231 }
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200232 max = atol(args[1]);
233 if (/*max < -1 || */max > INT_MAX) {
234 ha_alert("parsing [%s:%d] : '%s' expects -1 or an integer from 0 to INT_MAX.\n", file, linenum, args[0]);
235 err_code |= ERR_ALERT | ERR_FATAL;
236 goto out;
237 }
238 global.tune.maxaccept = max;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100239 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100240 else if (strcmp(args[0], "tune.chksize") == 0) {
Willy Tarreaueb9d90a2021-06-11 15:29:31 +0200241 ha_alert("parsing [%s:%d]: option '%s' is not supported any more (tune.bufsize is used instead).\n", file, linenum, args[0]);
242 err_code |= ERR_ALERT | ERR_FATAL;
243 goto out;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100244 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100245 else if (strcmp(args[0], "tune.recv_enough") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100246 if (alertif_too_many_args(1, file, linenum, args, &err_code))
247 goto out;
248 if (*(args[1]) == 0) {
249 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
250 err_code |= ERR_ALERT | ERR_FATAL;
251 goto out;
252 }
253 global.tune.recv_enough = atol(args[1]);
254 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100255 else if (strcmp(args[0], "tune.buffers.limit") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100256 if (alertif_too_many_args(1, file, linenum, args, &err_code))
257 goto out;
258 if (*(args[1]) == 0) {
259 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
260 err_code |= ERR_ALERT | ERR_FATAL;
261 goto out;
262 }
263 global.tune.buf_limit = atol(args[1]);
264 if (global.tune.buf_limit) {
265 if (global.tune.buf_limit < 3)
266 global.tune.buf_limit = 3;
267 if (global.tune.buf_limit <= global.tune.reserved_bufs)
268 global.tune.buf_limit = global.tune.reserved_bufs + 1;
269 }
270 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100271 else if (strcmp(args[0], "tune.buffers.reserve") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100272 if (alertif_too_many_args(1, file, linenum, args, &err_code))
273 goto out;
274 if (*(args[1]) == 0) {
275 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
276 err_code |= ERR_ALERT | ERR_FATAL;
277 goto out;
278 }
279 global.tune.reserved_bufs = atol(args[1]);
280 if (global.tune.reserved_bufs < 2)
281 global.tune.reserved_bufs = 2;
282 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
283 global.tune.buf_limit = global.tune.reserved_bufs + 1;
284 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100285 else if (strcmp(args[0], "tune.bufsize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100286 if (alertif_too_many_args(1, file, linenum, args, &err_code))
287 goto out;
288 if (*(args[1]) == 0) {
289 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
290 err_code |= ERR_ALERT | ERR_FATAL;
291 goto out;
292 }
293 global.tune.bufsize = atol(args[1]);
Willy Tarreauc77d3642018-12-12 06:19:42 +0100294 /* round it up to support a two-pointer alignment at the end */
295 global.tune.bufsize = (global.tune.bufsize + 2 * sizeof(void *) - 1) & -(2 * sizeof(void *));
Willy Tarreau36b9e222018-11-11 15:19:52 +0100296 if (global.tune.bufsize <= 0) {
297 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
298 err_code |= ERR_ALERT | ERR_FATAL;
299 goto out;
300 }
301 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100302 else if (strcmp(args[0], "tune.maxrewrite") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100303 if (alertif_too_many_args(1, file, linenum, args, &err_code))
304 goto out;
305 if (*(args[1]) == 0) {
306 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
307 err_code |= ERR_ALERT | ERR_FATAL;
308 goto out;
309 }
310 global.tune.maxrewrite = atol(args[1]);
311 if (global.tune.maxrewrite < 0) {
312 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
313 err_code |= ERR_ALERT | ERR_FATAL;
314 goto out;
315 }
316 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100317 else if (strcmp(args[0], "tune.idletimer") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100318 unsigned int idle;
319 const char *res;
320
321 if (alertif_too_many_args(1, file, linenum, args, &err_code))
322 goto out;
323 if (*(args[1]) == 0) {
324 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
325 err_code |= ERR_ALERT | ERR_FATAL;
326 goto out;
327 }
328
329 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +0200330 if (res == PARSE_TIME_OVER) {
331 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 65535 ms.\n",
332 file, linenum, args[1], args[0]);
333 err_code |= ERR_ALERT | ERR_FATAL;
334 goto out;
335 }
336 else if (res == PARSE_TIME_UNDER) {
337 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
338 file, linenum, args[1], args[0]);
339 err_code |= ERR_ALERT | ERR_FATAL;
340 goto out;
341 }
342 else if (res) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100343 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau9faebe32019-06-07 19:00:37 +0200344 file, linenum, *res, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100345 err_code |= ERR_ALERT | ERR_FATAL;
346 goto out;
347 }
348
349 if (idle > 65535) {
350 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
351 err_code |= ERR_ALERT | ERR_FATAL;
352 goto out;
353 }
354 global.tune.idle_timer = idle;
355 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100356 else if (strcmp(args[0], "tune.rcvbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100357 if (alertif_too_many_args(1, file, linenum, args, &err_code))
358 goto out;
359 if (global.tune.client_rcvbuf != 0) {
360 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
361 err_code |= ERR_ALERT;
362 goto out;
363 }
364 if (*(args[1]) == 0) {
365 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
366 err_code |= ERR_ALERT | ERR_FATAL;
367 goto out;
368 }
369 global.tune.client_rcvbuf = atol(args[1]);
370 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100371 else if (strcmp(args[0], "tune.rcvbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100372 if (alertif_too_many_args(1, file, linenum, args, &err_code))
373 goto out;
374 if (global.tune.server_rcvbuf != 0) {
375 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
376 err_code |= ERR_ALERT;
377 goto out;
378 }
379 if (*(args[1]) == 0) {
380 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
381 err_code |= ERR_ALERT | ERR_FATAL;
382 goto out;
383 }
384 global.tune.server_rcvbuf = atol(args[1]);
385 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100386 else if (strcmp(args[0], "tune.sndbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100387 if (alertif_too_many_args(1, file, linenum, args, &err_code))
388 goto out;
389 if (global.tune.client_sndbuf != 0) {
390 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
391 err_code |= ERR_ALERT;
392 goto out;
393 }
394 if (*(args[1]) == 0) {
395 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
396 err_code |= ERR_ALERT | ERR_FATAL;
397 goto out;
398 }
399 global.tune.client_sndbuf = atol(args[1]);
400 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100401 else if (strcmp(args[0], "tune.sndbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100402 if (alertif_too_many_args(1, file, linenum, args, &err_code))
403 goto out;
404 if (global.tune.server_sndbuf != 0) {
405 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
406 err_code |= ERR_ALERT;
407 goto out;
408 }
409 if (*(args[1]) == 0) {
410 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
411 err_code |= ERR_ALERT | ERR_FATAL;
412 goto out;
413 }
414 global.tune.server_sndbuf = atol(args[1]);
415 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100416 else if (strcmp(args[0], "tune.pipesize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100417 if (alertif_too_many_args(1, file, linenum, args, &err_code))
418 goto out;
419 if (*(args[1]) == 0) {
420 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
421 err_code |= ERR_ALERT | ERR_FATAL;
422 goto out;
423 }
424 global.tune.pipesize = atol(args[1]);
425 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100426 else if (strcmp(args[0], "tune.http.cookielen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100427 if (alertif_too_many_args(1, file, linenum, args, &err_code))
428 goto out;
429 if (*(args[1]) == 0) {
430 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
431 err_code |= ERR_ALERT | ERR_FATAL;
432 goto out;
433 }
434 global.tune.cookie_len = atol(args[1]) + 1;
435 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100436 else if (strcmp(args[0], "tune.http.logurilen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100437 if (alertif_too_many_args(1, file, linenum, args, &err_code))
438 goto out;
439 if (*(args[1]) == 0) {
440 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
441 err_code |= ERR_ALERT | ERR_FATAL;
442 goto out;
443 }
444 global.tune.requri_len = atol(args[1]) + 1;
445 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100446 else if (strcmp(args[0], "tune.http.maxhdr") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100447 if (alertif_too_many_args(1, file, linenum, args, &err_code))
448 goto out;
449 if (*(args[1]) == 0) {
450 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
451 err_code |= ERR_ALERT | ERR_FATAL;
452 goto out;
453 }
454 global.tune.max_http_hdr = atoi(args[1]);
455 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
456 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
457 file, linenum, args[0]);
458 err_code |= ERR_ALERT | ERR_FATAL;
459 goto out;
460 }
461 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100462 else if (strcmp(args[0], "tune.comp.maxlevel") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100463 if (alertif_too_many_args(1, file, linenum, args, &err_code))
464 goto out;
465 if (*args[1]) {
466 global.tune.comp_maxlevel = atoi(args[1]);
467 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
468 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
469 file, linenum, args[0]);
470 err_code |= ERR_ALERT | ERR_FATAL;
471 goto out;
472 }
473 } else {
474 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
475 file, linenum, args[0]);
476 err_code |= ERR_ALERT | ERR_FATAL;
477 goto out;
478 }
479 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100480 else if (strcmp(args[0], "tune.pattern.cache-size") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100481 if (*args[1]) {
482 global.tune.pattern_cache = atoi(args[1]);
483 if (global.tune.pattern_cache < 0) {
484 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
485 file, linenum, args[0]);
486 err_code |= ERR_ALERT | ERR_FATAL;
487 goto out;
488 }
489 } else {
490 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
491 file, linenum, args[0]);
492 err_code |= ERR_ALERT | ERR_FATAL;
493 goto out;
494 }
495 }
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100496 else if (strcmp(args[0], "tune.disable-fast-forward") == 0) {
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100497 if (!experimental_directives_allowed) {
498 ha_alert("parsing [%s:%d] : '%s' directive is experimental, must be allowed via a global 'expose-experimental-directives'",
499 file, linenum, args[0]);
500 err_code |= ERR_ALERT | ERR_FATAL;
501 goto out;
502 }
503 mark_tainted(TAINTED_CONFIG_EXP_KW_DECLARED);
504
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100505 if (alertif_too_many_args(0, file, linenum, args, &err_code))
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100506 goto out;
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100507 global.tune.options &= GTUNE_USE_FAST_FWD;
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100508 }
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200509 else if (strcmp(args[0], "cluster-secret") == 0) {
510 if (alertif_too_many_args(1, file, linenum, args, &err_code))
511 goto out;
512 if (*args[1] == 0) {
513 ha_alert("parsing [%s:%d] : expects an ASCII string argument.\n", file, linenum);
514 err_code |= ERR_ALERT | ERR_FATAL;
515 goto out;
516 }
517 if (global.cluster_secret != NULL) {
518 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
519 err_code |= ERR_ALERT;
520 goto out;
521 }
522 ha_free(&global.cluster_secret);
523 global.cluster_secret = strdup(args[1]);
524 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100525 else if (strcmp(args[0], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100526 if (alertif_too_many_args(1, file, linenum, args, &err_code))
527 goto out;
528 if (global.uid != 0) {
529 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
530 err_code |= ERR_ALERT;
531 goto out;
532 }
533 if (*(args[1]) == 0) {
534 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
535 err_code |= ERR_ALERT | ERR_FATAL;
536 goto out;
537 }
538 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
539 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]);
540 err_code |= ERR_WARN;
541 goto out;
542 }
543
544 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100545 else if (strcmp(args[0], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100546 if (alertif_too_many_args(1, file, linenum, args, &err_code))
547 goto out;
548 if (global.gid != 0) {
549 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
550 err_code |= ERR_ALERT;
551 goto out;
552 }
553 if (*(args[1]) == 0) {
554 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
555 err_code |= ERR_ALERT | ERR_FATAL;
556 goto out;
557 }
558 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
559 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]);
560 err_code |= ERR_WARN;
561 goto out;
562 }
563 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100564 else if (strcmp(args[0], "external-check") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100565 if (alertif_too_many_args(0, file, linenum, args, &err_code))
566 goto out;
567 global.external_check = 1;
568 }
569 /* user/group name handling */
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100570 else if (strcmp(args[0], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100571 struct passwd *ha_user;
572 if (alertif_too_many_args(1, file, linenum, args, &err_code))
573 goto out;
574 if (global.uid != 0) {
575 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
576 err_code |= ERR_ALERT;
577 goto out;
578 }
579 errno = 0;
580 ha_user = getpwnam(args[1]);
581 if (ha_user != NULL) {
582 global.uid = (int)ha_user->pw_uid;
583 }
584 else {
585 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
586 err_code |= ERR_ALERT | ERR_FATAL;
587 }
588 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100589 else if (strcmp(args[0], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100590 struct group *ha_group;
591 if (alertif_too_many_args(1, file, linenum, args, &err_code))
592 goto out;
593 if (global.gid != 0) {
594 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
595 err_code |= ERR_ALERT;
596 goto out;
597 }
598 errno = 0;
599 ha_group = getgrnam(args[1]);
600 if (ha_group != NULL) {
601 global.gid = (int)ha_group->gr_gid;
602 }
603 else {
604 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
605 err_code |= ERR_ALERT | ERR_FATAL;
606 }
607 }
608 /* end of user/group name handling*/
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100609 else if (strcmp(args[0], "nbproc") == 0) {
Willy Tarreaub63dbb72021-06-11 16:50:29 +0200610 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);
611 err_code |= ERR_ALERT | ERR_FATAL;
612 goto out;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100613 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100614 else if (strcmp(args[0], "maxconn") == 0) {
Thierry Fournier3d1c3342022-10-01 10:06:59 +0200615 char *stop;
616
Willy Tarreau36b9e222018-11-11 15:19:52 +0100617 if (alertif_too_many_args(1, file, linenum, args, &err_code))
618 goto out;
619 if (global.maxconn != 0) {
620 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
621 err_code |= ERR_ALERT;
622 goto out;
623 }
624 if (*(args[1]) == 0) {
625 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
626 err_code |= ERR_ALERT | ERR_FATAL;
627 goto out;
628 }
Thierry Fournier3d1c3342022-10-01 10:06:59 +0200629 global.maxconn = strtol(args[1], &stop, 10);
630 if (*stop != '\0') {
631 ha_alert("parsing [%s:%d] : cannot parse '%s' value '%s', an integer is expected.\n", file, linenum, args[0], args[1]);
632 err_code |= ERR_ALERT | ERR_FATAL;
633 goto out;
634 }
Willy Tarreau36b9e222018-11-11 15:19:52 +0100635#ifdef SYSTEM_MAXCONN
Willy Tarreauca783d42019-03-13 10:03:07 +0100636 if (global.maxconn > SYSTEM_MAXCONN && cfg_maxconn <= SYSTEM_MAXCONN) {
637 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);
638 global.maxconn = SYSTEM_MAXCONN;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100639 err_code |= ERR_ALERT;
640 }
641#endif /* SYSTEM_MAXCONN */
642 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100643 else if (strcmp(args[0], "ssl-server-verify") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100644 if (alertif_too_many_args(1, file, linenum, args, &err_code))
645 goto out;
646 if (*(args[1]) == 0) {
647 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
648 err_code |= ERR_ALERT | ERR_FATAL;
649 goto out;
650 }
651 if (strcmp(args[1],"none") == 0)
652 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
653 else if (strcmp(args[1],"required") == 0)
654 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
655 else {
656 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
657 err_code |= ERR_ALERT | ERR_FATAL;
658 goto out;
659 }
660 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100661 else if (strcmp(args[0], "maxconnrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100662 if (alertif_too_many_args(1, file, linenum, args, &err_code))
663 goto out;
664 if (global.cps_lim != 0) {
665 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
666 err_code |= ERR_ALERT;
667 goto out;
668 }
669 if (*(args[1]) == 0) {
670 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
671 err_code |= ERR_ALERT | ERR_FATAL;
672 goto out;
673 }
674 global.cps_lim = atol(args[1]);
675 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100676 else if (strcmp(args[0], "maxsessrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100677 if (alertif_too_many_args(1, file, linenum, args, &err_code))
678 goto out;
679 if (global.sps_lim != 0) {
680 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
681 err_code |= ERR_ALERT;
682 goto out;
683 }
684 if (*(args[1]) == 0) {
685 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
686 err_code |= ERR_ALERT | ERR_FATAL;
687 goto out;
688 }
689 global.sps_lim = atol(args[1]);
690 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100691 else if (strcmp(args[0], "maxsslrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100692 if (alertif_too_many_args(1, file, linenum, args, &err_code))
693 goto out;
694 if (global.ssl_lim != 0) {
695 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
696 err_code |= ERR_ALERT;
697 goto out;
698 }
699 if (*(args[1]) == 0) {
700 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
701 err_code |= ERR_ALERT | ERR_FATAL;
702 goto out;
703 }
704 global.ssl_lim = atol(args[1]);
705 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100706 else if (strcmp(args[0], "maxcomprate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100707 if (alertif_too_many_args(1, file, linenum, args, &err_code))
708 goto out;
709 if (*(args[1]) == 0) {
710 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
711 err_code |= ERR_ALERT | ERR_FATAL;
712 goto out;
713 }
714 global.comp_rate_lim = atoi(args[1]) * 1024;
715 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100716 else if (strcmp(args[0], "maxpipes") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100717 if (alertif_too_many_args(1, file, linenum, args, &err_code))
718 goto out;
719 if (global.maxpipes != 0) {
720 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
721 err_code |= ERR_ALERT;
722 goto out;
723 }
724 if (*(args[1]) == 0) {
725 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
726 err_code |= ERR_ALERT | ERR_FATAL;
727 goto out;
728 }
729 global.maxpipes = atol(args[1]);
730 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100731 else if (strcmp(args[0], "maxzlibmem") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100732 if (alertif_too_many_args(1, file, linenum, args, &err_code))
733 goto out;
734 if (*(args[1]) == 0) {
735 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
736 err_code |= ERR_ALERT | ERR_FATAL;
737 goto out;
738 }
739 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
740 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100741 else if (strcmp(args[0], "maxcompcpuusage") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100742 if (alertif_too_many_args(1, file, linenum, args, &err_code))
743 goto out;
744 if (*(args[1]) == 0) {
745 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
746 err_code |= ERR_ALERT | ERR_FATAL;
747 goto out;
748 }
749 compress_min_idle = 100 - atoi(args[1]);
750 if (compress_min_idle > 100) {
751 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
752 err_code |= ERR_ALERT | ERR_FATAL;
753 goto out;
754 }
755 }
Willy Tarreau2df1fbf2022-04-25 18:02:03 +0200756 else if (strcmp(args[0], "fd-hard-limit") == 0) {
757 if (alertif_too_many_args(1, file, linenum, args, &err_code))
758 goto out;
759 if (global.fd_hard_limit != 0) {
760 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
761 err_code |= ERR_ALERT;
762 goto out;
763 }
764 if (*(args[1]) == 0) {
765 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
766 err_code |= ERR_ALERT | ERR_FATAL;
767 goto out;
768 }
769 global.fd_hard_limit = atol(args[1]);
770 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100771 else if (strcmp(args[0], "ulimit-n") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100772 if (alertif_too_many_args(1, file, linenum, args, &err_code))
773 goto out;
774 if (global.rlimit_nofile != 0) {
775 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
776 err_code |= ERR_ALERT;
777 goto out;
778 }
779 if (*(args[1]) == 0) {
780 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
781 err_code |= ERR_ALERT | ERR_FATAL;
782 goto out;
783 }
784 global.rlimit_nofile = atol(args[1]);
785 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100786 else if (strcmp(args[0], "chroot") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100787 if (alertif_too_many_args(1, file, linenum, args, &err_code))
788 goto out;
789 if (global.chroot != NULL) {
790 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
791 err_code |= ERR_ALERT;
792 goto out;
793 }
794 if (*(args[1]) == 0) {
795 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
796 err_code |= ERR_ALERT | ERR_FATAL;
797 goto out;
798 }
799 global.chroot = strdup(args[1]);
800 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100801 else if (strcmp(args[0], "description") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100802 int i, len=0;
803 char *d;
804
805 if (!*args[1]) {
806 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
807 file, linenum, args[0]);
808 err_code |= ERR_ALERT | ERR_FATAL;
809 goto out;
810 }
811
812 for (i = 1; *args[i]; i++)
813 len += strlen(args[i]) + 1;
814
815 if (global.desc)
816 free(global.desc);
817
818 global.desc = d = calloc(1, len);
819
820 d += snprintf(d, global.desc + len - d, "%s", args[1]);
821 for (i = 2; *args[i]; i++)
822 d += snprintf(d, global.desc + len - d, " %s", args[i]);
823 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100824 else if (strcmp(args[0], "node") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100825 int i;
826 char c;
827
828 if (alertif_too_many_args(1, file, linenum, args, &err_code))
829 goto out;
830
831 for (i=0; args[1][i]; i++) {
832 c = args[1][i];
833 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
834 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
835 break;
836 }
837
838 if (!i || args[1][i]) {
839 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
840 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
841 file, linenum, args[0]);
842 err_code |= ERR_ALERT | ERR_FATAL;
843 goto out;
844 }
845
846 if (global.node)
847 free(global.node);
848
849 global.node = strdup(args[1]);
850 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100851 else if (strcmp(args[0], "pidfile") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100852 if (alertif_too_many_args(1, file, linenum, args, &err_code))
853 goto out;
854 if (global.pidfile != NULL) {
855 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
856 err_code |= ERR_ALERT;
857 goto out;
858 }
859 if (*(args[1]) == 0) {
860 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
861 err_code |= ERR_ALERT | ERR_FATAL;
862 goto out;
863 }
864 global.pidfile = strdup(args[1]);
865 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100866 else if (strcmp(args[0], "unix-bind") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100867 int cur_arg = 1;
868 while (*(args[cur_arg])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100869 if (strcmp(args[cur_arg], "prefix") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100870 if (global.unix_bind.prefix != NULL) {
871 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
872 err_code |= ERR_ALERT;
873 cur_arg += 2;
874 continue;
875 }
876
877 if (*(args[cur_arg+1]) == 0) {
878 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
879 err_code |= ERR_ALERT | ERR_FATAL;
880 goto out;
881 }
882 global.unix_bind.prefix = strdup(args[cur_arg+1]);
883 cur_arg += 2;
884 continue;
885 }
886
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100887 if (strcmp(args[cur_arg], "mode") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100888
889 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
890 cur_arg += 2;
891 continue;
892 }
893
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100894 if (strcmp(args[cur_arg], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100895
896 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
897 cur_arg += 2;
898 continue;
899 }
900
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100901 if (strcmp(args[cur_arg], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100902
903 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
904 cur_arg += 2;
905 continue;
906 }
907
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100908 if (strcmp(args[cur_arg], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100909 struct passwd *user;
910
911 user = getpwnam(args[cur_arg + 1]);
912 if (!user) {
913 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
914 file, linenum, args[0], args[cur_arg + 1 ]);
915 err_code |= ERR_ALERT | ERR_FATAL;
916 goto out;
917 }
918
919 global.unix_bind.ux.uid = user->pw_uid;
920 cur_arg += 2;
921 continue;
922 }
923
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100924 if (strcmp(args[cur_arg], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100925 struct group *group;
926
927 group = getgrnam(args[cur_arg + 1]);
928 if (!group) {
929 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
930 file, linenum, args[0], args[cur_arg + 1 ]);
931 err_code |= ERR_ALERT | ERR_FATAL;
932 goto out;
933 }
934
935 global.unix_bind.ux.gid = group->gr_gid;
936 cur_arg += 2;
937 continue;
938 }
939
940 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
941 file, linenum, args[0]);
942 err_code |= ERR_ALERT | ERR_FATAL;
943 goto out;
944 }
945 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100946 else if (strcmp(args[0], "log") == 0) { /* "no log" or "log ..." */
Emeric Brun9533a702021-04-02 10:13:43 +0200947 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), file, linenum, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100948 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
949 err_code |= ERR_ALERT | ERR_FATAL;
950 goto out;
951 }
952 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100953 else if (strcmp(args[0], "log-send-hostname") == 0) { /* set the hostname in syslog header */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100954 char *name;
955
956 if (global.log_send_hostname != NULL) {
957 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
958 err_code |= ERR_ALERT;
959 goto out;
960 }
961
962 if (*(args[1]))
963 name = args[1];
964 else
965 name = hostname;
966
967 free(global.log_send_hostname);
968 global.log_send_hostname = strdup(name);
969 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100970 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 +0100971 if (global.server_state_base != NULL) {
972 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
973 err_code |= ERR_ALERT;
974 goto out;
975 }
976
977 if (!*(args[1])) {
978 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
979 err_code |= ERR_FATAL;
980 goto out;
981 }
982
983 global.server_state_base = strdup(args[1]);
984 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100985 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 +0100986 if (global.server_state_file != NULL) {
987 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
988 err_code |= ERR_ALERT;
989 goto out;
990 }
991
992 if (!*(args[1])) {
993 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
994 err_code |= ERR_FATAL;
995 goto out;
996 }
997
998 global.server_state_file = strdup(args[1]);
999 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001000 else if (strcmp(args[0], "log-tag") == 0) { /* tag to report to syslog */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001001 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1002 goto out;
1003 if (*(args[1]) == 0) {
1004 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
1005 err_code |= ERR_ALERT | ERR_FATAL;
1006 goto out;
1007 }
1008 chunk_destroy(&global.log_tag);
Eric Salama7cea6062020-10-02 11:58:19 +02001009 chunk_initlen(&global.log_tag, strdup(args[1]), strlen(args[1]), strlen(args[1]));
1010 if (b_orig(&global.log_tag) == NULL) {
1011 chunk_destroy(&global.log_tag);
1012 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n", file, linenum, args[0]);
1013 err_code |= ERR_ALERT | ERR_FATAL;
1014 goto out;
1015 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001016 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001017 else if (strcmp(args[0], "spread-checks") == 0) { /* random time between checks (0-50) */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001018 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1019 goto out;
1020 if (global.spread_checks != 0) {
1021 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
1022 err_code |= ERR_ALERT;
1023 goto out;
1024 }
1025 if (*(args[1]) == 0) {
1026 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1027 err_code |= ERR_ALERT | ERR_FATAL;
1028 goto out;
1029 }
1030 global.spread_checks = atol(args[1]);
1031 if (global.spread_checks < 0 || global.spread_checks > 50) {
1032 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
1033 err_code |= ERR_ALERT | ERR_FATAL;
1034 }
1035 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001036 else if (strcmp(args[0], "max-spread-checks") == 0) { /* maximum time between first and last check */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001037 const char *err;
1038 unsigned int val;
1039
1040 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1041 goto out;
1042 if (*(args[1]) == 0) {
1043 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1044 err_code |= ERR_ALERT | ERR_FATAL;
1045 goto out;
1046 }
1047
1048 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +02001049 if (err == PARSE_TIME_OVER) {
1050 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 2147483647 ms (~24.8 days).\n",
1051 file, linenum, args[1], args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001052 err_code |= ERR_ALERT | ERR_FATAL;
1053 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001054 else if (err == PARSE_TIME_UNDER) {
1055 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
1056 file, linenum, args[1], args[0]);
1057 err_code |= ERR_ALERT | ERR_FATAL;
1058 }
1059 else if (err) {
1060 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 +01001061 err_code |= ERR_ALERT | ERR_FATAL;
1062 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001063 global.max_spread_checks = val;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001064 }
1065 else if (strcmp(args[0], "cpu-map") == 0) {
1066 /* map a process list to a CPU set */
1067#ifdef USE_CPU_AFFINITY
1068 char *slash;
Willy Tarreau5b093412022-07-08 09:38:30 +02001069 unsigned long tgroup = 0, thread = 0;
1070 int g, j, n, autoinc;
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001071 struct hap_cpuset cpus, cpus_copy;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001072
1073 if (!*args[1] || !*args[2]) {
Willy Tarreau5b093412022-07-08 09:38:30 +02001074 ha_alert("parsing [%s:%d] : %s expects a thread group number "
Willy Tarreau36b9e222018-11-11 15:19:52 +01001075 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1076 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001077 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001078 err_code |= ERR_ALERT | ERR_FATAL;
1079 goto out;
1080 }
1081
1082 if ((slash = strchr(args[1], '/')) != NULL)
1083 *slash = 0;
1084
Willy Tarreau5b093412022-07-08 09:38:30 +02001085 /* note: we silently ignore thread group numbers over MAX_TGROUPS
1086 * and threads over MAX_THREADS so as not to make configurations a
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001087 * pain to maintain.
1088 */
Willy Tarreau5b093412022-07-08 09:38:30 +02001089 if (parse_process_number(args[1], &tgroup, LONGBITS, &autoinc, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001090 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1091 err_code |= ERR_ALERT | ERR_FATAL;
1092 goto out;
1093 }
1094
1095 if (slash) {
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001096 if (parse_process_number(slash+1, &thread, LONGBITS, NULL, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001097 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1098 err_code |= ERR_ALERT | ERR_FATAL;
1099 goto out;
1100 }
1101 *slash = '/';
Willy Tarreau36b9e222018-11-11 15:19:52 +01001102 }
1103
Amaury Denoyellea8082352021-04-06 16:46:15 +02001104 if (parse_cpu_set((const char **)args+2, &cpus, 0, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001105 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1106 err_code |= ERR_ALERT | ERR_FATAL;
1107 goto out;
1108 }
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001109
Willy Tarreau36b9e222018-11-11 15:19:52 +01001110 if (autoinc &&
Willy Tarreau5b093412022-07-08 09:38:30 +02001111 my_popcountl(tgroup) != ha_cpuset_count(&cpus) &&
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001112 my_popcountl(thread) != ha_cpuset_count(&cpus)) {
Willy Tarreau5b093412022-07-08 09:38:30 +02001113 ha_alert("parsing [%s:%d] : %s : TGROUP/THREAD range and CPU sets "
Willy Tarreau36b9e222018-11-11 15:19:52 +01001114 "must have the same size to be automatically bound\n",
1115 file, linenum, args[0]);
1116 err_code |= ERR_ALERT | ERR_FATAL;
1117 goto out;
1118 }
1119
Willy Tarreau7764a572019-07-16 15:10:34 +02001120 /* we now have to deal with 3 real cases :
Willy Tarreau5b093412022-07-08 09:38:30 +02001121 * cpu-map P-Q => mapping for whole tgroups, numbers P to Q
1122 * cpu-map P-Q/1 => mapping of first thread of groups P to Q
1123 * cpu-map P/T-U => mapping of threads T to U of tgroup P
Willy Tarreau7764a572019-07-16 15:10:34 +02001124 */
Willy Tarreau3cd71ac2022-08-22 10:38:00 +02001125 /* first tgroup, iterate on threads. E.g. cpu-map 1/1-4 0-3 */
1126 for (g = 0; g < MAX_TGROUPS; g++) {
1127 /* No mapping for this tgroup */
1128 if (!(tgroup & (1UL << g)))
1129 continue;
Willy Tarreau81492c92019-05-03 09:41:23 +02001130
Willy Tarreau3cd71ac2022-08-22 10:38:00 +02001131 ha_cpuset_assign(&cpus_copy, &cpus);
1132
1133 if (!thread) {
1134 /* no thread set was specified, apply
1135 * the CPU set to the whole group.
1136 */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001137 if (!autoinc)
Willy Tarreau5b093412022-07-08 09:38:30 +02001138 ha_cpuset_assign(&cpu_map[g].proc, &cpus);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001139 else {
Willy Tarreau5b093412022-07-08 09:38:30 +02001140 ha_cpuset_zero(&cpu_map[g].proc);
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001141 n = ha_cpuset_ffs(&cpus_copy) - 1;
1142 ha_cpuset_clr(&cpus_copy, n);
Willy Tarreau5b093412022-07-08 09:38:30 +02001143 ha_cpuset_set(&cpu_map[g].proc, n);
1144 }
Willy Tarreau3cd71ac2022-08-22 10:38:00 +02001145 } else {
1146 /* a thread set is specified, apply the
1147 * CPU set to these threads.
1148 */
Willy Tarreau5b093412022-07-08 09:38:30 +02001149 for (j = n = 0; j < MAX_THREADS_PER_GROUP; j++) {
1150 /* No mapping for this thread */
1151 if (!(thread & (1UL << j)))
1152 continue;
1153
1154 if (!autoinc)
1155 ha_cpuset_assign(&cpu_map[g].thread[j], &cpus);
1156 else {
1157 ha_cpuset_zero(&cpu_map[g].thread[j]);
1158 n = ha_cpuset_ffs(&cpus_copy) - 1;
1159 ha_cpuset_clr(&cpus_copy, n);
1160 ha_cpuset_set(&cpu_map[g].thread[j], n);
1161 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001162 }
1163 }
1164 }
1165#else
1166 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1167 file, linenum, args[0]);
1168 err_code |= ERR_ALERT | ERR_FATAL;
1169 goto out;
1170#endif /* ! USE_CPU_AFFINITY */
1171 }
1172 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1173 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1174 goto out;
1175
1176 if (*(args[2]) == 0) {
1177 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
1178 err_code |= ERR_ALERT | ERR_FATAL;
1179 goto out;
1180 }
1181
1182 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1183 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
1184 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
1185 err_code |= ERR_ALERT | ERR_FATAL;
1186 goto out;
1187 }
1188 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001189 else if (strcmp(args[0], "unsetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001190 int arg;
1191
1192 if (*(args[1]) == 0) {
1193 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
1194 err_code |= ERR_ALERT | ERR_FATAL;
1195 goto out;
1196 }
1197
1198 for (arg = 1; *args[arg]; arg++) {
1199 if (unsetenv(args[arg]) != 0) {
1200 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
1201 err_code |= ERR_ALERT | ERR_FATAL;
1202 goto out;
1203 }
1204 }
1205 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001206 else if (strcmp(args[0], "resetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001207 extern char **environ;
1208 char **env = environ;
1209
1210 /* args contain variable names to keep, one per argument */
1211 while (*env) {
1212 int arg;
1213
1214 /* look for current variable in among all those we want to keep */
1215 for (arg = 1; *args[arg]; arg++) {
1216 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1217 (*env)[strlen(args[arg])] == '=')
1218 break;
1219 }
1220
1221 /* delete this variable */
1222 if (!*args[arg]) {
1223 char *delim = strchr(*env, '=');
1224
1225 if (!delim || delim - *env >= trash.size) {
1226 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
1227 err_code |= ERR_ALERT | ERR_FATAL;
1228 goto out;
1229 }
1230
1231 memcpy(trash.area, *env, delim - *env);
1232 trash.area[delim - *env] = 0;
1233
1234 if (unsetenv(trash.area) != 0) {
1235 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
1236 err_code |= ERR_ALERT | ERR_FATAL;
1237 goto out;
1238 }
1239 }
1240 else
1241 env++;
1242 }
1243 }
Willy Tarreaue98d3852022-11-15 09:34:07 +01001244 else if (strcmp(args[0], "quick-exit") == 0) {
1245 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1246 goto out;
1247 global.tune.options |= GTUNE_QUICK_EXIT;
1248 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001249 else if (strcmp(args[0], "strict-limits") == 0) { /* "no strict-limits" or "strict-limits" */
William Dauchy0fec3ab2019-10-27 20:08:11 +01001250 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1251 goto out;
1252 if (kwm == KWM_NO)
1253 global.tune.options &= ~GTUNE_STRICT_LIMITS;
William Dauchy0fec3ab2019-10-27 20:08:11 +01001254 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001255 else if (strcmp(args[0], "localpeer") == 0) {
Dragan Dosen13cd54c2020-06-18 18:24:05 +02001256 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1257 goto out;
1258
1259 if (*(args[1]) == 0) {
1260 ha_alert("parsing [%s:%d] : '%s' expects a name as an argument.\n",
1261 file, linenum, args[0]);
1262 err_code |= ERR_ALERT | ERR_FATAL;
1263 goto out;
1264 }
1265
1266 if (global.localpeer_cmdline != 0) {
1267 ha_warning("parsing [%s:%d] : '%s' ignored since it is already set by using the '-L' "
1268 "command line argument.\n", file, linenum, args[0]);
1269 err_code |= ERR_WARN;
1270 goto out;
1271 }
1272
1273 if (cfg_peers) {
1274 ha_warning("parsing [%s:%d] : '%s' ignored since it is used after 'peers' section.\n",
1275 file, linenum, args[0]);
1276 err_code |= ERR_WARN;
1277 goto out;
1278 }
1279
1280 free(localpeer);
1281 if ((localpeer = strdup(args[1])) == NULL) {
1282 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n",
1283 file, linenum, args[0]);
1284 err_code |= ERR_ALERT | ERR_FATAL;
1285 goto out;
1286 }
1287 setenv("HAPROXY_LOCALPEER", localpeer, 1);
1288 }
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +01001289 else if (strcmp(args[0], "numa-cpu-mapping") == 0) {
1290 global.numa_cpu_mapping = (kwm == KWM_NO) ? 0 : 1;
1291 }
Erwan Le Goasfad9da82022-09-14 17:24:22 +02001292 else if (strcmp(args[0], "anonkey") == 0) {
1293 long long tmp = 0;
1294
1295 if (*args[1] == 0) {
1296 ha_alert("parsing [%s:%d]: a key is expected after '%s'.\n",
1297 file, linenum, args[0]);
1298 err_code |= ERR_ALERT | ERR_FATAL;
1299 goto out;
1300 }
1301
1302 if (HA_ATOMIC_LOAD(&global.anon_key) == 0) {
1303 tmp = atoll(args[1]);
1304 if (tmp < 0 || tmp > UINT_MAX) {
1305 ha_alert("parsing [%s:%d]: '%s' value must be within range %u-%u (was '%s').\n",
1306 file, linenum, args[0], 0, UINT_MAX, args[1]);
1307 err_code |= ERR_ALERT | ERR_FATAL;
1308 goto out;
1309 }
1310
1311 HA_ATOMIC_STORE(&global.anon_key, tmp);
1312 }
1313 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001314 else {
1315 struct cfg_kw_list *kwl;
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001316 const char *best;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001317 int index;
1318 int rc;
1319
1320 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1321 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1322 if (kwl->kw[index].section != CFG_GLOBAL)
1323 continue;
1324 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001325 if (check_kw_experimental(&kwl->kw[index], file, linenum, &errmsg)) {
Amaury Denoyelle86c1d0f2021-05-07 15:07:21 +02001326 ha_alert("%s\n", errmsg);
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001327 err_code |= ERR_ALERT | ERR_FATAL;
1328 goto out;
1329 }
1330
Willy Tarreau36b9e222018-11-11 15:19:52 +01001331 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
1332 if (rc < 0) {
1333 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1334 err_code |= ERR_ALERT | ERR_FATAL;
1335 }
1336 else if (rc > 0) {
1337 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1338 err_code |= ERR_WARN;
1339 goto out;
1340 }
1341 goto out;
1342 }
1343 }
1344 }
1345
Willy Tarreau101df312021-03-15 09:12:41 +01001346 best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_GLOBAL, common_kw_list);
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001347 if (best)
1348 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best);
1349 else
1350 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau36b9e222018-11-11 15:19:52 +01001351 err_code |= ERR_ALERT | ERR_FATAL;
1352 }
1353
1354 out:
1355 free(errmsg);
1356 return err_code;
1357}
1358