blob: 864e9d465fd63f3a5ef4bada90f58d3c12416a6a [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écailledf3f4572023-07-21 18:22:38 +020054 "peers", "resolvers", "cluster-secret", "no-quic", "limited-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écailledf3f4572023-07-21 18:22:38 +0200120 else if (strcmp(args[0], "limited-quic") == 0) {
121 if (alertif_too_many_args(0, file, linenum, args, &err_code))
122 goto out;
123
124 global.tune.options |= GTUNE_LIMITED_QUIC;
125 }
Frédéric Lécaille12a03172023-01-12 15:23:54 +0100126 else if (strcmp(args[0], "no-quic") == 0) {
127 if (alertif_too_many_args(0, file, linenum, args, &err_code))
128 goto out;
129
130 global.tune.options |= GTUNE_NO_QUIC;
131 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100132 else if (strcmp(args[0], "busy-polling") == 0) { /* "no busy-polling" or "busy-polling" */
Willy Tarreaubeb859a2018-11-22 18:07:59 +0100133 if (alertif_too_many_args(0, file, linenum, args, &err_code))
134 goto out;
135 if (kwm == KWM_NO)
136 global.tune.options &= ~GTUNE_BUSY_POLLING;
137 else
138 global.tune.options |= GTUNE_BUSY_POLLING;
139 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100140 else if (strcmp(args[0], "set-dumpable") == 0) { /* "no set-dumpable" or "set-dumpable" */
Willy Tarreau636848a2019-04-15 19:38:50 +0200141 if (alertif_too_many_args(0, file, linenum, args, &err_code))
142 goto out;
143 if (kwm == KWM_NO)
144 global.tune.options &= ~GTUNE_SET_DUMPABLE;
145 else
146 global.tune.options |= GTUNE_SET_DUMPABLE;
147 }
Amaury Denoyellebefeae82021-07-09 17:14:30 +0200148 else if (strcmp(args[0], "h2-workaround-bogus-websocket-clients") == 0) { /* "no h2-workaround-bogus-websocket-clients" or "h2-workaround-bogus-websocket-clients" */
149 if (alertif_too_many_args(0, file, linenum, args, &err_code))
150 goto out;
151 if (kwm == KWM_NO)
152 global.tune.options &= ~GTUNE_DISABLE_H2_WEBSOCKET;
153 else
154 global.tune.options |= GTUNE_DISABLE_H2_WEBSOCKET;
155 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100156 else if (strcmp(args[0], "insecure-fork-wanted") == 0) { /* "no insecure-fork-wanted" or "insecure-fork-wanted" */
Willy Tarreaud96f1122019-12-03 07:07:36 +0100157 if (alertif_too_many_args(0, file, linenum, args, &err_code))
158 goto out;
159 if (kwm == KWM_NO)
160 global.tune.options &= ~GTUNE_INSECURE_FORK;
161 else
162 global.tune.options |= GTUNE_INSECURE_FORK;
163 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100164 else if (strcmp(args[0], "insecure-setuid-wanted") == 0) { /* "no insecure-setuid-wanted" or "insecure-setuid-wanted" */
Willy Tarreaua45a8b52019-12-06 16:31:45 +0100165 if (alertif_too_many_args(0, file, linenum, args, &err_code))
166 goto out;
167 if (kwm == KWM_NO)
168 global.tune.options &= ~GTUNE_INSECURE_SETUID;
169 else
170 global.tune.options |= GTUNE_INSECURE_SETUID;
171 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100172 else if (strcmp(args[0], "nosplice") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100173 if (alertif_too_many_args(0, file, linenum, args, &err_code))
174 goto out;
175 global.tune.options &= ~GTUNE_USE_SPLICE;
176 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100177 else if (strcmp(args[0], "nogetaddrinfo") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100178 if (alertif_too_many_args(0, file, linenum, args, &err_code))
179 goto out;
180 global.tune.options &= ~GTUNE_USE_GAI;
181 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100182 else if (strcmp(args[0], "noreuseport") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100183 if (alertif_too_many_args(0, file, linenum, args, &err_code))
184 goto out;
Willy Tarreau785b89f2023-04-22 15:09:07 +0200185 protocol_clrf_all(PROTO_F_REUSEPORT_SUPPORTED);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100186 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100187 else if (strcmp(args[0], "quiet") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100188 if (alertif_too_many_args(0, file, linenum, args, &err_code))
189 goto out;
190 global.mode |= MODE_QUIET;
191 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100192 else if (strcmp(args[0], "zero-warning") == 0) {
Willy Tarreau3eb10b82020-04-15 16:42:39 +0200193 if (alertif_too_many_args(0, file, linenum, args, &err_code))
194 goto out;
195 global.mode |= MODE_ZERO_WARNING;
196 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100197 else if (strcmp(args[0], "tune.runqueue-depth") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100198 if (alertif_too_many_args(1, file, linenum, args, &err_code))
199 goto out;
200 if (global.tune.runqueue_depth != 0) {
201 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
202 err_code |= ERR_ALERT;
203 goto out;
204 }
205 if (*(args[1]) == 0) {
206 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
207 err_code |= ERR_ALERT | ERR_FATAL;
208 goto out;
209 }
210 global.tune.runqueue_depth = atol(args[1]);
211
212 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100213 else if (strcmp(args[0], "tune.maxpollevents") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100214 if (alertif_too_many_args(1, file, linenum, args, &err_code))
215 goto out;
216 if (global.tune.maxpollevents != 0) {
217 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
218 err_code |= ERR_ALERT;
219 goto out;
220 }
221 if (*(args[1]) == 0) {
222 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
223 err_code |= ERR_ALERT | ERR_FATAL;
224 goto out;
225 }
226 global.tune.maxpollevents = atol(args[1]);
227 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100228 else if (strcmp(args[0], "tune.maxaccept") == 0) {
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200229 long max;
230
Willy Tarreau36b9e222018-11-11 15:19:52 +0100231 if (alertif_too_many_args(1, file, linenum, args, &err_code))
232 goto out;
233 if (global.tune.maxaccept != 0) {
234 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
235 err_code |= ERR_ALERT;
236 goto out;
237 }
238 if (*(args[1]) == 0) {
239 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
240 err_code |= ERR_ALERT | ERR_FATAL;
241 goto out;
242 }
Christopher Faulet6b02ab82019-04-30 14:03:56 +0200243 max = atol(args[1]);
244 if (/*max < -1 || */max > INT_MAX) {
245 ha_alert("parsing [%s:%d] : '%s' expects -1 or an integer from 0 to INT_MAX.\n", file, linenum, args[0]);
246 err_code |= ERR_ALERT | ERR_FATAL;
247 goto out;
248 }
249 global.tune.maxaccept = max;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100250 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100251 else if (strcmp(args[0], "tune.chksize") == 0) {
Willy Tarreaueb9d90a2021-06-11 15:29:31 +0200252 ha_alert("parsing [%s:%d]: option '%s' is not supported any more (tune.bufsize is used instead).\n", file, linenum, args[0]);
253 err_code |= ERR_ALERT | ERR_FATAL;
254 goto out;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100255 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100256 else if (strcmp(args[0], "tune.recv_enough") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100257 if (alertif_too_many_args(1, file, linenum, args, &err_code))
258 goto out;
259 if (*(args[1]) == 0) {
260 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
261 err_code |= ERR_ALERT | ERR_FATAL;
262 goto out;
263 }
264 global.tune.recv_enough = atol(args[1]);
265 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100266 else if (strcmp(args[0], "tune.buffers.limit") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100267 if (alertif_too_many_args(1, file, linenum, args, &err_code))
268 goto out;
269 if (*(args[1]) == 0) {
270 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
271 err_code |= ERR_ALERT | ERR_FATAL;
272 goto out;
273 }
274 global.tune.buf_limit = atol(args[1]);
275 if (global.tune.buf_limit) {
276 if (global.tune.buf_limit < 3)
277 global.tune.buf_limit = 3;
278 if (global.tune.buf_limit <= global.tune.reserved_bufs)
279 global.tune.buf_limit = global.tune.reserved_bufs + 1;
280 }
281 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100282 else if (strcmp(args[0], "tune.buffers.reserve") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100283 if (alertif_too_many_args(1, file, linenum, args, &err_code))
284 goto out;
285 if (*(args[1]) == 0) {
286 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
287 err_code |= ERR_ALERT | ERR_FATAL;
288 goto out;
289 }
290 global.tune.reserved_bufs = atol(args[1]);
291 if (global.tune.reserved_bufs < 2)
292 global.tune.reserved_bufs = 2;
293 if (global.tune.buf_limit && global.tune.buf_limit <= global.tune.reserved_bufs)
294 global.tune.buf_limit = global.tune.reserved_bufs + 1;
295 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100296 else if (strcmp(args[0], "tune.bufsize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100297 if (alertif_too_many_args(1, file, linenum, args, &err_code))
298 goto out;
299 if (*(args[1]) == 0) {
300 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
301 err_code |= ERR_ALERT | ERR_FATAL;
302 goto out;
303 }
304 global.tune.bufsize = atol(args[1]);
Willy Tarreauc77d3642018-12-12 06:19:42 +0100305 /* round it up to support a two-pointer alignment at the end */
306 global.tune.bufsize = (global.tune.bufsize + 2 * sizeof(void *) - 1) & -(2 * sizeof(void *));
Willy Tarreau36b9e222018-11-11 15:19:52 +0100307 if (global.tune.bufsize <= 0) {
308 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
309 err_code |= ERR_ALERT | ERR_FATAL;
310 goto out;
311 }
312 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100313 else if (strcmp(args[0], "tune.maxrewrite") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100314 if (alertif_too_many_args(1, file, linenum, args, &err_code))
315 goto out;
316 if (*(args[1]) == 0) {
317 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
318 err_code |= ERR_ALERT | ERR_FATAL;
319 goto out;
320 }
321 global.tune.maxrewrite = atol(args[1]);
322 if (global.tune.maxrewrite < 0) {
323 ha_alert("parsing [%s:%d] : '%s' expects a positive integer argument.\n", file, linenum, args[0]);
324 err_code |= ERR_ALERT | ERR_FATAL;
325 goto out;
326 }
327 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100328 else if (strcmp(args[0], "tune.idletimer") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100329 unsigned int idle;
330 const char *res;
331
332 if (alertif_too_many_args(1, file, linenum, args, &err_code))
333 goto out;
334 if (*(args[1]) == 0) {
335 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
336 err_code |= ERR_ALERT | ERR_FATAL;
337 goto out;
338 }
339
340 res = parse_time_err(args[1], &idle, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +0200341 if (res == PARSE_TIME_OVER) {
342 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 65535 ms.\n",
343 file, linenum, args[1], args[0]);
344 err_code |= ERR_ALERT | ERR_FATAL;
345 goto out;
346 }
347 else if (res == PARSE_TIME_UNDER) {
348 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
349 file, linenum, args[1], args[0]);
350 err_code |= ERR_ALERT | ERR_FATAL;
351 goto out;
352 }
353 else if (res) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100354 ha_alert("parsing [%s:%d]: unexpected character '%c' in argument to <%s>.\n",
Willy Tarreau9faebe32019-06-07 19:00:37 +0200355 file, linenum, *res, args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +0100356 err_code |= ERR_ALERT | ERR_FATAL;
357 goto out;
358 }
359
360 if (idle > 65535) {
361 ha_alert("parsing [%s:%d] : '%s' expects a timer value between 0 and 65535 ms.\n", file, linenum, args[0]);
362 err_code |= ERR_ALERT | ERR_FATAL;
363 goto out;
364 }
365 global.tune.idle_timer = idle;
366 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100367 else if (strcmp(args[0], "tune.rcvbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100368 if (alertif_too_many_args(1, file, linenum, args, &err_code))
369 goto out;
370 if (global.tune.client_rcvbuf != 0) {
371 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
372 err_code |= ERR_ALERT;
373 goto out;
374 }
375 if (*(args[1]) == 0) {
376 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
377 err_code |= ERR_ALERT | ERR_FATAL;
378 goto out;
379 }
380 global.tune.client_rcvbuf = atol(args[1]);
381 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100382 else if (strcmp(args[0], "tune.rcvbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100383 if (alertif_too_many_args(1, file, linenum, args, &err_code))
384 goto out;
385 if (global.tune.server_rcvbuf != 0) {
386 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
387 err_code |= ERR_ALERT;
388 goto out;
389 }
390 if (*(args[1]) == 0) {
391 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
392 err_code |= ERR_ALERT | ERR_FATAL;
393 goto out;
394 }
395 global.tune.server_rcvbuf = atol(args[1]);
396 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100397 else if (strcmp(args[0], "tune.sndbuf.client") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100398 if (alertif_too_many_args(1, file, linenum, args, &err_code))
399 goto out;
400 if (global.tune.client_sndbuf != 0) {
401 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
402 err_code |= ERR_ALERT;
403 goto out;
404 }
405 if (*(args[1]) == 0) {
406 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
407 err_code |= ERR_ALERT | ERR_FATAL;
408 goto out;
409 }
410 global.tune.client_sndbuf = atol(args[1]);
411 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100412 else if (strcmp(args[0], "tune.sndbuf.server") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100413 if (alertif_too_many_args(1, file, linenum, args, &err_code))
414 goto out;
415 if (global.tune.server_sndbuf != 0) {
416 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
417 err_code |= ERR_ALERT;
418 goto out;
419 }
420 if (*(args[1]) == 0) {
421 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
422 err_code |= ERR_ALERT | ERR_FATAL;
423 goto out;
424 }
425 global.tune.server_sndbuf = atol(args[1]);
426 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100427 else if (strcmp(args[0], "tune.pipesize") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100428 if (alertif_too_many_args(1, file, linenum, args, &err_code))
429 goto out;
430 if (*(args[1]) == 0) {
431 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
432 err_code |= ERR_ALERT | ERR_FATAL;
433 goto out;
434 }
435 global.tune.pipesize = atol(args[1]);
436 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100437 else if (strcmp(args[0], "tune.http.cookielen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100438 if (alertif_too_many_args(1, file, linenum, args, &err_code))
439 goto out;
440 if (*(args[1]) == 0) {
441 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
442 err_code |= ERR_ALERT | ERR_FATAL;
443 goto out;
444 }
445 global.tune.cookie_len = atol(args[1]) + 1;
446 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100447 else if (strcmp(args[0], "tune.http.logurilen") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100448 if (alertif_too_many_args(1, file, linenum, args, &err_code))
449 goto out;
450 if (*(args[1]) == 0) {
451 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
452 err_code |= ERR_ALERT | ERR_FATAL;
453 goto out;
454 }
455 global.tune.requri_len = atol(args[1]) + 1;
456 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100457 else if (strcmp(args[0], "tune.http.maxhdr") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100458 if (alertif_too_many_args(1, file, linenum, args, &err_code))
459 goto out;
460 if (*(args[1]) == 0) {
461 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
462 err_code |= ERR_ALERT | ERR_FATAL;
463 goto out;
464 }
465 global.tune.max_http_hdr = atoi(args[1]);
466 if (global.tune.max_http_hdr < 1 || global.tune.max_http_hdr > 32767) {
467 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 32767\n",
468 file, linenum, args[0]);
469 err_code |= ERR_ALERT | ERR_FATAL;
470 goto out;
471 }
472 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100473 else if (strcmp(args[0], "tune.comp.maxlevel") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100474 if (alertif_too_many_args(1, file, linenum, args, &err_code))
475 goto out;
476 if (*args[1]) {
477 global.tune.comp_maxlevel = atoi(args[1]);
478 if (global.tune.comp_maxlevel < 1 || global.tune.comp_maxlevel > 9) {
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 } else {
485 ha_alert("parsing [%s:%d] : '%s' expects a numeric value between 1 and 9\n",
486 file, linenum, args[0]);
487 err_code |= ERR_ALERT | ERR_FATAL;
488 goto out;
489 }
490 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100491 else if (strcmp(args[0], "tune.pattern.cache-size") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100492 if (*args[1]) {
493 global.tune.pattern_cache = atoi(args[1]);
494 if (global.tune.pattern_cache < 0) {
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 } else {
501 ha_alert("parsing [%s:%d] : '%s' expects a positive numeric value\n",
502 file, linenum, args[0]);
503 err_code |= ERR_ALERT | ERR_FATAL;
504 goto out;
505 }
506 }
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100507 else if (strcmp(args[0], "tune.disable-fast-forward") == 0) {
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100508 if (!experimental_directives_allowed) {
509 ha_alert("parsing [%s:%d] : '%s' directive is experimental, must be allowed via a global 'expose-experimental-directives'",
510 file, linenum, args[0]);
511 err_code |= ERR_ALERT | ERR_FATAL;
512 goto out;
513 }
514 mark_tainted(TAINTED_CONFIG_EXP_KW_DECLARED);
515
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100516 if (alertif_too_many_args(0, file, linenum, args, &err_code))
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100517 goto out;
Christopher Faulet2f7c82b2023-02-20 14:06:52 +0100518 global.tune.options &= GTUNE_USE_FAST_FWD;
Christopher Fauletd4eaa8a2023-02-14 15:37:14 +0100519 }
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200520 else if (strcmp(args[0], "cluster-secret") == 0) {
Frédéric Lécaille0499db42023-09-07 18:43:52 +0200521 blk_SHA_CTX sha1_ctx;
522 unsigned char sha1_out[20];
523
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200524 if (alertif_too_many_args(1, file, linenum, args, &err_code))
525 goto out;
526 if (*args[1] == 0) {
527 ha_alert("parsing [%s:%d] : expects an ASCII string argument.\n", file, linenum);
528 err_code |= ERR_ALERT | ERR_FATAL;
529 goto out;
530 }
Frédéric Lécaille0499db42023-09-07 18:43:52 +0200531 if (cluster_secret_isset) {
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200532 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
533 err_code |= ERR_ALERT;
534 goto out;
535 }
Frédéric Lécaille0499db42023-09-07 18:43:52 +0200536
537 blk_SHA1_Init(&sha1_ctx);
538 blk_SHA1_Update(&sha1_ctx, args[1], strlen(args[1]));
539 blk_SHA1_Final(sha1_out, &sha1_ctx);
540 BUG_ON(sizeof sha1_out < sizeof global.cluster_secret);
541 memcpy(global.cluster_secret, sha1_out, sizeof global.cluster_secret);
542 cluster_secret_isset = 1;
Frédéric Lécaille372508c2022-05-06 08:53:16 +0200543 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100544 else if (strcmp(args[0], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100545 if (alertif_too_many_args(1, file, linenum, args, &err_code))
546 goto out;
547 if (global.uid != 0) {
548 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
549 err_code |= ERR_ALERT;
550 goto out;
551 }
552 if (*(args[1]) == 0) {
553 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
554 err_code |= ERR_ALERT | ERR_FATAL;
555 goto out;
556 }
557 if (strl2irc(args[1], strlen(args[1]), &global.uid) != 0) {
558 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]);
559 err_code |= ERR_WARN;
560 goto out;
561 }
562
563 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100564 else if (strcmp(args[0], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100565 if (alertif_too_many_args(1, file, linenum, args, &err_code))
566 goto out;
567 if (global.gid != 0) {
568 ha_alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
569 err_code |= ERR_ALERT;
570 goto out;
571 }
572 if (*(args[1]) == 0) {
573 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
574 err_code |= ERR_ALERT | ERR_FATAL;
575 goto out;
576 }
577 if (strl2irc(args[1], strlen(args[1]), &global.gid) != 0) {
578 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]);
579 err_code |= ERR_WARN;
580 goto out;
581 }
582 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100583 else if (strcmp(args[0], "external-check") == 0) {
Willy Tarreau39dcd1f2023-11-23 16:48:48 +0100584 if (alertif_too_many_args(1, file, linenum, args, &err_code))
Willy Tarreau36b9e222018-11-11 15:19:52 +0100585 goto out;
586 global.external_check = 1;
Willy Tarreau39dcd1f2023-11-23 16:48:48 +0100587 if (strcmp(args[1], "preserve-env") == 0) {
588 global.external_check = 2;
Aurelien DARRAGONd3981352023-12-07 09:58:27 +0100589 } else if (*args[1]) {
Willy Tarreau39dcd1f2023-11-23 16:48:48 +0100590 ha_alert("parsing [%s:%d] : '%s' only supports 'preserve-env' as an argument, found '%s'.\n", file, linenum, args[0], args[1]);
591 err_code |= ERR_ALERT | ERR_FATAL;
592 goto out;
593 }
Willy Tarreau36b9e222018-11-11 15:19:52 +0100594 }
595 /* user/group name handling */
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100596 else if (strcmp(args[0], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100597 struct passwd *ha_user;
598 if (alertif_too_many_args(1, file, linenum, args, &err_code))
599 goto out;
600 if (global.uid != 0) {
601 ha_alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
602 err_code |= ERR_ALERT;
603 goto out;
604 }
605 errno = 0;
606 ha_user = getpwnam(args[1]);
607 if (ha_user != NULL) {
608 global.uid = (int)ha_user->pw_uid;
609 }
610 else {
611 ha_alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
612 err_code |= ERR_ALERT | ERR_FATAL;
613 }
614 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100615 else if (strcmp(args[0], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100616 struct group *ha_group;
617 if (alertif_too_many_args(1, file, linenum, args, &err_code))
618 goto out;
619 if (global.gid != 0) {
620 ha_alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
621 err_code |= ERR_ALERT;
622 goto out;
623 }
624 errno = 0;
625 ha_group = getgrnam(args[1]);
626 if (ha_group != NULL) {
627 global.gid = (int)ha_group->gr_gid;
628 }
629 else {
630 ha_alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
631 err_code |= ERR_ALERT | ERR_FATAL;
632 }
633 }
634 /* end of user/group name handling*/
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100635 else if (strcmp(args[0], "nbproc") == 0) {
Willy Tarreaub63dbb72021-06-11 16:50:29 +0200636 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);
637 err_code |= ERR_ALERT | ERR_FATAL;
638 goto out;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100639 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100640 else if (strcmp(args[0], "maxconn") == 0) {
Thierry Fournier3d1c3342022-10-01 10:06:59 +0200641 char *stop;
642
Willy Tarreau36b9e222018-11-11 15:19:52 +0100643 if (alertif_too_many_args(1, file, linenum, args, &err_code))
644 goto out;
645 if (global.maxconn != 0) {
646 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
647 err_code |= ERR_ALERT;
648 goto out;
649 }
650 if (*(args[1]) == 0) {
651 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
652 err_code |= ERR_ALERT | ERR_FATAL;
653 goto out;
654 }
Thierry Fournier3d1c3342022-10-01 10:06:59 +0200655 global.maxconn = strtol(args[1], &stop, 10);
656 if (*stop != '\0') {
657 ha_alert("parsing [%s:%d] : cannot parse '%s' value '%s', an integer is expected.\n", file, linenum, args[0], args[1]);
658 err_code |= ERR_ALERT | ERR_FATAL;
659 goto out;
660 }
Willy Tarreau36b9e222018-11-11 15:19:52 +0100661#ifdef SYSTEM_MAXCONN
Willy Tarreauca783d42019-03-13 10:03:07 +0100662 if (global.maxconn > SYSTEM_MAXCONN && cfg_maxconn <= SYSTEM_MAXCONN) {
663 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);
664 global.maxconn = SYSTEM_MAXCONN;
Willy Tarreau36b9e222018-11-11 15:19:52 +0100665 err_code |= ERR_ALERT;
666 }
667#endif /* SYSTEM_MAXCONN */
668 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100669 else if (strcmp(args[0], "ssl-server-verify") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100670 if (alertif_too_many_args(1, file, linenum, args, &err_code))
671 goto out;
672 if (*(args[1]) == 0) {
673 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
674 err_code |= ERR_ALERT | ERR_FATAL;
675 goto out;
676 }
677 if (strcmp(args[1],"none") == 0)
678 global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
679 else if (strcmp(args[1],"required") == 0)
680 global.ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED;
681 else {
682 ha_alert("parsing [%s:%d] : '%s' expects 'none' or 'required' as argument.\n", file, linenum, args[0]);
683 err_code |= ERR_ALERT | ERR_FATAL;
684 goto out;
685 }
686 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100687 else if (strcmp(args[0], "maxconnrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100688 if (alertif_too_many_args(1, file, linenum, args, &err_code))
689 goto out;
690 if (global.cps_lim != 0) {
691 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
692 err_code |= ERR_ALERT;
693 goto out;
694 }
695 if (*(args[1]) == 0) {
696 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
697 err_code |= ERR_ALERT | ERR_FATAL;
698 goto out;
699 }
700 global.cps_lim = atol(args[1]);
701 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100702 else if (strcmp(args[0], "maxsessrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100703 if (alertif_too_many_args(1, file, linenum, args, &err_code))
704 goto out;
705 if (global.sps_lim != 0) {
706 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
707 err_code |= ERR_ALERT;
708 goto out;
709 }
710 if (*(args[1]) == 0) {
711 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
712 err_code |= ERR_ALERT | ERR_FATAL;
713 goto out;
714 }
715 global.sps_lim = atol(args[1]);
716 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100717 else if (strcmp(args[0], "maxsslrate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100718 if (alertif_too_many_args(1, file, linenum, args, &err_code))
719 goto out;
720 if (global.ssl_lim != 0) {
721 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
722 err_code |= ERR_ALERT;
723 goto out;
724 }
725 if (*(args[1]) == 0) {
726 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
727 err_code |= ERR_ALERT | ERR_FATAL;
728 goto out;
729 }
730 global.ssl_lim = atol(args[1]);
731 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100732 else if (strcmp(args[0], "maxcomprate") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100733 if (alertif_too_many_args(1, file, linenum, args, &err_code))
734 goto out;
735 if (*(args[1]) == 0) {
736 ha_alert("parsing [%s:%d] : '%s' expects an integer argument in kb/s.\n", file, linenum, args[0]);
737 err_code |= ERR_ALERT | ERR_FATAL;
738 goto out;
739 }
740 global.comp_rate_lim = atoi(args[1]) * 1024;
741 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100742 else if (strcmp(args[0], "maxpipes") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100743 if (alertif_too_many_args(1, file, linenum, args, &err_code))
744 goto out;
745 if (global.maxpipes != 0) {
746 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
747 err_code |= ERR_ALERT;
748 goto out;
749 }
750 if (*(args[1]) == 0) {
751 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
752 err_code |= ERR_ALERT | ERR_FATAL;
753 goto out;
754 }
755 global.maxpipes = atol(args[1]);
756 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100757 else if (strcmp(args[0], "maxzlibmem") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100758 if (alertif_too_many_args(1, file, linenum, args, &err_code))
759 goto out;
760 if (*(args[1]) == 0) {
761 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
762 err_code |= ERR_ALERT | ERR_FATAL;
763 goto out;
764 }
765 global.maxzlibmem = atol(args[1]) * 1024L * 1024L;
766 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100767 else if (strcmp(args[0], "maxcompcpuusage") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100768 if (alertif_too_many_args(1, file, linenum, args, &err_code))
769 goto out;
770 if (*(args[1]) == 0) {
771 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
772 err_code |= ERR_ALERT | ERR_FATAL;
773 goto out;
774 }
775 compress_min_idle = 100 - atoi(args[1]);
776 if (compress_min_idle > 100) {
777 ha_alert("parsing [%s:%d] : '%s' expects an integer argument between 0 and 100.\n", file, linenum, args[0]);
778 err_code |= ERR_ALERT | ERR_FATAL;
779 goto out;
780 }
781 }
Willy Tarreau2df1fbf2022-04-25 18:02:03 +0200782 else if (strcmp(args[0], "fd-hard-limit") == 0) {
783 if (alertif_too_many_args(1, file, linenum, args, &err_code))
784 goto out;
785 if (global.fd_hard_limit != 0) {
786 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
787 err_code |= ERR_ALERT;
788 goto out;
789 }
790 if (*(args[1]) == 0) {
791 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
792 err_code |= ERR_ALERT | ERR_FATAL;
793 goto out;
794 }
795 global.fd_hard_limit = atol(args[1]);
796 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100797 else if (strcmp(args[0], "ulimit-n") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100798 if (alertif_too_many_args(1, file, linenum, args, &err_code))
799 goto out;
800 if (global.rlimit_nofile != 0) {
801 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
802 err_code |= ERR_ALERT;
803 goto out;
804 }
805 if (*(args[1]) == 0) {
806 ha_alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
807 err_code |= ERR_ALERT | ERR_FATAL;
808 goto out;
809 }
810 global.rlimit_nofile = atol(args[1]);
811 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100812 else if (strcmp(args[0], "chroot") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100813 if (alertif_too_many_args(1, file, linenum, args, &err_code))
814 goto out;
815 if (global.chroot != NULL) {
816 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
817 err_code |= ERR_ALERT;
818 goto out;
819 }
820 if (*(args[1]) == 0) {
821 ha_alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
822 err_code |= ERR_ALERT | ERR_FATAL;
823 goto out;
824 }
825 global.chroot = strdup(args[1]);
826 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100827 else if (strcmp(args[0], "description") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100828 int i, len=0;
829 char *d;
830
831 if (!*args[1]) {
832 ha_alert("parsing [%s:%d]: '%s' expects a string argument.\n",
833 file, linenum, args[0]);
834 err_code |= ERR_ALERT | ERR_FATAL;
835 goto out;
836 }
837
838 for (i = 1; *args[i]; i++)
839 len += strlen(args[i]) + 1;
840
841 if (global.desc)
842 free(global.desc);
843
844 global.desc = d = calloc(1, len);
845
846 d += snprintf(d, global.desc + len - d, "%s", args[1]);
847 for (i = 2; *args[i]; i++)
848 d += snprintf(d, global.desc + len - d, " %s", args[i]);
849 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100850 else if (strcmp(args[0], "node") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100851 int i;
852 char c;
853
854 if (alertif_too_many_args(1, file, linenum, args, &err_code))
855 goto out;
856
857 for (i=0; args[1][i]; i++) {
858 c = args[1][i];
859 if (!isupper((unsigned char)c) && !islower((unsigned char)c) &&
860 !isdigit((unsigned char)c) && c != '_' && c != '-' && c != '.')
861 break;
862 }
863
864 if (!i || args[1][i]) {
865 ha_alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
866 " with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
867 file, linenum, args[0]);
868 err_code |= ERR_ALERT | ERR_FATAL;
869 goto out;
870 }
871
872 if (global.node)
873 free(global.node);
874
875 global.node = strdup(args[1]);
876 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100877 else if (strcmp(args[0], "pidfile") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100878 if (alertif_too_many_args(1, file, linenum, args, &err_code))
879 goto out;
880 if (global.pidfile != NULL) {
881 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
882 err_code |= ERR_ALERT;
883 goto out;
884 }
885 if (*(args[1]) == 0) {
886 ha_alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
887 err_code |= ERR_ALERT | ERR_FATAL;
888 goto out;
889 }
890 global.pidfile = strdup(args[1]);
891 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100892 else if (strcmp(args[0], "unix-bind") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100893 int cur_arg = 1;
894 while (*(args[cur_arg])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100895 if (strcmp(args[cur_arg], "prefix") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100896 if (global.unix_bind.prefix != NULL) {
897 ha_alert("parsing [%s:%d] : unix-bind '%s' already specified. Continuing.\n", file, linenum, args[cur_arg]);
898 err_code |= ERR_ALERT;
899 cur_arg += 2;
900 continue;
901 }
902
903 if (*(args[cur_arg+1]) == 0) {
904 ha_alert("parsing [%s:%d] : unix_bind '%s' expects a path as an argument.\n", file, linenum, args[cur_arg]);
905 err_code |= ERR_ALERT | ERR_FATAL;
906 goto out;
907 }
908 global.unix_bind.prefix = strdup(args[cur_arg+1]);
909 cur_arg += 2;
910 continue;
911 }
912
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100913 if (strcmp(args[cur_arg], "mode") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100914
915 global.unix_bind.ux.mode = strtol(args[cur_arg + 1], NULL, 8);
916 cur_arg += 2;
917 continue;
918 }
919
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100920 if (strcmp(args[cur_arg], "uid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100921
922 global.unix_bind.ux.uid = atol(args[cur_arg + 1 ]);
923 cur_arg += 2;
924 continue;
925 }
926
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100927 if (strcmp(args[cur_arg], "gid") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100928
929 global.unix_bind.ux.gid = atol(args[cur_arg + 1 ]);
930 cur_arg += 2;
931 continue;
932 }
933
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100934 if (strcmp(args[cur_arg], "user") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100935 struct passwd *user;
936
937 user = getpwnam(args[cur_arg + 1]);
938 if (!user) {
939 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown user.\n",
940 file, linenum, args[0], args[cur_arg + 1 ]);
941 err_code |= ERR_ALERT | ERR_FATAL;
942 goto out;
943 }
944
945 global.unix_bind.ux.uid = user->pw_uid;
946 cur_arg += 2;
947 continue;
948 }
949
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100950 if (strcmp(args[cur_arg], "group") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100951 struct group *group;
952
953 group = getgrnam(args[cur_arg + 1]);
954 if (!group) {
955 ha_alert("parsing [%s:%d] : '%s' : '%s' unknown group.\n",
956 file, linenum, args[0], args[cur_arg + 1 ]);
957 err_code |= ERR_ALERT | ERR_FATAL;
958 goto out;
959 }
960
961 global.unix_bind.ux.gid = group->gr_gid;
962 cur_arg += 2;
963 continue;
964 }
965
966 ha_alert("parsing [%s:%d] : '%s' only supports the 'prefix', 'mode', 'uid', 'gid', 'user' and 'group' options.\n",
967 file, linenum, args[0]);
968 err_code |= ERR_ALERT | ERR_FATAL;
969 goto out;
970 }
971 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100972 else if (strcmp(args[0], "log") == 0) { /* "no log" or "log ..." */
Emeric Brun9533a702021-04-02 10:13:43 +0200973 if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), file, linenum, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +0100974 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
975 err_code |= ERR_ALERT | ERR_FATAL;
976 goto out;
977 }
978 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100979 else if (strcmp(args[0], "log-send-hostname") == 0) { /* set the hostname in syslog header */
Willy Tarreau36b9e222018-11-11 15:19:52 +0100980 char *name;
981
982 if (global.log_send_hostname != NULL) {
983 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
984 err_code |= ERR_ALERT;
985 goto out;
986 }
987
988 if (*(args[1]))
989 name = args[1];
990 else
991 name = hostname;
992
993 free(global.log_send_hostname);
994 global.log_send_hostname = strdup(name);
995 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100996 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 +0100997 if (global.server_state_base != NULL) {
998 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
999 err_code |= ERR_ALERT;
1000 goto out;
1001 }
1002
1003 if (!*(args[1])) {
1004 ha_alert("parsing [%s:%d] : '%s' expects one argument: a directory path.\n", file, linenum, args[0]);
1005 err_code |= ERR_FATAL;
1006 goto out;
1007 }
1008
1009 global.server_state_base = strdup(args[1]);
1010 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001011 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 +01001012 if (global.server_state_file != NULL) {
1013 ha_alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
1014 err_code |= ERR_ALERT;
1015 goto out;
1016 }
1017
1018 if (!*(args[1])) {
1019 ha_alert("parsing [%s:%d] : '%s' expect one argument: a file path.\n", file, linenum, args[0]);
1020 err_code |= ERR_FATAL;
1021 goto out;
1022 }
1023
1024 global.server_state_file = strdup(args[1]);
1025 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001026 else if (strcmp(args[0], "log-tag") == 0) { /* tag to report to syslog */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001027 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1028 goto out;
1029 if (*(args[1]) == 0) {
1030 ha_alert("parsing [%s:%d] : '%s' expects a tag for use in syslog.\n", file, linenum, args[0]);
1031 err_code |= ERR_ALERT | ERR_FATAL;
1032 goto out;
1033 }
1034 chunk_destroy(&global.log_tag);
Eric Salama7cea6062020-10-02 11:58:19 +02001035 chunk_initlen(&global.log_tag, strdup(args[1]), strlen(args[1]), strlen(args[1]));
1036 if (b_orig(&global.log_tag) == NULL) {
1037 chunk_destroy(&global.log_tag);
1038 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n", file, linenum, args[0]);
1039 err_code |= ERR_ALERT | ERR_FATAL;
1040 goto out;
1041 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001042 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001043 else if (strcmp(args[0], "spread-checks") == 0) { /* random time between checks (0-50) */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001044 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1045 goto out;
1046 if (global.spread_checks != 0) {
1047 ha_alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
1048 err_code |= ERR_ALERT;
1049 goto out;
1050 }
1051 if (*(args[1]) == 0) {
1052 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1053 err_code |= ERR_ALERT | ERR_FATAL;
1054 goto out;
1055 }
1056 global.spread_checks = atol(args[1]);
1057 if (global.spread_checks < 0 || global.spread_checks > 50) {
1058 ha_alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
1059 err_code |= ERR_ALERT | ERR_FATAL;
1060 }
1061 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001062 else if (strcmp(args[0], "max-spread-checks") == 0) { /* maximum time between first and last check */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001063 const char *err;
1064 unsigned int val;
1065
1066 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1067 goto out;
1068 if (*(args[1]) == 0) {
1069 ha_alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
1070 err_code |= ERR_ALERT | ERR_FATAL;
1071 goto out;
1072 }
1073
1074 err = parse_time_err(args[1], &val, TIME_UNIT_MS);
Willy Tarreau9faebe32019-06-07 19:00:37 +02001075 if (err == PARSE_TIME_OVER) {
1076 ha_alert("parsing [%s:%d]: timer overflow in argument <%s> to <%s>, maximum value is 2147483647 ms (~24.8 days).\n",
1077 file, linenum, args[1], args[0]);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001078 err_code |= ERR_ALERT | ERR_FATAL;
1079 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001080 else if (err == PARSE_TIME_UNDER) {
1081 ha_alert("parsing [%s:%d]: timer underflow in argument <%s> to <%s>, minimum non-null value is 1 ms.\n",
1082 file, linenum, args[1], args[0]);
1083 err_code |= ERR_ALERT | ERR_FATAL;
1084 }
1085 else if (err) {
1086 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 +01001087 err_code |= ERR_ALERT | ERR_FATAL;
1088 }
Willy Tarreau9faebe32019-06-07 19:00:37 +02001089 global.max_spread_checks = val;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001090 }
1091 else if (strcmp(args[0], "cpu-map") == 0) {
1092 /* map a process list to a CPU set */
1093#ifdef USE_CPU_AFFINITY
1094 char *slash;
Willy Tarreau5b093412022-07-08 09:38:30 +02001095 unsigned long tgroup = 0, thread = 0;
1096 int g, j, n, autoinc;
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001097 struct hap_cpuset cpus, cpus_copy;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001098
1099 if (!*args[1] || !*args[2]) {
Willy Tarreau5b093412022-07-08 09:38:30 +02001100 ha_alert("parsing [%s:%d] : %s expects a thread group number "
Willy Tarreau36b9e222018-11-11 15:19:52 +01001101 " ('all', 'odd', 'even', a number from 1 to %d or a range), "
1102 " followed by a list of CPU ranges with numbers from 0 to %d.\n",
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001103 file, linenum, args[0], LONGBITS, LONGBITS - 1);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001104 err_code |= ERR_ALERT | ERR_FATAL;
1105 goto out;
1106 }
1107
1108 if ((slash = strchr(args[1], '/')) != NULL)
1109 *slash = 0;
1110
Willy Tarreau5b093412022-07-08 09:38:30 +02001111 /* note: we silently ignore thread group numbers over MAX_TGROUPS
1112 * and threads over MAX_THREADS so as not to make configurations a
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001113 * pain to maintain.
1114 */
Willy Tarreau5b093412022-07-08 09:38:30 +02001115 if (parse_process_number(args[1], &tgroup, LONGBITS, &autoinc, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001116 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1117 err_code |= ERR_ALERT | ERR_FATAL;
1118 goto out;
1119 }
1120
1121 if (slash) {
Willy Tarreau5799e9c2019-03-05 18:14:03 +01001122 if (parse_process_number(slash+1, &thread, LONGBITS, NULL, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001123 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1124 err_code |= ERR_ALERT | ERR_FATAL;
1125 goto out;
1126 }
1127 *slash = '/';
Willy Tarreaueded6c12023-07-19 18:17:39 +02001128 } else
1129 thread = ~0UL; /* missing '/' = 'all' */
1130
1131 /* from now on, thread cannot be NULL anymore */
Willy Tarreau36b9e222018-11-11 15:19:52 +01001132
Willy Tarreau615c3012023-05-05 16:10:05 +02001133 if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001134 ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
1135 err_code |= ERR_ALERT | ERR_FATAL;
1136 goto out;
1137 }
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001138
Willy Tarreau36b9e222018-11-11 15:19:52 +01001139 if (autoinc &&
Willy Tarreau5b093412022-07-08 09:38:30 +02001140 my_popcountl(tgroup) != ha_cpuset_count(&cpus) &&
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001141 my_popcountl(thread) != ha_cpuset_count(&cpus)) {
Willy Tarreau5b093412022-07-08 09:38:30 +02001142 ha_alert("parsing [%s:%d] : %s : TGROUP/THREAD range and CPU sets "
Willy Tarreau36b9e222018-11-11 15:19:52 +01001143 "must have the same size to be automatically bound\n",
1144 file, linenum, args[0]);
1145 err_code |= ERR_ALERT | ERR_FATAL;
1146 goto out;
1147 }
1148
Willy Tarreau7764a572019-07-16 15:10:34 +02001149 /* we now have to deal with 3 real cases :
Willy Tarreau5b093412022-07-08 09:38:30 +02001150 * cpu-map P-Q => mapping for whole tgroups, numbers P to Q
1151 * cpu-map P-Q/1 => mapping of first thread of groups P to Q
1152 * cpu-map P/T-U => mapping of threads T to U of tgroup P
Willy Tarreau7764a572019-07-16 15:10:34 +02001153 */
Willy Tarreau3cd71ac2022-08-22 10:38:00 +02001154 /* first tgroup, iterate on threads. E.g. cpu-map 1/1-4 0-3 */
1155 for (g = 0; g < MAX_TGROUPS; g++) {
1156 /* No mapping for this tgroup */
1157 if (!(tgroup & (1UL << g)))
1158 continue;
Willy Tarreau81492c92019-05-03 09:41:23 +02001159
Willy Tarreau3cd71ac2022-08-22 10:38:00 +02001160 ha_cpuset_assign(&cpus_copy, &cpus);
1161
Willy Tarreaueded6c12023-07-19 18:17:39 +02001162 /* a thread set is specified, apply the
1163 * CPU set to these threads.
1164 */
1165 for (j = n = 0; j < MAX_THREADS_PER_GROUP; j++) {
1166 /* No mapping for this thread */
1167 if (!(thread & (1UL << j)))
1168 continue;
1169
Willy Tarreau36b9e222018-11-11 15:19:52 +01001170 if (!autoinc)
Willy Tarreaueded6c12023-07-19 18:17:39 +02001171 ha_cpuset_assign(&cpu_map[g].thread[j], &cpus);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001172 else {
Willy Tarreaueded6c12023-07-19 18:17:39 +02001173 ha_cpuset_zero(&cpu_map[g].thread[j]);
Amaury Denoyelle982fb532021-04-21 18:39:58 +02001174 n = ha_cpuset_ffs(&cpus_copy) - 1;
1175 ha_cpuset_clr(&cpus_copy, n);
Willy Tarreaueded6c12023-07-19 18:17:39 +02001176 ha_cpuset_set(&cpu_map[g].thread[j], n);
Willy Tarreau36b9e222018-11-11 15:19:52 +01001177 }
1178 }
1179 }
1180#else
1181 ha_alert("parsing [%s:%d] : '%s' is not enabled, please check build options for USE_CPU_AFFINITY.\n",
1182 file, linenum, args[0]);
1183 err_code |= ERR_ALERT | ERR_FATAL;
1184 goto out;
1185#endif /* ! USE_CPU_AFFINITY */
1186 }
1187 else if (strcmp(args[0], "setenv") == 0 || strcmp(args[0], "presetenv") == 0) {
1188 if (alertif_too_many_args(3, file, linenum, args, &err_code))
1189 goto out;
1190
1191 if (*(args[2]) == 0) {
1192 ha_alert("parsing [%s:%d]: '%s' expects a name and a value.\n", file, linenum, args[0]);
1193 err_code |= ERR_ALERT | ERR_FATAL;
1194 goto out;
1195 }
1196
1197 /* "setenv" overwrites, "presetenv" only sets if not yet set */
1198 if (setenv(args[1], args[2], (args[0][0] == 's')) != 0) {
1199 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[1], strerror(errno));
1200 err_code |= ERR_ALERT | ERR_FATAL;
1201 goto out;
1202 }
1203 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001204 else if (strcmp(args[0], "unsetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001205 int arg;
1206
1207 if (*(args[1]) == 0) {
1208 ha_alert("parsing [%s:%d]: '%s' expects at least one variable name.\n", file, linenum, args[0]);
1209 err_code |= ERR_ALERT | ERR_FATAL;
1210 goto out;
1211 }
1212
1213 for (arg = 1; *args[arg]; arg++) {
1214 if (unsetenv(args[arg]) != 0) {
1215 ha_alert("parsing [%s:%d]: '%s' failed on variable '%s' : %s.\n", file, linenum, args[0], args[arg], strerror(errno));
1216 err_code |= ERR_ALERT | ERR_FATAL;
1217 goto out;
1218 }
1219 }
1220 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001221 else if (strcmp(args[0], "resetenv") == 0) {
Willy Tarreau36b9e222018-11-11 15:19:52 +01001222 extern char **environ;
1223 char **env = environ;
1224
1225 /* args contain variable names to keep, one per argument */
1226 while (*env) {
1227 int arg;
1228
1229 /* look for current variable in among all those we want to keep */
1230 for (arg = 1; *args[arg]; arg++) {
1231 if (strncmp(*env, args[arg], strlen(args[arg])) == 0 &&
1232 (*env)[strlen(args[arg])] == '=')
1233 break;
1234 }
1235
1236 /* delete this variable */
1237 if (!*args[arg]) {
1238 char *delim = strchr(*env, '=');
1239
1240 if (!delim || delim - *env >= trash.size) {
1241 ha_alert("parsing [%s:%d]: '%s' failed to unset invalid variable '%s'.\n", file, linenum, args[0], *env);
1242 err_code |= ERR_ALERT | ERR_FATAL;
1243 goto out;
1244 }
1245
1246 memcpy(trash.area, *env, delim - *env);
1247 trash.area[delim - *env] = 0;
1248
1249 if (unsetenv(trash.area) != 0) {
1250 ha_alert("parsing [%s:%d]: '%s' failed to unset variable '%s' : %s.\n", file, linenum, args[0], *env, strerror(errno));
1251 err_code |= ERR_ALERT | ERR_FATAL;
1252 goto out;
1253 }
1254 }
1255 else
1256 env++;
1257 }
1258 }
Willy Tarreaue98d3852022-11-15 09:34:07 +01001259 else if (strcmp(args[0], "quick-exit") == 0) {
1260 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1261 goto out;
1262 global.tune.options |= GTUNE_QUICK_EXIT;
1263 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001264 else if (strcmp(args[0], "strict-limits") == 0) { /* "no strict-limits" or "strict-limits" */
William Dauchy0fec3ab2019-10-27 20:08:11 +01001265 if (alertif_too_many_args(0, file, linenum, args, &err_code))
1266 goto out;
1267 if (kwm == KWM_NO)
1268 global.tune.options &= ~GTUNE_STRICT_LIMITS;
William Dauchy0fec3ab2019-10-27 20:08:11 +01001269 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001270 else if (strcmp(args[0], "localpeer") == 0) {
Dragan Dosen13cd54c2020-06-18 18:24:05 +02001271 if (alertif_too_many_args(1, file, linenum, args, &err_code))
1272 goto out;
1273
1274 if (*(args[1]) == 0) {
1275 ha_alert("parsing [%s:%d] : '%s' expects a name as an argument.\n",
1276 file, linenum, args[0]);
1277 err_code |= ERR_ALERT | ERR_FATAL;
1278 goto out;
1279 }
1280
1281 if (global.localpeer_cmdline != 0) {
1282 ha_warning("parsing [%s:%d] : '%s' ignored since it is already set by using the '-L' "
1283 "command line argument.\n", file, linenum, args[0]);
1284 err_code |= ERR_WARN;
1285 goto out;
1286 }
1287
1288 if (cfg_peers) {
1289 ha_warning("parsing [%s:%d] : '%s' ignored since it is used after 'peers' section.\n",
1290 file, linenum, args[0]);
1291 err_code |= ERR_WARN;
1292 goto out;
1293 }
1294
1295 free(localpeer);
1296 if ((localpeer = strdup(args[1])) == NULL) {
1297 ha_alert("parsing [%s:%d]: cannot allocate memory for '%s'.\n",
1298 file, linenum, args[0]);
1299 err_code |= ERR_ALERT | ERR_FATAL;
1300 goto out;
1301 }
1302 setenv("HAPROXY_LOCALPEER", localpeer, 1);
1303 }
Amaury Denoyelle0f50cb92021-03-26 18:50:33 +01001304 else if (strcmp(args[0], "numa-cpu-mapping") == 0) {
1305 global.numa_cpu_mapping = (kwm == KWM_NO) ? 0 : 1;
1306 }
Erwan Le Goasfad9da82022-09-14 17:24:22 +02001307 else if (strcmp(args[0], "anonkey") == 0) {
1308 long long tmp = 0;
1309
1310 if (*args[1] == 0) {
1311 ha_alert("parsing [%s:%d]: a key is expected after '%s'.\n",
1312 file, linenum, args[0]);
1313 err_code |= ERR_ALERT | ERR_FATAL;
1314 goto out;
1315 }
1316
1317 if (HA_ATOMIC_LOAD(&global.anon_key) == 0) {
1318 tmp = atoll(args[1]);
1319 if (tmp < 0 || tmp > UINT_MAX) {
1320 ha_alert("parsing [%s:%d]: '%s' value must be within range %u-%u (was '%s').\n",
1321 file, linenum, args[0], 0, UINT_MAX, args[1]);
1322 err_code |= ERR_ALERT | ERR_FATAL;
1323 goto out;
1324 }
1325
1326 HA_ATOMIC_STORE(&global.anon_key, tmp);
1327 }
1328 }
Willy Tarreau36b9e222018-11-11 15:19:52 +01001329 else {
1330 struct cfg_kw_list *kwl;
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001331 const char *best;
Willy Tarreau36b9e222018-11-11 15:19:52 +01001332 int index;
1333 int rc;
1334
1335 list_for_each_entry(kwl, &cfg_keywords.list, list) {
1336 for (index = 0; kwl->kw[index].kw != NULL; index++) {
1337 if (kwl->kw[index].section != CFG_GLOBAL)
1338 continue;
1339 if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001340 if (check_kw_experimental(&kwl->kw[index], file, linenum, &errmsg)) {
Amaury Denoyelle86c1d0f2021-05-07 15:07:21 +02001341 ha_alert("%s\n", errmsg);
Amaury Denoyelled2e53cd2021-05-06 16:21:39 +02001342 err_code |= ERR_ALERT | ERR_FATAL;
1343 goto out;
1344 }
1345
Willy Tarreau36b9e222018-11-11 15:19:52 +01001346 rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
1347 if (rc < 0) {
1348 ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1349 err_code |= ERR_ALERT | ERR_FATAL;
1350 }
1351 else if (rc > 0) {
1352 ha_warning("parsing [%s:%d] : %s\n", file, linenum, errmsg);
1353 err_code |= ERR_WARN;
1354 goto out;
1355 }
1356 goto out;
1357 }
1358 }
1359 }
1360
Willy Tarreau101df312021-03-15 09:12:41 +01001361 best = cfg_find_best_match(args[0], &cfg_keywords.list, CFG_GLOBAL, common_kw_list);
Willy Tarreaua0e8eb82021-03-12 09:30:14 +01001362 if (best)
1363 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section; did you mean '%s' maybe ?\n", file, linenum, args[0], cursection, best);
1364 else
1365 ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
Willy Tarreau36b9e222018-11-11 15:19:52 +01001366 err_code |= ERR_ALERT | ERR_FATAL;
1367 }
1368
1369 out:
1370 free(errmsg);
1371 return err_code;
1372}
1373
Patrick Hemmer425d7ad2023-05-23 13:02:08 -04001374static int cfg_parse_prealloc_fd(char **args, int section_type, struct proxy *curpx,
1375 const struct proxy *defpx, const char *file, int line,
1376 char **err)
1377{
1378 if (too_many_args(0, args, err, NULL))
1379 return -1;
1380
1381 global.prealloc_fd = 1;
1382
1383 return 0;
1384}
1385
Amaury Denoyelle1125d052024-05-22 14:21:16 +02001386/* Parser for harden.reject-privileged-ports.{tcp|quic}. */
1387static int cfg_parse_reject_privileged_ports(char **args, int section_type,
1388 struct proxy *curpx,
1389 const struct proxy *defpx,
1390 const char *file, int line, char **err)
1391{
1392 struct ist proto;
1393 char onoff;
1394
1395 if (!*(args[1])) {
1396 memprintf(err, "'%s' expects either 'on' or 'off'.", args[0]);
1397 return -1;
1398 }
1399
1400 proto = ist(args[0]);
1401 while (istlen(istfind(proto, '.')))
1402 proto = istadv(istfind(proto, '.'), 1);
1403
1404 if (strcmp(args[1], "on") == 0) {
1405 onoff = 1;
1406 }
1407 else if (strcmp(args[1], "off") == 0) {
1408 onoff = 0;
1409 }
1410 else {
1411 memprintf(err, "'%s' expects either 'on' or 'off'.", args[0]);
1412 return -1;
1413 }
1414
1415 if (istmatch(proto, ist("tcp"))) {
1416 if (!onoff)
1417 global.clt_privileged_ports |= HA_PROTO_TCP;
1418 else
1419 global.clt_privileged_ports &= ~HA_PROTO_TCP;
1420 }
1421 else if (istmatch(proto, ist("quic"))) {
1422 if (!onoff)
1423 global.clt_privileged_ports |= HA_PROTO_QUIC;
1424 else
1425 global.clt_privileged_ports &= ~HA_PROTO_QUIC;
1426 }
1427 else {
1428 memprintf(err, "invalid protocol for '%s'.", args[0]);
1429 return -1;
1430 }
1431
1432 return 0;
1433}
1434
Patrick Hemmer425d7ad2023-05-23 13:02:08 -04001435static struct cfg_kw_list cfg_kws = {ILH, {
1436 { CFG_GLOBAL, "prealloc-fd", cfg_parse_prealloc_fd },
Amaury Denoyelle1125d052024-05-22 14:21:16 +02001437 { CFG_GLOBAL, "harden.reject-privileged-ports.tcp", cfg_parse_reject_privileged_ports },
1438 { CFG_GLOBAL, "harden.reject-privileged-ports.quic", cfg_parse_reject_privileged_ports },
Patrick Hemmer425d7ad2023-05-23 13:02:08 -04001439 { 0, NULL, NULL },
1440}};
1441
1442INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);