Coverage Report

Created: 2026-01-13 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/haproxy/src/haproxy.c
Line
Count
Source
1
/*
2
 * HAProxy : High Availability-enabled HTTP/TCP proxy
3
 * Copyright 2000-2026 Willy Tarreau <willy@haproxy.org>.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version
8
 * 2 of the License, or (at your option) any later version.
9
 */
10
11
#define _GNU_SOURCE
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <unistd.h>
15
#include <string.h>
16
#include <ctype.h>
17
#include <dirent.h>
18
#include <sys/stat.h>
19
#include <sys/time.h>
20
#include <sys/types.h>
21
#include <sys/socket.h>
22
#include <netinet/tcp.h>
23
#include <netinet/in.h>
24
#include <arpa/inet.h>
25
#include <netdb.h>
26
#include <signal.h>
27
#include <stdarg.h>
28
#include <sys/resource.h>
29
#include <sys/utsname.h>
30
#include <sys/wait.h>
31
#include <time.h>
32
#include <syslog.h>
33
#include <grp.h>
34
35
#ifdef USE_THREAD
36
#include <pthread.h>
37
#endif
38
39
#ifdef USE_CPU_AFFINITY
40
#include <sched.h>
41
#if defined(__FreeBSD__) || defined(__DragonFly__)
42
#include <sys/param.h>
43
#ifdef __FreeBSD__
44
#include <sys/cpuset.h>
45
#endif
46
#endif
47
#endif
48
49
#if defined(USE_PRCTL)
50
#include <sys/prctl.h>
51
#endif
52
53
#if defined(USE_PROCCTL)
54
#include <sys/procctl.h>
55
#endif
56
57
#ifdef DEBUG_FULL
58
#include <assert.h>
59
#endif
60
61
#include <import/sha1.h>
62
63
#include <haproxy/acl.h>
64
#include <haproxy/action.h>
65
#include <haproxy/activity.h>
66
#include <haproxy/api.h>
67
#include <haproxy/arg.h>
68
#include <haproxy/auth.h>
69
#include <haproxy/base64.h>
70
#include <haproxy/capture-t.h>
71
#include <haproxy/cfgcond.h>
72
#include <haproxy/cfgdiag.h>
73
#include <haproxy/cfgparse.h>
74
#include <haproxy/chunk.h>
75
#include <haproxy/cli.h>
76
#include <haproxy/clock.h>
77
#include <haproxy/connection.h>
78
#include <haproxy/counters.h>
79
#ifdef USE_CPU_AFFINITY
80
#include <haproxy/cpuset.h>
81
#include <haproxy/cpu_topo.h>
82
#endif
83
#include <haproxy/debug.h>
84
#include <haproxy/dns.h>
85
#include <haproxy/dynbuf.h>
86
#include <haproxy/errors.h>
87
#include <haproxy/fd.h>
88
#include <haproxy/filters.h>
89
#include <haproxy/global.h>
90
#include <haproxy/hlua.h>
91
#include <haproxy/http_rules.h>
92
#include <haproxy/limits.h>
93
#if defined(USE_LINUX_CAP)
94
#include <haproxy/linuxcap.h>
95
#endif
96
#include <haproxy/list.h>
97
#include <haproxy/listener.h>
98
#include <haproxy/log.h>
99
#include <haproxy/mworker.h>
100
#include <haproxy/namespace.h>
101
#include <haproxy/net_helper.h>
102
#include <haproxy/openssl-compat.h>
103
#include <haproxy/pattern.h>
104
#include <haproxy/peers.h>
105
#include <haproxy/pool.h>
106
#include <haproxy/protocol.h>
107
#include <haproxy/proto_sockpair.h>
108
#include <haproxy/proto_tcp.h>
109
#include <haproxy/proxy.h>
110
#include <haproxy/regex.h>
111
#include <haproxy/resolvers.h>
112
#include <haproxy/sample.h>
113
#include <haproxy/server.h>
114
#include <haproxy/session.h>
115
#include <haproxy/signal.h>
116
#include <haproxy/sock.h>
117
#include <haproxy/sock_inet.h>
118
#include <haproxy/ssl_sock.h>
119
#include <haproxy/stats-file.h>
120
#include <haproxy/stats-t.h>
121
#include <haproxy/stream.h>
122
#include <haproxy/systemd.h>
123
#include <haproxy/task.h>
124
#include <haproxy/thread.h>
125
#include <haproxy/time.h>
126
#include <haproxy/tools.h>
127
#include <haproxy/trace.h>
128
#include <haproxy/uri_auth-t.h>
129
#include <haproxy/vars.h>
130
#include <haproxy/version.h>
131
132
133
/* array of init calls for older platforms */
134
DECLARE_INIT_STAGES;
135
136
/* create a read_mostly section to hold variables which are accessed a lot
137
 * but which almost never change. The purpose is to isolate them in their
138
 * own cache lines where they don't risk to be perturbated by write accesses
139
 * to neighbor variables. We need to create an empty aligned variable for
140
 * this. The fact that the variable is of size zero means that it will be
141
 * eliminated at link time if no other variable uses it, but alignment will
142
 * be respected.
143
 */
144
empty_t __read_mostly_align HA_SECTION("read_mostly") ALIGNED(64);
145
146
/* list of config files */
147
static struct list cfg_cfgfiles = LIST_HEAD_INIT(cfg_cfgfiles);
148
int  pid;     /* current process id */
149
char **init_env;    /* to keep current process env variables backup */
150
int  pidfd = -1;    /* FD to keep PID */
151
int daemon_fd[2] = {-1, -1};  /* pipe to communicate with parent process */
152
int devnullfd = -1;
153
154
static int stopped_tgroups;
155
static int stop_detected;
156
157
/* global options */
158
struct global global = {
159
  .uid = -1, // not set
160
  .gid = -1, // not set
161
  .hard_stop_after = TICK_ETERNITY,
162
  .close_spread_time = TICK_ETERNITY,
163
  .close_spread_end = TICK_ETERNITY,
164
  .numa_cpu_mapping = 1,
165
  .nbthread = 0,
166
  .req_count = 0,
167
  .loggers = LIST_HEAD_INIT(global.loggers),
168
  .maxzlibmem = DEFAULT_MAXZLIBMEM * 1024U * 1024U,
169
  .comp_rate_lim = 0,
170
  .ssl_server_verify = SSL_SERVER_VERIFY_REQUIRED,
171
  .unix_bind = {
172
     .ux = {
173
       .uid = -1,
174
       .gid = -1,
175
       .mode = 0,
176
     }
177
  },
178
  .tune = {
179
    .options = GTUNE_LISTENER_MQ_OPT,
180
    .bufsize = (BUFSIZE + 2*sizeof(void *) - 1) & -(2*sizeof(void *)),
181
    .bufsize_small = BUFSIZE_SMALL,
182
    .maxrewrite = MAXREWRITE,
183
    .reserved_bufs = RESERVED_BUFS,
184
    .pattern_cache = DEFAULT_PAT_LRU_SIZE,
185
    .pool_low_ratio  = 20,
186
    .pool_high_ratio = 25,
187
    .max_http_hdr = MAX_HTTP_HDR,
188
#ifdef USE_OPENSSL
189
    .sslcachesize = SSLCACHESIZE,
190
#endif
191
    .comp_maxlevel = 1,
192
    .glitch_kill_maxidle = 100,
193
#ifdef DEFAULT_IDLE_TIMER
194
    .idle_timer = DEFAULT_IDLE_TIMER,
195
#else
196
    .idle_timer = 1000, /* 1 second */
197
#endif
198
    .nb_stk_ctr = MAX_SESS_STKCTR,
199
    .default_shards = -2, /* by-group */
200
  },
201
#ifdef USE_OPENSSL
202
#ifdef DEFAULT_MAXSSLCONN
203
  .maxsslconn = DEFAULT_MAXSSLCONN,
204
#endif
205
#endif
206
  /* by default allow clients which use a privileged port for TCP only */
207
  .clt_privileged_ports = HA_PROTO_TCP,
208
  /* others NULL OK */
209
};
210
211
/*********************************************************************/
212
213
int stopping; /* non zero means stopping in progress */
214
int killed; /* non zero means a hard-stop is triggered */
215
int jobs = 0;   /* number of active jobs (conns, listeners, active tasks, ...) */
216
int unstoppable_jobs = 0;  /* number of active jobs that can't be stopped during a soft stop */
217
int active_peers = 0; /* number of active peers (connection attempts and connected) */
218
int connected_peers = 0; /* number of connected peers (verified ones) */
219
int arg_mode = 0; /* MODE_DEBUG etc as passed on command line ... */
220
char *change_dir = NULL; /* set when -C is passed */
221
char *check_condition = NULL; /* check condition passed to -cc */
222
char *progname = NULL; /* HAProxy binary's name */
223
224
/* Here we store information about the pids of the processes we may pause
225
 * or kill. We will send them a signal every 10 ms until we can bind to all
226
 * our ports. With 200 retries, that's about 2 seconds.
227
 */
228
0
#define MAX_START_RETRIES 200
229
static int *oldpids = NULL;
230
int oldpids_sig; /* use USR1 or TERM */
231
232
/* Path to the unix socket we use to retrieve listener sockets from the old process */
233
const char *old_unixsocket;
234
235
int atexit_flag = 0;
236
237
int nb_oldpids = 0;
238
const int zero = 0;
239
const int one = 1;
240
const struct linger nolinger = { .l_onoff = 1, .l_linger = 0 };
241
242
char hostname[MAX_HOSTNAME_LEN];
243
char *localpeer = NULL;
244
static char *kwd_dump = NULL; // list of keyword dumps to produce
245
246
char **old_argv = NULL; /* previous argv but cleaned up */
247
248
struct list proc_list = LIST_HEAD_INIT(proc_list);
249
250
#ifdef DEBUG_UNIT
251
struct list unittest_list = LIST_HEAD_INIT(unittest_list);
252
static int unittest_argc = -1;
253
#endif
254
255
int master = 0; /* 1 if in master, 0 if in child */
256
257
/* per-boot randomness */
258
unsigned char boot_seed[20];        /* per-boot random seed (160 bits initially) */
259
260
/* bitfield of a few warnings to emit just once (WARN_*) */
261
unsigned int warned = 0;
262
263
/* set if experimental features have been used for the current process */
264
unsigned int tainted = 0;
265
266
unsigned int experimental_directives_allowed = 0;
267
unsigned int deprecated_directives_allowed = 0;
268
269
int check_kw_experimental(struct cfg_keyword *kw, const char *file, int linenum,
270
                          char **errmsg)
271
0
{
272
0
  if (kw->flags & KWF_EXPERIMENTAL) {
273
0
    if (!experimental_directives_allowed) {
274
0
      memprintf(errmsg, "parsing [%s:%d] : '%s' directive is experimental, must be allowed via a global 'expose-experimental-directives'",
275
0
                file, linenum, kw->kw);
276
0
      return 1;
277
0
    }
278
0
    mark_tainted(TAINTED_CONFIG_EXP_KW_DECLARED);
279
0
  }
280
281
0
  return 0;
282
0
}
283
284
/* These are strings to be reported in the output of "haproxy -vv". They may
285
 * either be constants (in which case must_free must be zero) or dynamically
286
 * allocated strings to pass to free() on exit, and in this case must_free
287
 * must be non-zero.
288
 */
289
struct list build_opts_list = LIST_HEAD_INIT(build_opts_list);
290
struct build_opts_str {
291
  struct list list;
292
  const char *str;
293
  int must_free;
294
};
295
296
int mode_stress_level = 0;
297
298
/*********************************************************************/
299
/*  general purpose functions  ***************************************/
300
/*********************************************************************/
301
302
/* used to register some build option strings at boot. Set must_free to
303
 * non-zero if the string must be freed upon exit.
304
 */
305
void hap_register_build_opts(const char *str, int must_free)
306
0
{
307
0
  struct build_opts_str *b;
308
309
0
  b = calloc(1, sizeof(*b));
310
0
  if (!b) {
311
0
    fprintf(stderr, "out of memory\n");
312
0
    exit(1);
313
0
  }
314
0
  b->str = str;
315
0
  b->must_free = must_free;
316
0
  LIST_APPEND(&build_opts_list, &b->list);
317
0
}
318
319
/* returns the first build option when <curr> is NULL, or the next one when
320
 * <curr> is passed the last returned value. NULL when there is no more entries
321
 * in the list. Otherwise the returned pointer is &opt->str so the caller can
322
 * print it as *ret.
323
 */
324
const char **hap_get_next_build_opt(const char **curr)
325
0
{
326
0
  struct build_opts_str *head, *start;
327
328
0
  head = container_of(&build_opts_list, struct build_opts_str, list);
329
330
0
  if (curr)
331
0
    start = container_of(curr, struct build_opts_str, str);
332
0
  else
333
0
    start = head;
334
335
0
  start = container_of(start->list.n, struct build_opts_str, list);
336
337
0
  if (start == head)
338
0
    return NULL;
339
340
0
  return &start->str;
341
0
}
342
343
/* used to make a new feature appear in the build_features list at boot time.
344
 * The feature must be in the format "XXX" without the leading "+" which will
345
 * be automatically appended.
346
 */
347
void hap_register_feature(const char *name)
348
0
{
349
0
  static int must_free = 0;
350
0
  int new_len = strlen(build_features) + 2 + strlen(name);
351
0
  char *new_features;
352
0
  char *startp, *endp;
353
0
  int found = 0;
354
355
0
  new_features = malloc(new_len + 1);
356
0
  if (!new_features)
357
0
    return;
358
359
0
  strlcpy2(new_features, build_features, new_len);
360
361
0
  startp = new_features;
362
363
  /* look if the string already exists */
364
0
  while (startp) {
365
0
    char *sign = startp;
366
367
    /* tokenize for simpler strcmp */
368
0
    endp = strchr(startp, ' ');
369
0
    if (endp)
370
0
      *endp = '\0';
371
372
0
    startp++; /* skip sign */
373
374
0
    if (strcmp(startp, name) == 0) {
375
0
      *sign = '+';
376
0
      found = 1;
377
0
    }
378
379
    /* couldn't find a space, that's the end of the string */
380
0
    if (!endp)
381
0
      break;
382
383
0
    *endp = ' ';
384
0
    startp = endp + 1;
385
386
0
    if (found)
387
0
      break;
388
0
  }
389
390
  /* if we didn't find the feature add it to the string */
391
0
  if (!found)
392
0
    snprintf(new_features, new_len + 1, "%s +%s", build_features, name);
393
394
0
  if (must_free)
395
0
    ha_free(&build_features);
396
397
0
  build_features = new_features;
398
0
  must_free = 1;
399
0
}
400
401
#ifdef DEBUG_UNIT
402
/* register a function that could be registered in "-U" argument */
403
void hap_register_unittest(const char *name, int (*fct)(int argc, char **argv))
404
{
405
  struct unittest_fct *unit;
406
407
  if (!name || !fct)
408
    return;
409
410
  unit = calloc(1, sizeof(*unit));
411
  unit->fct = fct;
412
  unit->name = name;
413
  LIST_APPEND(&unittest_list, &unit->list);
414
}
415
#endif
416
417
0
#define VERSION_MAX_ELTS  7
418
419
/* This function splits an haproxy version string into an array of integers.
420
 * The syntax of the supported version string is the following:
421
 *
422
 *    <a>[.<b>[.<c>[.<d>]]][-{dev,pre,rc}<f>][-*][-<g>]
423
 *
424
 * This validates for example:
425
 *   1.2.1-pre2, 1.2.1, 1.2.10.1, 1.3.16-rc1, 1.4-dev3, 1.5-dev18, 1.5-dev18-43
426
 *   2.4-dev18-f6818d-20
427
 *
428
 * The result is set in a array of <VERSION_MAX_ELTS> elements. Each letter has
429
 * one fixed place in the array. The tags take a numeric value called <e> which
430
 * defaults to 3. "dev" is 1, "rc" and "pre" are 2. Numbers not encountered are
431
 * considered as zero (henxe 1.5 and 1.5.0 are the same).
432
 *
433
 * The resulting values are:
434
 *   1.2.1-pre2            1, 2,  1, 0, 2,  2,  0
435
 *   1.2.1                 1, 2,  1, 0, 3,  0,  0
436
 *   1.2.10.1              1, 2, 10, 1, 3,  0,  0
437
 *   1.3.16-rc1            1, 3, 16, 0, 2,  1,  0
438
 *   1.4-dev3              1, 4,  0, 0, 1,  3,  0
439
 *   1.5-dev18             1, 5,  0, 0, 1, 18,  0
440
 *   1.5-dev18-43          1, 5,  0, 0, 1, 18, 43
441
 *   2.4-dev18-f6818d-20   2, 4,  0, 0, 1, 18, 20
442
 *
443
 * The function returns non-zero if the conversion succeeded, or zero if it
444
 * failed.
445
 */
446
int split_version(const char *version, unsigned int *value)
447
0
{
448
0
  const char *p, *s;
449
0
  char *error;
450
0
  int nelts;
451
452
  /* Initialize array with zeroes */
453
0
  for (nelts = 0; nelts < VERSION_MAX_ELTS; nelts++)
454
0
    value[nelts] = 0;
455
0
  value[4] = 3;
456
457
0
  p = version;
458
459
  /* If the version number is empty, return false */
460
0
  if (*p == '\0')
461
0
    return 0;
462
463
  /* Convert first number <a> */
464
0
  value[0] = strtol(p, &error, 10);
465
0
  p = error + 1;
466
0
  if (*error == '\0')
467
0
    return 1;
468
0
  if (*error == '-')
469
0
    goto split_version_tag;
470
0
  if (*error != '.')
471
0
    return 0;
472
473
  /* Convert first number <b> */
474
0
  value[1] = strtol(p, &error, 10);
475
0
  p = error + 1;
476
0
  if (*error == '\0')
477
0
    return 1;
478
0
  if (*error == '-')
479
0
    goto split_version_tag;
480
0
  if (*error != '.')
481
0
    return 0;
482
483
  /* Convert first number <c> */
484
0
  value[2] = strtol(p, &error, 10);
485
0
  p = error + 1;
486
0
  if (*error == '\0')
487
0
    return 1;
488
0
  if (*error == '-')
489
0
    goto split_version_tag;
490
0
  if (*error != '.')
491
0
    return 0;
492
493
  /* Convert first number <d> */
494
0
  value[3] = strtol(p, &error, 10);
495
0
  p = error + 1;
496
0
  if (*error == '\0')
497
0
    return 1;
498
0
  if (*error != '-')
499
0
    return 0;
500
501
0
 split_version_tag:
502
  /* Check for commit number */
503
0
  if (*p >= '0' && *p <= '9')
504
0
    goto split_version_commit;
505
506
  /* Read tag */
507
0
  if (strncmp(p, "dev", 3) == 0)      { value[4] = 1; p += 3; }
508
0
  else if (strncmp(p, "rc", 2) == 0)  { value[4] = 2; p += 2; }
509
0
  else if (strncmp(p, "pre", 3) == 0) { value[4] = 2; p += 3; }
510
0
  else
511
0
    goto split_version_commit;
512
513
  /* Convert tag number */
514
0
  value[5] = strtol(p, &error, 10);
515
0
  p = error + 1;
516
0
  if (*error == '\0')
517
0
    return 1;
518
0
  if (*error != '-')
519
0
    return 0;
520
521
0
 split_version_commit:
522
  /* Search the last "-" */
523
0
  s = strrchr(p, '-');
524
0
  if (s) {
525
0
    s++;
526
0
    if (*s == '\0')
527
0
      return 0;
528
0
    value[6] = strtol(s, &error, 10);
529
0
    if (*error != '\0')
530
0
      value[6] = 0;
531
0
    return 1;
532
0
  }
533
534
  /* convert the version */
535
0
  value[6] = strtol(p, &error, 10);
536
0
  if (*error != '\0')
537
0
    value[6] = 0;
538
539
0
  return 1;
540
0
}
541
542
/* This function compares the current haproxy version with an arbitrary version
543
 * string. It returns:
544
 *  -1 : the version in argument is older than the current haproxy version
545
 *   0 : the version in argument is the same as the current haproxy version
546
 *   1 : the version in argument is newer than the current haproxy version
547
 *
548
 * Or some errors:
549
 *  -2 : the current haproxy version is not parsable
550
 *  -3 : the version in argument is not parsable
551
 */
552
int compare_current_version(const char *version)
553
0
{
554
0
  unsigned int loc[VERSION_MAX_ELTS];
555
0
  unsigned int mod[VERSION_MAX_ELTS];
556
0
  int i;
557
558
  /* split versions */
559
0
  if (!split_version(haproxy_version, loc))
560
0
    return -2;
561
0
  if (!split_version(version, mod))
562
0
    return -3;
563
564
  /* compare versions */
565
0
  for (i = 0; i < VERSION_MAX_ELTS; i++) {
566
0
    if (mod[i] < loc[i])
567
0
      return -1;
568
0
    else if (mod[i] > loc[i])
569
0
      return 1;
570
0
  }
571
0
  return 0;
572
0
}
573
574
void display_version()
575
0
{
576
0
  struct utsname utsname;
577
578
0
  printf("HAProxy version %s %s - https://haproxy.org/\n"
579
0
         PRODUCT_STATUS "\n", haproxy_version, haproxy_date);
580
581
0
  if (strlen(PRODUCT_URL_BUGS) > 0) {
582
0
    char base_version[20];
583
0
    int dots = 0;
584
0
    char *del;
585
586
    /* only retrieve the base version without distro-specific extensions */
587
0
    for (del = haproxy_version; *del; del++) {
588
0
      if (*del == '.')
589
0
        dots++;
590
0
      else if (*del < '0' || *del > '9')
591
0
        break;
592
0
    }
593
594
0
    strlcpy2(base_version, haproxy_version, del - haproxy_version + 1);
595
0
    if (dots < 2)
596
0
      printf("Known bugs: https://github.com/haproxy/haproxy/issues?q=is:issue+is:open\n");
597
0
    else
598
0
      printf("Known bugs: " PRODUCT_URL_BUGS "\n", base_version);
599
0
  }
600
601
0
  if (uname(&utsname) == 0) {
602
0
    printf("Running on: %s %s %s %s\n", utsname.sysname, utsname.release, utsname.version, utsname.machine);
603
0
  }
604
0
}
605
606
/* display_mode:
607
 * 0 = short version (e.g., "3.3.1")
608
 * 1 = full version (e.g., "3.3.1-dev5-1bb975-71")
609
 * 2 = branch version (e.g., "3.3")
610
 */
611
void display_version_plain(int display_mode)
612
0
{
613
0
  char out[30] = "";
614
0
  int dots = 0;
615
0
  int i;
616
617
0
  if (display_mode == 1) {
618
0
    printf("%s\n", haproxy_version);
619
0
    return;
620
0
  }
621
622
0
  for (i = 0; i < sizeof(out) - 1 && haproxy_version[i]; i++) {
623
0
    if (display_mode == 2) {
624
0
      if (haproxy_version[i] == '.') dots++;
625
0
      if (dots == 2 || haproxy_version[i] == '-') {
626
0
        out[i] = '\0';
627
0
        break;
628
0
      }
629
0
    } else {
630
0
      if ((haproxy_version[i] < '0' || haproxy_version[i] > '9') && haproxy_version[i] != '.') {
631
0
        out[i] = '\0';
632
0
        break;
633
0
      }
634
0
    }
635
0
    out[i] = haproxy_version[i];
636
0
    out[i+1] = '\0';
637
0
  }
638
639
0
  printf("%s\n", out);
640
0
}
641
642
static void display_build_opts()
643
0
{
644
0
  const char **opt;
645
646
0
  printf("Build options : %s"
647
0
         "\n\nFeature list : %s"
648
0
         "\n\nDefault settings :"
649
0
         "\n  bufsize = %d, maxrewrite = %d, maxpollevents = %d"
650
0
         "\n\n",
651
0
         build_opts_string,
652
0
         build_features, BUFSIZE, MAXREWRITE, MAX_POLL_EVENTS);
653
654
0
  for (opt = NULL; (opt = hap_get_next_build_opt(opt)); puts(*opt))
655
0
    ;
656
657
0
  putchar('\n');
658
659
#ifdef DEBUG_UNIT
660
  list_unittests();
661
  putchar('\n');
662
#endif
663
0
  list_pollers(stdout);
664
0
  putchar('\n');
665
0
  list_mux_proto(stdout);
666
0
  putchar('\n');
667
0
  list_services(stdout);
668
0
  putchar('\n');
669
0
  list_filters(stdout);
670
0
  putchar('\n');
671
0
}
672
673
/*
674
 * This function prints the command line usage and exits
675
 */
676
static void usage(char *name)
677
0
{
678
0
  display_version();
679
0
  fprintf(stderr,
680
0
    "Usage : %s [-f <cfgfile|cfgdir>]* [ -vdV"
681
0
    "D ] [ -n <maxconn> ] [ -N <maxpconn> ]\n"
682
0
    "        [ -p <pidfile> ] [ -m <max megs> ] [ -C <dir> ] [-- <cfgfile>*]\n"
683
0
    "        -v displays version ; -vv shows known build options.\n"
684
0
    "        -vq/-vqs/-vqb only displays version, short version, branch.\n"
685
0
    "        -d enters debug mode ; -db only disables background mode.\n"
686
0
    "        -dM[<byte>,help,...] debug memory (default: poison with <byte>/0x50)\n"
687
0
    "        -dt activate traces on stderr; see '-dt help'\n"
688
0
    "        -V enters verbose mode (disables quiet mode)\n"
689
0
    "        -D goes daemon ; -C changes to <dir> before loading files.\n"
690
0
    "        -W master-worker mode.\n"
691
0
    "        -Ws master-worker mode with systemd notify support.\n"
692
0
    "        -q quiet mode : don't display messages\n"
693
0
    "        -c check mode : only check config files and exit\n"
694
0
    "        -cc check condition : evaluate a condition and exit\n"
695
0
    "        -4 force resolvers to consider IPv4 responses only\n"
696
0
    "        -n sets the maximum total # of connections (uses ulimit -n)\n"
697
0
    "        -m limits the usable amount of memory (in MB)\n"
698
0
    "        -N sets the default, per-proxy maximum # of connections (%d)\n"
699
0
    "        -L set local peer name (default to hostname)\n"
700
0
    "        -p writes pids of all children to this file\n"
701
0
    "        -dC[[key],line] display the configuration file, if there is a key, the file will be anonymised\n"
702
#if defined(USE_EPOLL)
703
    "        -de disables epoll() usage even when available\n"
704
#endif
705
#if defined(USE_KQUEUE)
706
    "        -dk disables kqueue() usage even when available\n"
707
#endif
708
#if defined(USE_EVPORTS)
709
    "        -dv disables event ports usage even when available\n"
710
#endif
711
0
#if defined(USE_POLL)
712
0
    "        -dp disables poll() usage even when available\n"
713
0
#endif
714
#if defined(USE_LINUX_SPLICE)
715
    "        -dS disables splice usage (broken on old kernels)\n"
716
#endif
717
#if defined(USE_GETADDRINFO)
718
    "        -dG disables getaddrinfo() usage\n"
719
#endif
720
0
#if defined(SO_REUSEPORT)
721
0
    "        -dR disables SO_REUSEPORT usage\n"
722
0
#endif
723
#if defined(HA_HAVE_DUMP_LIBS)
724
    "        -dL dumps loaded object files after config checks\n"
725
#endif
726
#if defined(USE_CPU_AFFINITY)
727
    "        -dc dumps the list of selected and evicted CPUs\n"
728
#endif
729
0
    "        -dK{class[,...]} dump registered keywords (use 'help' for list)\n"
730
0
    "        -dr ignores server address resolution failures\n"
731
0
    "        -dV disables SSL verify on servers side\n"
732
0
    "        -dW fails if any warning is emitted\n"
733
0
    "        -dD diagnostic mode : warn about suspicious configuration statements\n"
734
0
    "        -dF disable fast-forward\n"
735
0
    "        -dI enable insecure fork\n"
736
0
    "        -dZ disable zero-copy forwarding\n"
737
#if defined(HA_USE_KTLS)
738
    "        -dT disable kTLS\n"
739
#endif
740
0
    "        -sf/-st [pid ]* finishes/terminates old pids.\n"
741
0
    "        -x <unix_socket> get listening sockets from a unix socket\n"
742
0
    "        -S <bind>[,<bind options>...] new master CLI\n"
743
0
    "\n",
744
0
    name, cfg_maxpconn);
745
0
  exit(1);
746
0
}
747
748
749
750
/*********************************************************************/
751
/*   more specific functions   ***************************************/
752
/*********************************************************************/
753
754
/* sends the signal <sig> to all pids found in <oldpids>. Returns the number of
755
 * pids the signal was correctly delivered to.
756
 */
757
int tell_old_pids(int sig)
758
0
{
759
0
  int p;
760
0
  int ret = 0;
761
0
  for (p = 0; p < nb_oldpids; p++)
762
0
    if (kill(oldpids[p], sig) == 0)
763
0
      ret++;
764
0
  return ret;
765
0
}
766
767
/*
768
 * remove a pid forom the olpid array and decrease nb_oldpids
769
 * return 1 pid was found otherwise return 0
770
 */
771
772
int delete_oldpid(int pid)
773
0
{
774
0
  int i;
775
776
0
  for (i = 0; i < nb_oldpids; i++) {
777
0
    if (oldpids[i] == pid) {
778
0
      oldpids[i] = oldpids[nb_oldpids - 1];
779
0
      oldpids[nb_oldpids - 1] = 0;
780
0
      nb_oldpids--;
781
0
      return 1;
782
0
    }
783
0
  }
784
0
  return 0;
785
0
}
786
787
/*
788
 * Exit with an error message upon a master recovery mode failure.
789
 */
790
static void exit_on_failure()
791
0
{
792
0
  ha_alert("Master encountered an error in recovery mode, exiting.\n");
793
0
}
794
795
796
/*
797
 * upon SIGUSR1, let's have a soft stop. Note that soft_stop() broadcasts
798
 * a signal zero to all subscribers. This means that it's as easy as
799
 * subscribing to signal 0 to get informed about an imminent shutdown.
800
 */
801
static void sig_soft_stop(struct sig_handler *sh)
802
0
{
803
0
  soft_stop();
804
0
  signal_unregister_handler(sh);
805
0
  pool_gc(NULL);
806
0
}
807
808
/*
809
 * upon SIGTTOU, we pause everything
810
 */
811
static void sig_pause(struct sig_handler *sh)
812
0
{
813
0
  if (protocol_pause_all() & ERR_FATAL) {
814
0
    const char *msg = "Some proxies refused to pause, performing soft stop now.\n";
815
0
    ha_warning("%s", msg);
816
0
    send_log(NULL, LOG_WARNING, "%s", msg);
817
0
    soft_stop();
818
0
  }
819
0
  pool_gc(NULL);
820
0
}
821
822
/*
823
 * upon SIGTTIN, let's have a soft stop.
824
 */
825
static void sig_listen(struct sig_handler *sh)
826
0
{
827
0
  if (protocol_resume_all() & ERR_FATAL) {
828
0
    const char *msg = "Some proxies refused to resume, probably due to a conflict on a listening port. You may want to try again after the conflicting application is stopped, otherwise a restart might be needed to resume safe operations.\n";
829
0
    ha_warning("%s", msg);
830
0
    send_log(NULL, LOG_WARNING, "%s", msg);
831
0
  }
832
0
}
833
834
/*
835
 * this function dumps every server's state when the process receives SIGHUP.
836
 */
837
static void sig_dump_state(struct sig_handler *sh)
838
0
{
839
0
  struct proxy *p = proxies_list;
840
841
0
  ha_warning("SIGHUP received, dumping servers states.\n");
842
0
  while (p) {
843
0
    struct server *s = p->srv;
844
845
0
    send_log(p, LOG_NOTICE, "SIGHUP received, dumping servers states for proxy %s.\n", p->id);
846
0
    while (s) {
847
0
      chunk_printf(&trash,
848
0
                   "SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %llu tot.",
849
0
                   p->id, s->id,
850
0
                   (s->cur_state != SRV_ST_STOPPED) ? "UP" : "DOWN",
851
0
                   s->cur_sess, s->queueslength, (ullong)COUNTERS_SHARED_TOTAL(s->counters.shared.tg, cum_sess, HA_ATOMIC_LOAD));
852
0
      ha_warning("%s\n", trash.area);
853
0
      send_log(p, LOG_NOTICE, "%s\n", trash.area);
854
0
      s = s->next;
855
0
    }
856
857
    /* FIXME: those info are a bit outdated. We should be able to distinguish between FE and BE. */
858
0
    if (!p->srv) {
859
0
      chunk_printf(&trash,
860
0
                   "SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %llu+%llu.",
861
0
                   p->id,
862
0
                   p->feconn, p->beconn, p->totpend, p->queueslength, (ullong)COUNTERS_SHARED_TOTAL(p->fe_counters.shared.tg, cum_conn, HA_ATOMIC_LOAD), (ullong)COUNTERS_SHARED_TOTAL(p->be_counters.shared.tg, cum_sess, HA_ATOMIC_LOAD));
863
0
    } else if (p->srv_act == 0) {
864
0
      chunk_printf(&trash,
865
0
                   "SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %llu+%llu.",
866
0
                   p->id,
867
0
                   (p->srv_bck) ? "is running on backup servers" : "has no server available",
868
0
                   p->feconn, p->beconn, p->totpend, p->queueslength, (ullong)COUNTERS_SHARED_TOTAL(p->fe_counters.shared.tg, cum_conn, HA_ATOMIC_LOAD), (ullong)COUNTERS_SHARED_TOTAL(p->be_counters.shared.tg, cum_sess, HA_ATOMIC_LOAD));
869
0
    } else {
870
0
      chunk_printf(&trash,
871
0
                   "SIGHUP: Proxy %s has %d active servers and %d backup servers available."
872
0
                   " Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %llu+%llu.",
873
0
                   p->id, p->srv_act, p->srv_bck,
874
0
                   p->feconn, p->beconn, p->totpend, p->queueslength, (ullong)COUNTERS_SHARED_TOTAL(p->fe_counters.shared.tg, cum_conn, HA_ATOMIC_LOAD), (ullong)COUNTERS_SHARED_TOTAL(p->be_counters.shared.tg, cum_sess, HA_ATOMIC_LOAD));
875
0
    }
876
0
    ha_warning("%s\n", trash.area);
877
0
    send_log(p, LOG_NOTICE, "%s\n", trash.area);
878
879
0
    p = p->next;
880
0
  }
881
0
}
882
883
static void dump(struct sig_handler *sh)
884
0
{
885
  /* free everything possible */
886
0
  pool_gc(NULL);
887
0
}
888
889
/*
890
 *  This function dup2 the stdio FDs (0,1,2) with <fd>, then closes <fd>
891
 *  If <fd> < 0, it opens /dev/null and use it to dup
892
 *
893
 *  In the case of chrooting, you have to open /dev/null before the chroot, and
894
 *  pass the <fd> to this function
895
 */
896
void stdio_quiet(int fd)
897
0
{
898
0
  int close_fd = 0;
899
0
  if (fd < 0) {
900
0
    fd = open("/dev/null", O_RDWR, 0);
901
0
    close_fd = 1;
902
0
  }
903
904
0
  if (fd > -1) {
905
0
    fclose(stdin);
906
0
    fclose(stdout);
907
0
    fclose(stderr);
908
909
0
    dup2(fd, 0);
910
0
    dup2(fd, 1);
911
0
    dup2(fd, 2);
912
0
    if (fd > 2 && close_fd)
913
0
      close(fd);
914
0
    return;
915
0
  }
916
917
0
  ha_alert("Cannot open /dev/null\n");
918
0
  exit(EXIT_FAILURE);
919
0
}
920
921
922
/* This function checks if cfg_cfgfiles contains directories.
923
 * If it finds one, it adds all the files (and only files) it contains
924
 * in cfg_cfgfiles in place of the directory (and removes the directory).
925
 * It adds the files in lexical order.
926
 * It adds only files with .cfg extension.
927
 * It doesn't add files with name starting with '.'
928
 */
929
static void cfgfiles_expand_directories(void)
930
0
{
931
0
  struct cfgfile *cfg, *cfg_tmp;
932
0
  char *err = NULL;
933
934
0
  list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list) {
935
0
    struct stat file_stat;
936
0
    struct dirent **dir_entries = NULL;
937
0
    int dir_entries_nb;
938
0
    int dir_entries_it;
939
940
0
    if (stat(cfg->filename, &file_stat)) {
941
0
      ha_alert("Cannot open configuration file/directory %s : %s\n",
942
0
         cfg->filename,
943
0
         strerror(errno));
944
0
      exit(1);
945
0
    }
946
947
0
    if (!S_ISDIR(file_stat.st_mode))
948
0
      continue;
949
950
    /* from this point cfg->name is a directory */
951
952
0
    dir_entries_nb = scandir(cfg->filename, &dir_entries, NULL, alphasort);
953
0
    if (dir_entries_nb < 0) {
954
0
      ha_alert("Cannot open configuration directory %s : %s\n",
955
0
         cfg->filename,
956
0
         strerror(errno));
957
0
      exit(1);
958
0
    }
959
960
    /* for each element in the directory cfg->name */
961
0
    for (dir_entries_it = 0; dir_entries_it < dir_entries_nb; dir_entries_it++) {
962
0
      struct dirent *dir_entry = dir_entries[dir_entries_it];
963
0
      char *filename = NULL;
964
0
      char *d_name_cfgext = strstr(dir_entry->d_name, ".cfg");
965
966
      /* don't add filename that begin with .
967
       * only add filename with .cfg extension
968
       */
969
0
      if (dir_entry->d_name[0] == '.' ||
970
0
          !(d_name_cfgext && d_name_cfgext[4] == '\0'))
971
0
        goto next_dir_entry;
972
973
0
      if (!memprintf(&filename, "%s/%s", cfg->filename, dir_entry->d_name)) {
974
0
        ha_alert("Cannot load configuration files %s : out of memory.\n",
975
0
           filename);
976
0
        exit(1);
977
0
      }
978
979
0
      if (stat(filename, &file_stat)) {
980
0
        ha_alert("Cannot open configuration file %s : %s\n",
981
0
           cfg->filename,
982
0
           strerror(errno));
983
0
        exit(1);
984
0
      }
985
986
      /* don't add anything else than regular file in cfg_cfgfiles
987
       * this way we avoid loops
988
       */
989
0
      if (!S_ISREG(file_stat.st_mode))
990
0
        goto next_dir_entry;
991
992
0
      if (!list_append_cfgfile(&cfg->list, filename, &err)) {
993
0
        ha_alert("Cannot load configuration files %s : %s\n",
994
0
           filename,
995
0
           err);
996
0
        exit(1);
997
0
      }
998
999
0
next_dir_entry:
1000
0
      free(filename);
1001
0
      free(dir_entry);
1002
0
    }
1003
1004
0
    free(dir_entries);
1005
1006
    /* remove the current directory (cfg) from cfgfiles */
1007
0
    free(cfg->filename);
1008
0
    LIST_DELETE(&cfg->list);
1009
0
    free(cfg);
1010
0
  }
1011
1012
0
  free(err);
1013
0
}
1014
1015
/* Loads config files. Returns -1 and frees allocated memory in env_cfgfiles, if
1016
 * we are run out of memory or load_cfg_in_mem() has failed. load_cfg_in_mem()
1017
 * frees in its stack the memory allocated for config files content, if it has
1018
 * encountered an error.
1019
 */
1020
static int load_cfg()
1021
0
{
1022
0
  struct cfgfile *cfg, *cfg_tmp;
1023
1024
  /* handle cfgfiles that are actually directories */
1025
0
  cfgfiles_expand_directories();
1026
1027
0
  if (LIST_ISEMPTY(&cfg_cfgfiles))
1028
0
    usage(progname);
1029
1030
0
  list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list) {
1031
1032
0
    cfg->size = load_cfg_in_mem(cfg->filename, &cfg->content);
1033
0
    if (cfg->size < 0)
1034
0
      return -1;
1035
1036
0
  }
1037
1038
0
  return 0;
1039
1040
0
}
1041
1042
/* Calls parser for each config file from cfg_cfgfiles list. Returns -1, if we
1043
 * are run out of memory, can't apply default path or when the parser function
1044
 * returns some fatal errors.
1045
 * Otherwise, it returns an err_code, which may contain 0 (OK) or ERR_WARN,
1046
 * ERR_ALERT.
1047
 */
1048
static int read_cfg()
1049
0
{
1050
0
  char *env_cfgfiles = NULL;
1051
0
  struct cfgfile *cfg;
1052
0
  int err_code = 0;
1053
1054
  /* temporary create environment variables with default
1055
   * values to ease user configuration. Do not forget to
1056
   * unset them after the list_for_each_entry loop.
1057
   */
1058
0
  setenv("HAPROXY_HTTP_LOG_FMT", default_http_log_format, 1);
1059
0
  setenv("HAPROXY_HTTP_CLF_LOG_FMT", clf_http_log_format, 1);
1060
0
  setenv("HAPROXY_HTTPS_LOG_FMT", default_https_log_format, 1);
1061
0
  setenv("HAPROXY_TCP_LOG_FMT", default_tcp_log_format, 1);
1062
0
  setenv("HAPROXY_TCP_CLF_LOG_FMT", clf_tcp_log_format, 1);
1063
0
  setenv("HAPROXY_BRANCH", PRODUCT_BRANCH, 1);
1064
0
  list_for_each_entry(cfg, &cfg_cfgfiles, list) {
1065
0
    int ret;
1066
1067
    /* save all successfully loaded conf files in HAPROXY_CFGFILES
1068
     * env var
1069
     */
1070
0
    if (!memprintf(&env_cfgfiles, "%s%s%s",
1071
0
             (env_cfgfiles ? env_cfgfiles : ""),
1072
0
             (env_cfgfiles ? ";" : ""), cfg->filename)) {
1073
      /* free what we've already allocated and free cfglist */
1074
0
      ha_alert("Could not allocate memory for HAPROXY_CFGFILES env variable\n");
1075
0
      goto err;
1076
0
    }
1077
1078
0
    ret = parse_cfg(cfg);
1079
0
    if (ret == -1)
1080
0
      goto err;
1081
1082
0
    if (ret & (ERR_ABORT|ERR_FATAL))
1083
0
      ha_alert("Error(s) found in configuration file : %s\n", cfg->filename);
1084
0
    err_code |= ret;
1085
0
    if (err_code & ERR_ABORT)
1086
0
      goto err;
1087
1088
1089
0
  }
1090
  /* remove temporary environment variables. */
1091
0
  unsetenv("HAPROXY_HTTP_LOG_FMT");
1092
0
  unsetenv("HAPROXY_HTTP_CLF_LOG_FMT");
1093
0
  unsetenv("HAPROXY_HTTPS_LOG_FMT");
1094
0
  unsetenv("HAPROXY_TCP_LOG_FMT");
1095
0
  unsetenv("HAPROXY_TCP_CLF_LOG_FMT");
1096
1097
  /* do not try to resolve arguments nor to spot inconsistencies when
1098
   * the configuration contains fatal errors.
1099
   */
1100
0
  if (err_code & (ERR_ABORT|ERR_FATAL)) {
1101
0
    ha_alert("Fatal errors found in configuration.\n");
1102
0
    goto err;
1103
0
  }
1104
1105
0
  setenv("HAPROXY_CFGFILES", env_cfgfiles, 1);
1106
0
  free(env_cfgfiles);
1107
1108
0
  return err_code;
1109
1110
0
err:
1111
0
  free(env_cfgfiles);
1112
0
  return -1;
1113
0
}
1114
1115
/*
1116
 * copy and cleanup the current argv
1117
 * Remove the -sf /-st / -x parameters
1118
 * Return an allocated copy of argv
1119
 */
1120
1121
static char **copy_argv(int argc, char **argv)
1122
0
{
1123
0
  char **newargv, **retargv;
1124
1125
0
  newargv = calloc(argc + 2, sizeof(*newargv));
1126
0
  if (newargv == NULL) {
1127
0
    ha_warning("Cannot allocate memory\n");
1128
0
    return NULL;
1129
0
  }
1130
0
  retargv = newargv;
1131
1132
  /* first copy argv[0] */
1133
0
  *newargv++ = *argv++;
1134
0
  argc--;
1135
1136
0
  while (argc > 0) {
1137
0
    if (**argv != '-') {
1138
      /* non options are copied but will fail in the argument parser */
1139
0
      *newargv++ = *argv++;
1140
0
      argc--;
1141
1142
0
    } else  {
1143
0
      char *flag;
1144
1145
0
      flag = *argv + 1;
1146
1147
0
      if (flag[0] == '-' && flag[1] == 0) {
1148
        /* "--\0" copy every arguments till the end of argv */
1149
0
        *newargv++ = *argv++;
1150
0
        argc--;
1151
1152
0
        while (argc > 0) {
1153
0
          *newargv++ = *argv++;
1154
0
          argc--;
1155
0
        }
1156
0
      } else {
1157
0
        switch (*flag) {
1158
0
          case 's':
1159
            /* -sf / -st and their parameters are ignored */
1160
0
            if (flag[1] == 'f' || flag[1] == 't') {
1161
0
              argc--;
1162
0
              argv++;
1163
              /* The list can't contain a negative value since the only
1164
              way to know the end of this list is by looking for the
1165
              next option or the end of the options */
1166
0
              while (argc > 0 && argv[0][0] != '-') {
1167
0
                argc--;
1168
0
                argv++;
1169
0
              }
1170
0
            } else {
1171
0
              argc--;
1172
0
              argv++;
1173
1174
0
            }
1175
0
            break;
1176
1177
0
          case 'x':
1178
            /* this option and its parameter are ignored */
1179
0
            argc--;
1180
0
            argv++;
1181
0
            if (argc > 0) {
1182
0
              argc--;
1183
0
              argv++;
1184
0
            }
1185
0
            break;
1186
1187
0
          case 'C':
1188
0
          case 'n':
1189
0
          case 'm':
1190
0
          case 'N':
1191
0
          case 'L':
1192
0
          case 'f':
1193
0
          case 'p':
1194
0
          case 'S':
1195
            /* these options have only 1 parameter which must be copied and can start with a '-' */
1196
0
            *newargv++ = *argv++;
1197
0
            argc--;
1198
0
            if (argc == 0)
1199
0
              goto error;
1200
0
            *newargv++ = *argv++;
1201
0
            argc--;
1202
0
            break;
1203
0
          default:
1204
            /* for other options just copy them without parameters, this is also done
1205
             * for options like "--foo", but this  will fail in the argument parser.
1206
             * */
1207
0
            *newargv++ = *argv++;
1208
0
            argc--;
1209
0
            break;
1210
0
        }
1211
0
      }
1212
0
    }
1213
0
  }
1214
1215
0
  return retargv;
1216
1217
0
error:
1218
0
  free(retargv);
1219
0
  return NULL;
1220
0
}
1221
1222
1223
/* Performs basic random seed initialization. The main issue with this is that
1224
 * srandom_r() only takes 32 bits and purposely provides a reproducible sequence,
1225
 * which means that there will only be 4 billion possible random sequences once
1226
 * srandom() is called, regardless of the internal state. Not calling it is
1227
 * even worse as we'll always produce the same randoms sequences. What we do
1228
 * here is to create an initial sequence from various entropy sources, hash it
1229
 * using SHA1 and keep the resulting 160 bits available globally.
1230
 *
1231
 * We initialize the current process with the first 32 bits before starting the
1232
 * polling loop, where all this will be changed to have process specific and
1233
 * thread specific sequences.
1234
 *
1235
 * Before starting threads, it's still possible to call random() as srandom()
1236
 * is initialized from this, but after threads and/or processes are started,
1237
 * only ha_random() is expected to be used to guarantee distinct sequences.
1238
 */
1239
static void ha_random_boot(char *const *argv)
1240
0
{
1241
0
  unsigned char message[256];
1242
0
  unsigned char *m = message;
1243
0
  struct timeval tv;
1244
0
  blk_SHA_CTX ctx;
1245
0
  unsigned long l;
1246
0
  int fd;
1247
0
  int i;
1248
1249
  /* start with current time as pseudo-random seed */
1250
0
  gettimeofday(&tv, NULL);
1251
0
  write_u32(m, tv.tv_sec);  m += 4;
1252
0
  write_u32(m, tv.tv_usec); m += 4;
1253
1254
  /* PID and PPID add some OS-based randomness */
1255
0
  write_u16(m, getpid());   m += 2;
1256
0
  write_u16(m, getppid());  m += 2;
1257
1258
  /* take up to 160 bits bytes from /dev/urandom if available (non-blocking) */
1259
0
  fd = open("/dev/urandom", O_RDONLY);
1260
0
  if (fd >= 0) {
1261
0
    i = read(fd, m, 20);
1262
0
    if (i > 0)
1263
0
      m += i;
1264
0
    close(fd);
1265
0
  }
1266
1267
  /* take up to 160 bits bytes from openssl (non-blocking) */
1268
#ifdef USE_OPENSSL
1269
  if (RAND_bytes(m, 20) == 1)
1270
    m += 20;
1271
#endif
1272
1273
  /* take 160 bits from existing random in case it was already initialized */
1274
0
  for (i = 0; i < 5; i++) {
1275
0
    write_u32(m, random());
1276
0
    m += 4;
1277
0
  }
1278
1279
  /* stack address (benefit from operating system's ASLR) */
1280
0
  l = (unsigned long)&m;
1281
0
  memcpy(m, &l, sizeof(l)); m += sizeof(l);
1282
1283
  /* argv address (benefit from operating system's ASLR) */
1284
0
  l = (unsigned long)&argv;
1285
0
  memcpy(m, &l, sizeof(l)); m += sizeof(l);
1286
1287
  /* use tv_usec again after all the operations above */
1288
0
  gettimeofday(&tv, NULL);
1289
0
  write_u32(m, tv.tv_usec); m += 4;
1290
1291
  /*
1292
   * At this point, ~84-92 bytes have been used
1293
   */
1294
1295
  /* finish with the hostname */
1296
0
  strncpy((char *)m, hostname, message + sizeof(message) - m);
1297
0
  m += strlen(hostname);
1298
1299
  /* total message length */
1300
0
  l = m - message;
1301
1302
0
  memset(&ctx, 0, sizeof(ctx));
1303
0
  blk_SHA1_Init(&ctx);
1304
0
  blk_SHA1_Update(&ctx, message, l);
1305
0
  blk_SHA1_Final(boot_seed, &ctx);
1306
1307
0
  srandom(read_u32(boot_seed));
1308
0
  ha_random_seed(boot_seed, sizeof(boot_seed));
1309
0
}
1310
1311
1312
/* Evaluates a condition provided within a conditional block of the
1313
 * configuration. Makes process to exit with 0, if the condition is true, with
1314
 * 1, if the condition is false or with 2, if parse_line encounters an error.
1315
 */
1316
static void do_check_condition()
1317
0
{
1318
0
  int result;
1319
0
  uint32_t err;
1320
0
  const char *errptr;
1321
0
  char *errmsg = NULL;
1322
1323
0
  char *args[MAX_LINE_ARGS+1];
1324
0
  int arg = sizeof(args) / sizeof(*args);
1325
0
  size_t outlen;
1326
0
  char *w;
1327
1328
0
  if (!check_condition)
1329
0
    usage(progname);
1330
1331
0
  outlen = strlen(check_condition) + 1;
1332
0
  err = parse_line(check_condition, check_condition, &outlen, args, &arg,
1333
0
                         PARSE_OPT_ENV | PARSE_OPT_WORD_EXPAND | PARSE_OPT_DQUOTE | PARSE_OPT_SQUOTE | PARSE_OPT_BKSLASH,
1334
0
                         &errptr);
1335
1336
0
  if (err & PARSE_ERR_QUOTE) {
1337
0
    ha_alert("Syntax Error in condition: Unmatched quote.\n");
1338
0
    exit(2);
1339
0
  }
1340
1341
0
  if (err & PARSE_ERR_HEX) {
1342
0
    ha_alert("Syntax Error in condition: Truncated or invalid hexadecimal sequence.\n");
1343
0
    exit(2);
1344
0
  }
1345
1346
0
  if (err & (PARSE_ERR_TOOLARGE|PARSE_ERR_OVERLAP)) {
1347
0
    ha_alert("Error in condition: Line too long.\n");
1348
0
    exit(2);
1349
0
  }
1350
1351
0
  if (err & PARSE_ERR_TOOMANY) {
1352
0
    ha_alert("Error in condition: Too many words.\n");
1353
0
    exit(2);
1354
0
  }
1355
1356
0
  if (err) {
1357
0
    ha_alert("Unhandled error in condition, please report this to the developers.\n");
1358
0
    exit(2);
1359
0
  }
1360
1361
  /* remerge all words into a single expression */
1362
0
  for (w = *args; (w += strlen(w)) < check_condition + outlen - 1; *w = ' ')
1363
0
    ;
1364
1365
0
  result = cfg_eval_condition(args, &errmsg, &errptr);
1366
1367
0
  if (result < 0) {
1368
0
    if (errmsg)
1369
0
      ha_alert("Failed to evaluate condition: %s\n", errmsg);
1370
1371
0
    exit(2);
1372
0
  }
1373
1374
0
  exit(result ? 0 : 1);
1375
0
}
1376
1377
/* This performs th every basic early initialization at the end of the PREPARE
1378
 * init stage. It may only assume that list heads are initialized, but not that
1379
 * anything else is correct. It will initialize a number of variables that
1380
 * depend on command line and will pre-parse the command line. If it fails, it
1381
 * directly exits.
1382
 */
1383
static void init_early(int argc, char **argv)
1384
0
{
1385
0
  char *tmp;
1386
0
  int len;
1387
1388
0
  setenv("HAPROXY_STARTUP_VERSION", haproxy_version, 0);
1389
1390
  /* First, let's initialize most global variables */
1391
0
  totalconn = actconn = listeners = stopping = 0;
1392
0
  killed = pid = 0;
1393
1394
  /* cast to one byte in order to fill better a 3 bytes hole in the global struct,
1395
   * we hopefully will never start with > than 255 args
1396
   */
1397
0
  global.argc = (unsigned char)argc;
1398
0
  global.argv = argv;
1399
0
  global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
1400
0
  global.rlimit_memmax_all = HAPROXY_MEMMAX;
1401
0
  global.mode = MODE_STARTING;
1402
1403
  /* if we were in mworker mode, we should restart in mworker mode */
1404
0
  if (getenv("HAPROXY_MWORKER_REEXEC") != NULL)
1405
0
    global.mode |= MODE_MWORKER;
1406
1407
  /* initialize date, time, and pid */
1408
0
  tzset();
1409
0
  clock_init_process_date();
1410
0
  start_date = date;
1411
0
  start_time_ns = now_ns;
1412
0
  pid = getpid();
1413
1414
  /* Set local host name and adjust some environment variables.
1415
   * NB: POSIX does not make it mandatory for gethostname() to
1416
   * NULL-terminate the string in case of truncation, and at least
1417
   * FreeBSD appears not to do it.
1418
   */
1419
0
  memset(hostname, 0, sizeof(hostname));
1420
0
  gethostname(hostname, sizeof(hostname) - 1);
1421
1422
0
  localpeer = strdup(hostname);
1423
0
  if (!localpeer) {
1424
0
    ha_alert("Cannot allocate memory for local peer.\n");
1425
0
    exit(EXIT_FAILURE);
1426
0
  }
1427
1428
  /* extract the program name from argv[0], it will be used for the logs
1429
   * and error messages.
1430
   */
1431
0
  progname = *argv;
1432
0
  while ((tmp = strchr(progname, '/')) != NULL)
1433
0
    progname = tmp + 1;
1434
1435
0
  len = strlen(progname);
1436
0
  progname = strdup(progname);
1437
0
  if (!progname) {
1438
0
    ha_alert("Cannot allocate memory for log_tag.\n");
1439
0
    exit(EXIT_FAILURE);
1440
0
  }
1441
1442
0
  chunk_initlen(&global.log_tag, strdup(progname), len, len);
1443
0
}
1444
1445
/* handles program arguments. Very minimal parsing is performed, variables are
1446
 * fed with some values, and lists are completed with other ones. In case of
1447
 * error, it will exit.
1448
 */
1449
static void init_args(int argc, char **argv)
1450
0
{
1451
0
  char *err_msg = NULL;
1452
1453
  /* pre-fill in the global tuning options before we let the cmdline
1454
   * change them.
1455
   */
1456
0
  global.tune.options |= GTUNE_USE_SELECT;  /* select() is always available */
1457
0
#if defined(USE_POLL)
1458
0
  global.tune.options |= GTUNE_USE_POLL;
1459
0
#endif
1460
#if defined(USE_EPOLL)
1461
  global.tune.options |= GTUNE_USE_EPOLL;
1462
#endif
1463
#if defined(USE_KQUEUE)
1464
  global.tune.options |= GTUNE_USE_KQUEUE;
1465
#endif
1466
#if defined(USE_EVPORTS)
1467
  global.tune.options |= GTUNE_USE_EVPORTS;
1468
#endif
1469
#if defined(USE_LINUX_SPLICE)
1470
  global.tune.options |= GTUNE_USE_SPLICE;
1471
#endif
1472
#if defined(USE_GETADDRINFO)
1473
  global.tune.options |= GTUNE_USE_GAI;
1474
#endif
1475
#ifdef USE_THREAD
1476
  global.tune.options |= GTUNE_IDLE_POOL_SHARED;
1477
#endif
1478
0
  global.tune.options |= GTUNE_STRICT_LIMITS;
1479
1480
0
  global.tune.options |= GTUNE_USE_FAST_FWD; /* Use fast-forward by default */
1481
1482
  /* Use zero-copy forwarding by default */
1483
0
  global.tune.no_zero_copy_fwd = 0;
1484
1485
  /* keep a copy of original arguments for the master process */
1486
0
  old_argv = copy_argv(argc, argv);
1487
0
  if (!old_argv) {
1488
0
    ha_alert("failed to copy argv.\n");
1489
0
    exit(EXIT_FAILURE);
1490
0
  }
1491
1492
  /* skip program name and start */
1493
0
  argc--; argv++;
1494
0
  while (argc > 0) {
1495
0
    char *flag;
1496
1497
0
    if (**argv == '-') {
1498
0
      flag = *argv+1;
1499
1500
      /* 1 arg */
1501
0
      if (*flag == 'v') {
1502
0
        if (flag[1] == 'q' && flag[2] == 's' && flag[3] == '\0') {
1503
0
          display_version_plain(0);  // -vqs
1504
0
          deinit_and_exit(0);
1505
0
        }
1506
0
        else if (flag[1] == 'q' && flag[2] == 'b' && flag[3] == '\0') {
1507
0
          display_version_plain(2);  // -vqb
1508
0
          deinit_and_exit(0);
1509
0
        }
1510
0
        else if (flag[1] == 'q' && flag[2] == '\0') {
1511
0
          display_version_plain(1);  // -vq
1512
0
          deinit_and_exit(0);
1513
0
        }
1514
0
        else {
1515
0
          display_version();
1516
0
          if (flag[1] == 'v')  // -vv
1517
0
            display_build_opts();
1518
0
          deinit_and_exit(0);
1519
0
        }
1520
0
      }
1521
#if defined(USE_EPOLL)
1522
      else if (*flag == 'd' && flag[1] == 'e')
1523
        global.tune.options &= ~GTUNE_USE_EPOLL;
1524
#endif
1525
0
#if defined(USE_POLL)
1526
0
      else if (*flag == 'd' && flag[1] == 'p')
1527
0
        global.tune.options &= ~GTUNE_USE_POLL;
1528
0
#endif
1529
#if defined(USE_KQUEUE)
1530
      else if (*flag == 'd' && flag[1] == 'k')
1531
        global.tune.options &= ~GTUNE_USE_KQUEUE;
1532
#endif
1533
#if defined(USE_EVPORTS)
1534
      else if (*flag == 'd' && flag[1] == 'v')
1535
        global.tune.options &= ~GTUNE_USE_EVPORTS;
1536
#endif
1537
#if defined(USE_LINUX_SPLICE)
1538
      else if (*flag == 'd' && flag[1] == 'S')
1539
        global.tune.options &= ~GTUNE_USE_SPLICE;
1540
#endif
1541
#if defined(USE_GETADDRINFO)
1542
      else if (*flag == 'd' && flag[1] == 'G')
1543
        global.tune.options &= ~GTUNE_USE_GAI;
1544
#endif
1545
0
#if defined(SO_REUSEPORT)
1546
0
      else if (*flag == 'd' && flag[1] == 'R')
1547
0
        protocol_clrf_all(PROTO_F_REUSEPORT_SUPPORTED);
1548
0
#endif
1549
#if defined(USE_CPU_AFFINITY)
1550
      else if (*flag == 'd' && flag[1] == 'c')
1551
        global.tune.debug |= GDBG_CPU_AFFINITY;
1552
#endif
1553
0
      else if (*flag == 'd' && flag[1] == 'F')
1554
0
        global.tune.options &= ~GTUNE_USE_FAST_FWD;
1555
0
      else if (*flag == 'd' && flag[1] == 'I')
1556
0
        global.tune.options |= GTUNE_INSECURE_FORK;
1557
0
      else if (*flag == 'd' && flag[1] == 'V')
1558
0
        global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
1559
0
      else if (*flag == 'd' && flag[1] == 'Z')
1560
0
        global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD;
1561
0
      else if (*flag == 'V')
1562
0
        arg_mode |= MODE_VERBOSE;
1563
0
      else if (*flag == 'd' && flag[1] == 'C') {
1564
0
        char *end;
1565
0
        char *key;
1566
1567
0
        key = flag + 2;
1568
0
        for (;key && *key; key = end) {
1569
0
          end = strchr(key, ',');
1570
0
          if (end)
1571
0
            *(end++) = 0;
1572
1573
0
          if (strcmp(key, "line") == 0)
1574
0
            arg_mode |= MODE_DUMP_NB_L;
1575
1576
0
        }
1577
0
        arg_mode |= MODE_DUMP_CFG;
1578
0
        HA_ATOMIC_STORE(&global.anon_key, atoll(flag + 2));
1579
0
      }
1580
0
      else if (*flag == 'd' && flag[1] == 'b')
1581
0
        arg_mode |= MODE_FOREGROUND;
1582
0
      else if (*flag == 'd' && flag[1] == 'D')
1583
0
        arg_mode |= MODE_DIAG;
1584
0
      else if (*flag == 'd' && flag[1] == 'W')
1585
0
        arg_mode |= MODE_ZERO_WARNING;
1586
0
      else if (*flag == 'd' && flag[1] == 'M') {
1587
0
        int ret = pool_parse_debugging(flag + 2, &err_msg);
1588
1589
0
        if (ret <= -1) {
1590
0
          if (ret < -1)
1591
0
            ha_alert("-dM: %s\n", err_msg);
1592
0
          else
1593
0
            printf("%s\n", err_msg);
1594
0
          ha_free(&err_msg);
1595
0
          exit(ret < -1 ? EXIT_FAILURE : 0);
1596
0
        } else if (ret == 0) {
1597
0
          ha_warning("-dM: %s\n", err_msg);
1598
0
          ha_free(&err_msg);
1599
0
        }
1600
0
      }
1601
0
      else if (*flag == 'd' && flag[1] == 'r')
1602
0
        global.tune.options |= GTUNE_RESOLVE_DONTFAIL;
1603
#if defined(HA_HAVE_DUMP_LIBS)
1604
      else if (*flag == 'd' && flag[1] == 'L')
1605
        arg_mode |= MODE_DUMP_LIBS;
1606
#endif
1607
0
      else if (*flag == 'd' && flag[1] == 'K') {
1608
0
        arg_mode |= MODE_DUMP_KWD;
1609
0
        kwd_dump = flag + 2;
1610
0
      }
1611
0
      else if (*flag == 'd' && flag[1] == 't') {
1612
0
        char *arg = flag + 2;
1613
0
        int ret;
1614
1615
0
        if (!*arg && argc > 1 && argv[1][0] != '-') {
1616
0
          arg = argv[1];
1617
0
          argc--; argv++;
1618
0
        }
1619
1620
0
        ret = trace_parse_cmd(arg, &err_msg);
1621
0
        if (ret <= -1) {
1622
0
          if (ret < -1) {
1623
0
            ha_alert("-dt: %s.\n", err_msg);
1624
0
            ha_free(&err_msg);
1625
0
            exit(EXIT_FAILURE);
1626
0
          }
1627
0
          else {
1628
0
            printf("%s\n", err_msg);
1629
0
            ha_free(&err_msg);
1630
0
            exit(0);
1631
0
          }
1632
0
        }
1633
0
      }
1634
#ifdef HA_USE_KTLS
1635
      else if (*flag == 'd' && flag[1] == 'T') {
1636
        global.tune.options |= GTUNE_NO_KTLS;
1637
      }
1638
#endif
1639
0
      else if (*flag == 'd')
1640
0
        arg_mode |= MODE_DEBUG;
1641
0
      else if (*flag == 'c' && flag[1] == 'c') {
1642
0
        arg_mode |= MODE_CHECK_CONDITION;
1643
0
        argv++;
1644
0
        argc--;
1645
0
        check_condition = *argv;
1646
0
      }
1647
0
      else if (*flag == '4')
1648
0
        resolv_accept_families = RSLV_ACCEPT_IPV4 | RSLV_FORCED_FAMILY;
1649
0
      else if (*flag == 'c')
1650
0
        arg_mode |= MODE_CHECK;
1651
0
      else if (*flag == 'D')
1652
0
        arg_mode |= MODE_DAEMON;
1653
0
      else if (*flag == 'W' && flag[1] == 's') {
1654
0
        arg_mode |= MODE_MWORKER | MODE_FOREGROUND;
1655
0
        global.tune.options |= GTUNE_USE_SYSTEMD;
1656
0
      }
1657
0
      else if (*flag == 'W')
1658
0
        arg_mode |= MODE_MWORKER;
1659
0
      else if (*flag == 'q')
1660
0
        arg_mode |= MODE_QUIET;
1661
0
      else if (*flag == 'x') {
1662
0
        if (argc <= 1) {
1663
0
          ha_alert("Unix socket path expected with the -x flag\n\n");
1664
0
          usage(progname);
1665
0
        }
1666
0
        if (old_unixsocket)
1667
0
          ha_warning("-x option already set, overwriting the value\n");
1668
0
        old_unixsocket = argv[1];
1669
1670
0
        argv++;
1671
0
        argc--;
1672
0
      }
1673
0
      else if (*flag == 'S') {
1674
0
        struct wordlist *c;
1675
1676
0
        if (argc <= 1) {
1677
0
          ha_alert("Socket and optional bind parameters expected with the -S flag\n");
1678
0
          usage(progname);
1679
0
        }
1680
0
        if ((c = malloc(sizeof(*c))) == NULL || (c->s = strdup(argv[1])) == NULL) {
1681
0
          ha_alert("Cannot allocate memory\n");
1682
0
          exit(EXIT_FAILURE);
1683
0
        }
1684
0
        LIST_INSERT(&mworker_cli_conf, &c->list);
1685
1686
0
        argv++;
1687
0
        argc--;
1688
0
      }
1689
0
      else if (*flag == 's' && (flag[1] == 'f' || flag[1] == 't')) {
1690
        /* list of pids to finish ('f') or terminate ('t') */
1691
1692
0
        if (flag[1] == 'f')
1693
0
          oldpids_sig = SIGUSR1; /* finish then exit */
1694
0
        else
1695
0
          oldpids_sig = SIGTERM; /* terminate immediately */
1696
0
        while (argc > 1 && argv[1][0] != '-') {
1697
0
          char * endptr = NULL;
1698
0
          oldpids = realloc(oldpids, (nb_oldpids + 1) * sizeof(int));
1699
0
          if (!oldpids) {
1700
0
            ha_alert("Cannot allocate old pid : out of memory.\n");
1701
0
            exit(1);
1702
0
          }
1703
0
          argc--; argv++;
1704
0
          errno = 0;
1705
0
          oldpids[nb_oldpids] = strtol(*argv, &endptr, 10);
1706
0
          if (errno) {
1707
0
            ha_alert("-%2s option: failed to parse {%s}: %s\n",
1708
0
               flag,
1709
0
               *argv, strerror(errno));
1710
0
            exit(1);
1711
0
          } else if (endptr && strlen(endptr)) {
1712
0
            while (isspace((unsigned char)*endptr)) endptr++;
1713
0
            if (*endptr != 0) {
1714
0
              ha_alert("-%2s option: some bytes unconsumed in PID list {%s}\n",
1715
0
                 flag, endptr);
1716
0
              exit(1);
1717
0
            }
1718
0
          }
1719
0
          if (oldpids[nb_oldpids] <= 0)
1720
0
            usage(progname);
1721
0
          nb_oldpids++;
1722
0
        }
1723
0
      }
1724
#ifdef DEBUG_UNIT
1725
      else if (*flag == 'U')  {
1726
        if (argc <= 1) {
1727
          ha_alert("-U takes a least a unittest name in argument, and must be the last option\n");
1728
          usage(progname);
1729
        }
1730
        /* this is the last option, we keep the option position */
1731
        argv++;
1732
        argc--;
1733
        unittest_argc = argc;
1734
        break;
1735
      }
1736
#endif
1737
0
      else if (flag[0] == '-' && flag[1] == 0) { /* "--" */
1738
        /* now that's a cfgfile list */
1739
0
        argv++; argc--;
1740
0
        while (argc > 0) {
1741
0
          if (!list_append_cfgfile(&cfg_cfgfiles, *argv, &err_msg)) {
1742
0
            ha_alert("Cannot load configuration file/directory %s : %s\n",
1743
0
               *argv,
1744
0
               err_msg);
1745
0
            exit(1);
1746
0
          }
1747
0
          argv++; argc--;
1748
0
        }
1749
0
        break;
1750
0
      }
1751
0
      else { /* >=2 args */
1752
0
        argv++; argc--;
1753
0
        if (argc == 0)
1754
0
          usage(progname);
1755
1756
0
        switch (*flag) {
1757
0
        case 'C' : change_dir = *argv; break;
1758
0
        case 'n' : cfg_maxconn = atol(*argv); break;
1759
0
        case 'm' : global.rlimit_memmax_all = atol(*argv); break;
1760
0
        case 'N' : cfg_maxpconn = atol(*argv); break;
1761
0
        case 'L' :
1762
0
          free(localpeer);
1763
0
          if ((localpeer = strdup(*argv)) == NULL) {
1764
0
            ha_alert("Cannot allocate memory for local peer.\n");
1765
0
            exit(EXIT_FAILURE);
1766
0
          }
1767
0
          global.localpeer_cmdline = 1;
1768
0
          break;
1769
0
        case 'f' :
1770
0
          if (!list_append_cfgfile(&cfg_cfgfiles, *argv, &err_msg)) {
1771
0
            ha_alert("Cannot load configuration file/directory %s : %s\n",
1772
0
               *argv,
1773
0
               err_msg);
1774
0
            exit(1);
1775
0
          }
1776
0
          break;
1777
0
        case 'p' :
1778
0
          free(global.pidfile);
1779
0
          if ((global.pidfile = strdup(*argv)) == NULL) {
1780
0
            ha_alert("Cannot allocate memory for pidfile.\n");
1781
0
            exit(EXIT_FAILURE);
1782
0
          }
1783
0
          break;
1784
0
        default: usage(progname);
1785
0
        }
1786
0
      }
1787
0
    }
1788
0
    else
1789
0
      usage(progname);
1790
0
    argv++; argc--;
1791
0
  }
1792
0
  free(err_msg);
1793
0
}
1794
1795
/* call the various keyword dump functions based on the comma-delimited list of
1796
 * classes in kwd_dump.
1797
 */
1798
static void dump_registered_keywords(void)
1799
0
{
1800
0
  char *end;
1801
0
  int all __maybe_unused = 0;
1802
1803
0
  for (; kwd_dump && *kwd_dump; kwd_dump = end) {
1804
0
    end = strchr(kwd_dump, ',');
1805
0
    if (end)
1806
0
      *(end++) = 0;
1807
1808
0
    if (strcmp(kwd_dump, "help") == 0) {
1809
0
      printf("# List of supported keyword classes:\n");
1810
0
      printf("all: list all keywords\n");
1811
0
      printf("acl: ACL keywords\n");
1812
0
      printf("cfg: configuration keywords\n");
1813
0
      printf("cli: CLI keywords\n");
1814
0
      printf("cnv: sample converter keywords\n");
1815
0
      printf("flt: filter names\n");
1816
0
      printf("smp: sample fetch functions\n");
1817
0
      printf("svc: service names\n");
1818
0
      continue;
1819
0
    }
1820
0
    else if (strcmp(kwd_dump, "all") == 0) {
1821
0
      all = 1;
1822
0
    }
1823
1824
0
    if (all || strcmp(kwd_dump, "acl") == 0) {
1825
0
      printf("# List of registered ACL keywords:\n");
1826
0
      acl_dump_kwd();
1827
0
    }
1828
1829
0
    if (all || strcmp(kwd_dump, "cfg") == 0) {
1830
0
      printf("# List of registered configuration keywords:\n");
1831
0
      cfg_dump_registered_keywords();
1832
0
    }
1833
1834
0
    if (all || strcmp(kwd_dump, "cli") == 0) {
1835
0
      printf("# List of registered CLI keywords:\n");
1836
0
      cli_list_keywords();
1837
0
    }
1838
1839
0
    if (all || strcmp(kwd_dump, "cnv") == 0) {
1840
0
      printf("# List of registered sample converter functions:\n");
1841
0
      smp_dump_conv_kw();
1842
0
    }
1843
1844
0
    if (all || strcmp(kwd_dump, "flt") == 0) {
1845
0
      printf("# List of registered filter names:\n");
1846
0
      flt_dump_kws(NULL);
1847
0
    }
1848
1849
0
    if (all || strcmp(kwd_dump, "smp") == 0) {
1850
0
      printf("# List of registered sample fetch functions:\n");
1851
0
      smp_dump_fetch_kw();
1852
0
    }
1853
1854
0
    if (all || strcmp(kwd_dump, "svc") == 0) {
1855
0
      printf("# List of registered service names:\n");
1856
0
      list_services(NULL);
1857
0
    }
1858
0
  }
1859
0
}
1860
1861
/* Generate a random cluster-secret in case the setting is not provided in the
1862
 * configuration. This allows to use features which rely on it albeit with some
1863
 * limitations.
1864
 */
1865
static void generate_random_cluster_secret()
1866
0
{
1867
  /* used as a default random cluster-secret if none defined. */
1868
0
  uint64_t rand;
1869
1870
  /* The caller must not overwrite an already defined secret. */
1871
0
  BUG_ON(cluster_secret_isset);
1872
1873
0
  rand = ha_random64();
1874
0
  memcpy(global.cluster_secret, &rand, sizeof(rand));
1875
0
  rand = ha_random64();
1876
0
  memcpy(global.cluster_secret + sizeof(rand), &rand, sizeof(rand));
1877
0
  cluster_secret_isset = 1;
1878
0
}
1879
1880
/*
1881
 * This function does daemonization fork. It only returns if everything is OK.
1882
 * If something fails, it exits.
1883
 */
1884
static void apply_daemon_mode()
1885
0
{
1886
0
  int ret;
1887
0
  int wstatus = 0;
1888
0
  int exitcode = 0;
1889
0
  pid_t child_pid;
1890
0
  char buf[2];
1891
1892
0
  if (pipe(daemon_fd) < 0) {
1893
0
    ha_alert("[%s.main()] Cannot create pipe for getting the status of "
1894
0
       "child process: %s.\n", progname, strerror(errno));
1895
1896
0
    exit(EXIT_FAILURE);
1897
0
  }
1898
1899
0
  ret = fork();
1900
0
  switch(ret) {
1901
0
  case -1:
1902
0
    ha_alert("[%s.main()] Cannot fork.\n", progname);
1903
0
    protocol_unbind_all();
1904
0
    exit(1); /* there has been an error */
1905
0
  case 0:
1906
    /* in child, change the process group ID, in the master-worker
1907
     * mode, this will be the master process
1908
     */
1909
0
    close(daemon_fd[0]);
1910
0
    daemon_fd[0] = -1;
1911
0
    setsid();
1912
1913
0
    break;
1914
0
  default:
1915
    /* in parent */
1916
0
    close(daemon_fd[1]);
1917
0
    daemon_fd[1] = -1;
1918
    /* In standalone + daemon modes: parent (launcher process) tries
1919
     * to read the child's (daemonized process) "READY" message. Child
1920
     * writes this message, when he has finished initialization. If
1921
     * child failed to start, we get his status.
1922
     * In master-worker mode: daemonized process is the master. He
1923
     * sends his READY message to launcher, only when
1924
     * he has received the READY message from the worker, see
1925
     * _send_status().
1926
     */
1927
0
    if (read(daemon_fd[0], buf, 1) == 0) {
1928
0
      child_pid = waitpid(ret, &wstatus, 0);
1929
0
      if (child_pid < 0) {
1930
0
        ha_alert("[%s.main()] waitpid() failed: %s\n",
1931
0
           progname, strerror(errno));
1932
0
        exit(EXIT_FAILURE);
1933
0
      }
1934
0
      if (WIFEXITED(wstatus))
1935
0
        wstatus = WEXITSTATUS(wstatus);
1936
0
      else if (WIFSIGNALED(wstatus))
1937
0
        wstatus = 128 + WTERMSIG(wstatus);
1938
0
      else
1939
0
        wstatus = 255;
1940
1941
0
      ha_alert("Process %d exited with code %d (%s)\n",
1942
0
         child_pid, wstatus, (wstatus >= 128) ? strsignal(wstatus - 128) : "Exit");
1943
0
      if (wstatus != 0 && wstatus != 143)
1944
0
        exitcode = wstatus;
1945
0
    }
1946
0
    exit(exitcode);
1947
0
  }
1948
0
}
1949
1950
/* Returns 0, if everything is OK. If open() fails, returns -1. */
1951
int handle_pidfile(void)
1952
0
{
1953
0
  char pidstr[100];
1954
1955
0
  unlink(global.pidfile);
1956
0
  pidfd = open(global.pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
1957
0
  if (pidfd < 0) {
1958
0
    ha_alert("[%s.main()] Cannot create pidfile %s\n", progname, global.pidfile);
1959
0
    return -1;
1960
0
  }
1961
0
  snprintf(pidstr, sizeof(pidstr), "%d\n", (int)getpid());
1962
0
  DISGUISE(write(pidfd, pidstr, strlen(pidstr)));
1963
0
  close(pidfd);
1964
  /* We won't ever use this anymore */
1965
0
  ha_free(&global.pidfile);
1966
1967
0
  return 0;
1968
0
}
1969
1970
static void get_listeners_fd()
1971
0
{
1972
  /* Try to get the listeners FD from the previous process using
1973
   * _getsocks on the stat socket, it must never been done in wait mode
1974
   * and check mode
1975
   */
1976
1977
0
  if (strcmp("/dev/null", old_unixsocket) != 0) {
1978
0
    if (sock_get_old_sockets(old_unixsocket) != 0) {
1979
0
      ha_alert("Failed to get the sockets from the old process!\n");
1980
0
      if (!(global.mode & MODE_MWORKER))
1981
0
        exit(1);
1982
0
    }
1983
0
  }
1984
0
}
1985
1986
static void bind_listeners()
1987
0
{
1988
0
  int err, retry;
1989
1990
  /* We will loop at most 100 times with 10 ms delay each time.
1991
   * That's at most 1 second. We only send a signal to old pids
1992
   * if we cannot grab at least one port.
1993
   */
1994
0
  retry = MAX_START_RETRIES;
1995
0
  err = ERR_NONE;
1996
0
  while (retry >= 0) {
1997
0
    struct timeval w;
1998
0
    err = protocol_bind_all(retry == 0 || nb_oldpids == 0);
1999
    /* exit the loop on no error or fatal error */
2000
0
    if ((err & (ERR_RETRYABLE|ERR_FATAL)) != ERR_RETRYABLE)
2001
0
      break;
2002
0
    if (nb_oldpids == 0 || retry == 0)
2003
0
      break;
2004
2005
    /* FIXME-20060514: Solaris and OpenBSD do not support shutdown() on
2006
     * listening sockets. So on those platforms, it would be wiser to
2007
     * simply send SIGUSR1, which will not be undoable.
2008
     */
2009
0
    if (tell_old_pids(SIGTTOU) == 0) {
2010
      /* no need to wait if we can't contact old pids */
2011
0
      retry = 0;
2012
0
      continue;
2013
0
    }
2014
    /* give some time to old processes to stop listening */
2015
0
    w.tv_sec = 0;
2016
0
    w.tv_usec = 10*1000;
2017
0
    select(0, NULL, NULL, NULL, &w);
2018
0
    retry--;
2019
0
  }
2020
  /* Note: protocol_bind_all() sends an alert when it fails. */
2021
0
  if ((err & ~ERR_WARN) != ERR_NONE) {
2022
0
    ha_alert("[%s.main()] Some protocols failed to start their listeners! Exiting.\n", progname);
2023
0
    if (retry != MAX_START_RETRIES && nb_oldpids)
2024
0
      tell_old_pids(SIGTTIN);
2025
0
    protocol_unbind_all(); /* cleanup everything we can */
2026
0
    exit(1);
2027
0
  }
2028
0
}
2029
2030
/*
2031
 * This function does some initialization steps, which are better to perform
2032
 * before config parsing. It only returns if everything is OK. If something
2033
 * fails, it exits.
2034
 */
2035
static void step_init_1()
2036
0
{
2037
#ifdef USE_OPENSSL
2038
#ifdef USE_OPENSSL_WOLFSSL
2039
        wolfSSL_Init();
2040
        wolfSSL_Debugging_ON();
2041
#endif
2042
2043
#ifdef OPENSSL_IS_AWSLC
2044
        const char *version_str = OpenSSL_version(OPENSSL_VERSION);
2045
        if (strncmp(version_str, "AWS-LC", 6) != 0) {
2046
            ha_alert("HAPRoxy built with AWS-LC but running with %s.\n", version_str);
2047
        exit(1);
2048
        }
2049
#endif
2050
2051
#if (HA_OPENSSL_VERSION_NUMBER < 0x1010000fL)
2052
  /* Initialize the error strings of OpenSSL
2053
   * It only needs to be done explicitly with older versions of the SSL
2054
   * library. On newer versions, errors strings are loaded during start
2055
   * up. */
2056
  SSL_load_error_strings();
2057
#endif
2058
#endif /* USE_OPENSSL */
2059
2060
  /* saves ptr to ring in startup_logs var */
2061
0
  startup_logs_init();
2062
2063
0
  if (init_acl() != 0)
2064
0
    exit(1);
2065
2066
  /* Initialise lua. */
2067
0
  hlua_init();
2068
2069
  /* set modes given from cmdline */
2070
0
  global.mode |= (arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE
2071
0
            | MODE_QUIET | MODE_CHECK | MODE_DEBUG | MODE_ZERO_WARNING
2072
0
            | MODE_DIAG | MODE_CHECK_CONDITION | MODE_DUMP_LIBS | MODE_DUMP_KWD
2073
0
            | MODE_DUMP_CFG | MODE_DUMP_NB_L));
2074
2075
  /* Do check_condition, if we started with -cc, and exit. */
2076
0
  if (global.mode & MODE_CHECK_CONDITION)
2077
0
    do_check_condition();
2078
2079
0
  if (change_dir && chdir(change_dir) < 0) {
2080
0
    ha_alert("Could not change to directory %s : %s\n", change_dir, strerror(errno));
2081
0
    exit(1);
2082
0
  }
2083
0
}
2084
2085
/*
2086
 * This is a second part of the late init (previous init() function). It should
2087
 * be called after the stage, when all basic runtime modes (daemon, master-worker)
2088
 * are already applied. It calls routines from pre_check_list and also functions,
2089
 * which allocate pools, initialize proxies, compute ideal maxconn, it also
2090
 * initializes postmortem structure at the end. It only returns if everything is
2091
 * OK. If something fails, it exits.
2092
 */
2093
static void step_init_2(int argc, char** argv)
2094
0
{
2095
0
  int err_code = 0;
2096
0
  struct proxy *px;
2097
0
  struct post_check_fct *pcf;
2098
0
  struct pre_check_fct *prcf;
2099
0
  const char *cc, *cflags, *opts;
2100
2101
  /* destroy unreferenced defaults proxies  */
2102
0
  proxy_destroy_all_unref_defaults();
2103
2104
0
  list_for_each_entry(prcf, &pre_check_list, list) {
2105
0
    err_code |= prcf->fct();
2106
0
    if (err_code & (ERR_ABORT|ERR_FATAL)) {
2107
0
      ha_alert("Fatal errors found in configuration.\n");
2108
0
      exit(1);
2109
0
    }
2110
0
  }
2111
2112
  /* update the ready date that will be used to count the startup time
2113
   * during config checks (e.g. to schedule certain tasks if needed)
2114
   */
2115
0
  clock_update_date(0, 1);
2116
0
  clock_adjust_now_offset();
2117
0
  ready_date = date;
2118
2119
#ifdef USE_CPU_AFFINITY
2120
  /* we've already read the config and know what CPUs are expected
2121
   * to be used. Let's check which of these are usable.
2122
   */
2123
  cpu_detect_usable();
2124
2125
  /* Now detect how CPUs are arranged */
2126
  cpu_detect_topology();
2127
2128
  /* fixup missing info */
2129
  cpu_fixup_topology();
2130
2131
  /* compose clusters */
2132
  cpu_compose_clusters();
2133
2134
  /* refine topology-based CPU sets */
2135
  cpu_refine_cpusets();
2136
#endif
2137
2138
  /* detect the optimal thread-groups and nbthreads if not set */
2139
0
  thread_detect_count();
2140
2141
  /* Note: global.nbthread will be initialized as part of this call */
2142
0
  err_code |= check_config_validity();
2143
0
  if (*initial_cwd && chdir(initial_cwd) == -1) {
2144
0
    ha_alert("Impossible to get back to initial directory '%s' : %s\n", initial_cwd, strerror(errno));
2145
0
    exit(1);
2146
0
  }
2147
2148
  /* now that config was parsed and checked
2149
   * prepare and preload shm-stats-file (if set)
2150
   */
2151
0
  err_code |= shm_stats_file_prepare();
2152
0
  if (err_code & (ERR_ABORT|ERR_FATAL))
2153
0
    exit(1);
2154
2155
  /* update the ready date to also account for the check time */
2156
0
  clock_update_date(0, 1);
2157
0
  clock_adjust_now_offset();
2158
0
  ready_date = date;
2159
2160
0
  list_for_each_entry(px, &proxies, global_list) {
2161
0
    struct server *srv;
2162
0
    struct post_proxy_check_fct *ppcf;
2163
0
    struct post_server_check_fct *pscf;
2164
2165
0
    if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
2166
0
      continue;
2167
2168
0
    list_for_each_entry(pscf, &post_server_check_list, list) {
2169
0
      for (srv = px->srv; srv; srv = srv->next) {
2170
0
        err_code |= pscf->fct(srv);
2171
0
        if (err_code & (ERR_ABORT|ERR_FATAL)) {
2172
0
          ha_alert("Fatal errors found in configuration.\n");
2173
0
          exit(1);
2174
0
        }
2175
0
      }
2176
0
    }
2177
0
    list_for_each_entry(ppcf, &post_proxy_check_list, list) {
2178
0
      err_code |= ppcf->fct(px);
2179
0
      if (err_code & (ERR_ABORT|ERR_FATAL)) {
2180
0
        ha_alert("Fatal errors found in configuration.\n");
2181
0
        exit(1);
2182
0
      }
2183
2184
0
    }
2185
0
    px->flags |= PR_FL_CHECKED;
2186
0
  }
2187
2188
0
  err_code |= pattern_finalize_config();
2189
0
  if (err_code & (ERR_ABORT|ERR_FATAL)) {
2190
0
    ha_alert("Failed to finalize pattern config.\n");
2191
0
    exit(1);
2192
0
  }
2193
2194
0
  if (global.rlimit_memmax_all)
2195
0
    global.rlimit_memmax = global.rlimit_memmax_all;
2196
2197
#ifdef USE_NS
2198
        err_code |= netns_init();
2199
        if (err_code & (ERR_ABORT|ERR_FATAL)) {
2200
                ha_alert("Failed to initialize namespace support.\n");
2201
                exit(1);
2202
        }
2203
#endif
2204
2205
0
  thread_detect_binding_discrepancies();
2206
0
  thread_detect_more_than_cpus();
2207
2208
  /* Apply server states */
2209
0
  apply_server_state();
2210
2211
  /* Preload internal counters. */
2212
0
  apply_stats_file();
2213
2214
0
  for (px = proxies_list; px; px = px->next)
2215
0
    srv_compute_all_admin_states(px);
2216
2217
  /* Apply servers' configured address */
2218
0
  err_code |= srv_init_addr();
2219
0
  if (err_code & (ERR_ABORT|ERR_FATAL)) {
2220
0
    ha_alert("Failed to initialize server(s) addr.\n");
2221
0
    exit(1);
2222
0
  }
2223
2224
0
  if (warned & WARN_ANY && global.mode & MODE_ZERO_WARNING) {
2225
0
    ha_alert("Some warnings were found and 'zero-warning' is set. Aborting.\n");
2226
0
    exit(1);
2227
0
  }
2228
2229
#if defined(HA_HAVE_DUMP_LIBS)
2230
  if (global.mode & MODE_DUMP_LIBS && !master) {
2231
    qfprintf(stdout, "List of loaded object files:\n");
2232
    chunk_reset(&trash);
2233
    if (dump_libs(&trash, ((arg_mode & (MODE_QUIET|MODE_VERBOSE)) == MODE_VERBOSE)))
2234
      printf("%s", trash.area);
2235
  }
2236
#endif
2237
2238
0
  if (global.mode & MODE_DUMP_KWD && !master)
2239
0
    dump_registered_keywords();
2240
2241
0
  if (global.mode & MODE_DIAG) {
2242
0
    cfg_run_diagnostics();
2243
0
  }
2244
2245
0
  if (global.mode & MODE_CHECK) {
2246
0
    struct peers *pr;
2247
0
    struct proxy *px;
2248
2249
0
    if (warned & WARN_ANY)
2250
0
      qfprintf(stdout, "Warnings were found.\n");
2251
2252
0
    for (pr = cfg_peers; pr; pr = pr->next)
2253
0
      if (pr->peers_fe)
2254
0
        break;
2255
2256
0
    for (px = proxies_list; px; px = px->next)
2257
0
      if (!(px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && px->li_all)
2258
0
        break;
2259
2260
0
    if (!px) {
2261
      /* We may only have log-forward section */
2262
0
      for (px = cfg_log_forward; px; px = px->next)
2263
0
        if (!(px->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && px->li_all)
2264
0
          break;
2265
0
    }
2266
2267
0
    if (pr || px) {
2268
      /* At least one peer or one listener has been found */
2269
0
      if (global.mode & MODE_VERBOSE)
2270
0
        qfprintf(stdout, "Configuration file is valid\n");
2271
0
      deinit_and_exit(0);
2272
0
    }
2273
0
    qfprintf(stdout, "Configuration file has no error but will not start (no listener) => exit(2).\n");
2274
0
    exit(2);
2275
0
  }
2276
2277
0
  if (global.mode & MODE_DUMP_CFG)
2278
0
    deinit_and_exit(0);
2279
2280
  /* now we know the buffer size, we can initialize the channels and buffers */
2281
0
  init_buffer();
2282
2283
0
  list_for_each_entry(pcf, &post_check_list, list) {
2284
0
    err_code |= pcf->fct();
2285
0
    if (err_code & (ERR_ABORT|ERR_FATAL))
2286
0
      exit(1);
2287
0
  }
2288
2289
  /* set the default maxconn in the master, but let it be rewritable with -n */
2290
0
  if (master)
2291
0
    global.maxconn = MASTER_MAXCONN;
2292
2293
0
  if (cfg_maxconn > 0)
2294
0
    global.maxconn = cfg_maxconn;
2295
2296
0
  if (global.cli_fe)
2297
0
    global.maxsock += global.cli_fe->maxconn;
2298
2299
0
  if (cfg_peers) {
2300
    /* peers also need to bypass global maxconn */
2301
0
    struct peers *p = cfg_peers;
2302
2303
0
    for (p = cfg_peers; p; p = p->next)
2304
0
      if (p->peers_fe)
2305
0
        global.maxsock += p->peers_fe->maxconn;
2306
0
  }
2307
2308
  /* count listeners, checks, plus 1 poller and one wake-up pipe (2fd) per thread */
2309
0
  global.est_fd_usage = global.maxsock + 3 * global.nbthread;
2310
2311
  /* Compute the global.maxconn and possibly global.maxsslconn values */
2312
0
  set_global_maxconn();
2313
0
  global.maxsock = compute_ideal_maxsock(global.maxconn);
2314
0
  global.hardmaxconn = global.maxconn;
2315
0
  if (!global.maxpipes)
2316
0
    global.maxpipes = compute_ideal_maxpipes();
2317
2318
  /* update connection pool thresholds */
2319
0
  global.tune.pool_low_count  = ((long long)global.maxsock * global.tune.pool_low_ratio  + 99) / 100;
2320
0
  global.tune.pool_high_count = ((long long)global.maxsock * global.tune.pool_high_ratio + 99) / 100;
2321
2322
0
  proxy_adjust_all_maxconn();
2323
2324
0
  if (global.tune.maxpollevents <= 0)
2325
0
    global.tune.maxpollevents = MAX_POLL_EVENTS;
2326
2327
0
  if (global.tune.max_rules_at_once <= 0)
2328
0
    global.tune.max_rules_at_once = MAX_RULES_AT_ONCE;
2329
2330
0
  if (global.tune.runqueue_depth <= 0) {
2331
    /* tests on various thread counts from 1 to 64 have shown an
2332
     * optimal queue depth following roughly 1/sqrt(threads).
2333
     */
2334
0
    int s = my_flsl(global.nbthread);
2335
0
    s += (global.nbthread / s); // roughly twice the sqrt.
2336
0
    global.tune.runqueue_depth = RUNQUEUE_DEPTH * 2 / s;
2337
0
  }
2338
2339
0
  if (global.tune.recv_enough == 0)
2340
0
    global.tune.recv_enough = MIN_RECV_AT_ONCE_ENOUGH;
2341
2342
0
  if (global.tune.maxrewrite >= global.tune.bufsize / 2)
2343
0
    global.tune.maxrewrite = global.tune.bufsize / 2;
2344
2345
  /* Realloc trash buffers because global.tune.bufsize may have changed */
2346
0
  if (!init_trash_buffers(0)) {
2347
0
    ha_alert("failed to initialize trash buffers.\n");
2348
0
    exit(1);
2349
0
  }
2350
2351
0
  if (!init_log_buffers()) {
2352
0
    ha_alert("failed to initialize log buffers.\n");
2353
0
    exit(1);
2354
0
  }
2355
2356
0
  if (!cluster_secret_isset)
2357
0
    generate_random_cluster_secret();
2358
2359
  /*
2360
   * Note: we could register external pollers here.
2361
   * Built-in pollers have been registered before main().
2362
   */
2363
2364
0
  if (!(global.tune.options & GTUNE_USE_KQUEUE))
2365
0
    disable_poller("kqueue");
2366
2367
0
  if (!(global.tune.options & GTUNE_USE_EVPORTS))
2368
0
    disable_poller("evports");
2369
2370
0
  if (!(global.tune.options & GTUNE_USE_EPOLL))
2371
0
    disable_poller("epoll");
2372
2373
0
  if (!(global.tune.options & GTUNE_USE_POLL))
2374
0
    disable_poller("poll");
2375
2376
0
  if (!(global.tune.options & GTUNE_USE_SELECT))
2377
0
    disable_poller("select");
2378
2379
  /* Note: we could disable any poller by name here */
2380
2381
0
  if ((global.mode & (MODE_VERBOSE|MODE_DEBUG)) && !master) {
2382
0
    list_pollers(stderr);
2383
0
    fprintf(stderr, "\n");
2384
0
    list_filters(stderr);
2385
0
  }
2386
2387
0
  if (!init_pollers()) {
2388
0
    ha_alert("No polling mechanism available.\n"
2389
0
       "  This may happen when using thread-groups with old pollers (poll/select), or\n"
2390
0
       "  it is possible that haproxy was built with TARGET=generic and that FD_SETSIZE\n"
2391
0
       "  is too low on this platform to support maxconn and the number of listeners\n"
2392
0
       "  and servers. You should rebuild haproxy specifying your system using TARGET=\n"
2393
0
       "  in order to support other polling systems (poll, epoll, kqueue) or reduce the\n"
2394
0
       "  global maxconn setting to accommodate the system's limitation. For reference,\n"
2395
0
       "  FD_SETSIZE=%d on this system, global.maxconn=%d resulting in a maximum of\n"
2396
0
       "  %d file descriptors. You should thus reduce global.maxconn by %d. Also,\n"
2397
0
       "  check build settings using 'haproxy -vv'.\n\n",
2398
0
       FD_SETSIZE, global.maxconn, global.maxsock, (global.maxsock + 1 - FD_SETSIZE) / 2);
2399
0
    exit(1);
2400
0
  }
2401
0
  if (global.mode & (MODE_VERBOSE|MODE_DEBUG)) {
2402
0
    printf("Using %s() as the polling mechanism.\n", cur_poller.name);
2403
0
  }
2404
2405
0
  if (!global.node)
2406
0
    global.node = strdup(hostname);
2407
2408
  /* stop disabled proxies */
2409
0
  for (px = proxies_list; px; px = px->next) {
2410
0
    if (px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))
2411
0
      stop_proxy(px);
2412
0
  }
2413
2414
0
  if (!hlua_post_init())
2415
0
    exit(1);
2416
2417
  /* Set the per-thread pool cache size to the default value if not set.
2418
   * This is the right place to decide to automatically adjust it (e.g.
2419
   * check L2 cache size, thread counts or take into account certain
2420
   * expensive pools).
2421
   */
2422
0
  if (!global.tune.pool_cache_size)
2423
0
    global.tune.pool_cache_size = CONFIG_HAP_POOL_CACHE_SIZE;
2424
2425
  /* fill in a few info about our version and build options */
2426
0
  chunk_reset(&trash);
2427
2428
  /* toolchain */
2429
0
  cc = chunk_newstr(&trash);
2430
0
#if defined(__clang_version__)
2431
0
  chunk_appendf(&trash, "clang-" __clang_version__);
2432
#elif defined(__VERSION__)
2433
  chunk_appendf(&trash, "gcc-" __VERSION__);
2434
#endif
2435
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
2436
  chunk_appendf(&trash, "+asan");
2437
#endif
2438
  /* toolchain opts */
2439
0
  cflags = chunk_newstr(&trash);
2440
0
  chunk_appendf(&trash, "%s", pm_toolchain_opts);
2441
2442
  /* settings */
2443
0
  opts = chunk_newstr(&trash);
2444
0
  chunk_appendf(&trash, "TARGET='%s'", pm_target_opts);
2445
2446
0
  post_mortem_add_component("haproxy", haproxy_version, cc, cflags, opts, argv[0]);
2447
0
}
2448
2449
/* This is a third part of the late init sequence, where we register signals for
2450
 * process in worker and in standalone modes. We also check here, if the
2451
 * global.maxsock calculated in step_init_2() could be applied as the nofile limit
2452
 * for the process. Memory limit, if set, will be applied here as well. If some
2453
 * capabilities were set on the haproxy binary by administrator, we will try to
2454
 * put it into the process Effective capabilities set. It only returns if
2455
 * everything is OK. If something fails, it exits.
2456
 */
2457
static void step_init_3(void)
2458
0
{
2459
0
  if (master) {
2460
0
    signal_register_fct(SIGQUIT, NULL, 0);
2461
0
    signal_register_fct(SIGUSR1, NULL, 0);
2462
0
    signal_register_fct(SIGHUP, NULL, 0);
2463
0
    signal_register_fct(SIGUSR2, NULL, 0);
2464
0
  } else {
2465
0
    signal_register_fct(SIGQUIT, dump, SIGQUIT);
2466
0
    signal_register_fct(SIGUSR1, sig_soft_stop, SIGUSR1);
2467
0
    signal_register_fct(SIGHUP, sig_dump_state, SIGHUP);
2468
0
    signal_register_fct(SIGUSR2, NULL, 0);
2469
0
  }
2470
2471
  /* Always catch SIGPIPE even on platforms which define MSG_NOSIGNAL.
2472
   * Some recent FreeBSD setups report broken pipes, and MSG_NOSIGNAL
2473
   * was defined there, so let's stay on the safe side.
2474
   */
2475
0
  signal_register_fct(SIGPIPE, NULL, 0);
2476
2477
  /* ulimits */
2478
0
  apply_nofile_limit();
2479
0
  apply_memory_limit();
2480
2481
#if defined(USE_LINUX_CAP)
2482
  /* If CAP_NET_BIND_SERVICE is in binary file permitted set and process
2483
   * is started and run under the same non-root user, this allows
2484
   * binding to privileged ports.
2485
   */
2486
  if (!master)
2487
      prepare_caps_from_permitted_set(geteuid(), global.uid);
2488
#endif
2489
0
}
2490
2491
/* This is a forth part of the late init sequence, where we apply verbosity
2492
 * modes, check nofile current limit, preallocate fds, update the ready date
2493
 * the last time, and close PID fd. It only returns if everything is OK. If
2494
 * something fails, it exits.
2495
 */
2496
static void step_init_4(void)
2497
0
{
2498
  /* MODE_QUIET is applied here, it can inhibit alerts and warnings below this line */
2499
0
  if (getenv("HAPROXY_MWORKER_REEXEC") != NULL) {
2500
    /* either stdin/out/err are already closed or should stay as they are. */
2501
0
    if ((global.mode & MODE_DAEMON)) {
2502
      /* daemon mode re-executing, stdin/stdout/stderr are already closed so keep quiet */
2503
0
      global.mode &= ~MODE_VERBOSE;
2504
0
      global.mode |= MODE_QUIET; /* ensure that we won't say anything from now */
2505
0
    }
2506
0
  } else {
2507
0
    if ((global.mode & MODE_QUIET) && !(global.mode & MODE_VERBOSE)) {
2508
      /* detach from the tty */
2509
0
      stdio_quiet(devnullfd);
2510
0
    }
2511
0
  }
2512
2513
  /* Note that any error at this stage will be fatal because we will not
2514
   * be able to restart the old pids.
2515
   */
2516
2517
  /* check current nofile limit reported via getrlimit() and check if we
2518
   * can preallocate FDs, if global.prealloc_fd is set.
2519
   */
2520
0
  check_nofile_lim_and_prealloc_fd();
2521
2522
  /* update the ready date a last time to also account for final setup time */
2523
0
  clock_update_date(0, 1);
2524
0
  clock_adjust_now_offset();
2525
0
  ready_date = date;
2526
0
}
2527
2528
/* This function sets verbosity modes. Should be called after the first
2529
 * configuration read in order that in master-worker mode, both master and
2530
 * worker have the same verbosiness.
2531
 */
2532
0
static void set_verbosity(void) {
2533
2534
0
  if (arg_mode & (MODE_DEBUG | MODE_FOREGROUND)) {
2535
    /* command line debug mode inhibits configuration mode */
2536
0
    global.mode &= ~(MODE_DAEMON | MODE_QUIET);
2537
0
    global.mode |= (arg_mode & (MODE_DEBUG | MODE_FOREGROUND));
2538
0
  }
2539
2540
0
  if (arg_mode & MODE_DAEMON) {
2541
    /* command line daemon mode inhibits foreground and debug modes mode */
2542
0
    global.mode &= ~(MODE_DEBUG | MODE_FOREGROUND);
2543
0
    global.mode |= arg_mode & MODE_DAEMON;
2544
0
  }
2545
2546
0
  global.mode |= (arg_mode & (MODE_QUIET | MODE_VERBOSE));
2547
2548
0
  if ((global.mode & MODE_DEBUG) && (global.mode & (MODE_DAEMON | MODE_QUIET))) {
2549
0
    ha_warning("<debug> mode incompatible with <quiet> and <daemon>. Keeping <debug> only.\n");
2550
0
    global.mode &= ~(MODE_DAEMON | MODE_QUIET);
2551
0
  }
2552
0
}
2553
2554
static void run_master_in_recovery_mode(int argc, char **argv)
2555
0
{
2556
0
  struct mworker_proc *proc;
2557
0
  char *errmsg = NULL;
2558
2559
  /* load_status is global and checked in cli_io_handler_show_cli_sock() to
2560
   * dump master startup logs with its alerts/warnings via master CLI sock.
2561
   */
2562
0
  load_status = 0;
2563
2564
  /* increment the number failed reloads */
2565
0
  list_for_each_entry(proc, &proc_list, list) {
2566
0
    proc->failedreloads++;
2567
0
  }
2568
  /* the sd_notify API is not able to send a reload failure signal. So
2569
   * the READY=1 signal still need to be sent */
2570
0
  if (global.tune.options & GTUNE_USE_SYSTEMD)
2571
0
    sd_notify(0, "READY=1\nSTATUS=Reload failed (master failed to load or to parse new configuration)!\n");
2572
2573
0
  global.nbtgroups = 1;
2574
0
  global.nbthread = 1;
2575
0
  master = 1;
2576
0
  atexit(exit_on_failure);
2577
0
  set_verbosity();
2578
2579
  /* creates MASTER proxy */
2580
0
  if (mworker_cli_create_master_proxy(&errmsg) < 0) {
2581
0
    ha_alert("Can't create MASTER proxy: %s\n", errmsg);
2582
0
    free(errmsg);
2583
0
    exit(EXIT_FAILURE);
2584
0
  }
2585
2586
  /* attaches servers to all existed workers on its shared MCLI sockpair ends, ipc_fd[0] */
2587
0
  if (mworker_cli_attach_server(&errmsg) < 0) {
2588
0
    ha_alert("Can't attach servers needed for master CLI %s\n", errmsg ? errmsg : "");
2589
0
    free(errmsg);
2590
0
    exit(EXIT_FAILURE);
2591
0
  }
2592
2593
  /* master CLI */
2594
0
  mworker_create_master_cli();
2595
0
  step_init_2(argc, argv);
2596
0
  step_init_3();
2597
0
  if (protocol_bind_all(1) != 0) {
2598
0
    ha_alert("Master failed to bind master CLI socket.\n");
2599
0
    exit(1);
2600
0
  }
2601
2602
0
  step_init_4();
2603
2604
  /* set quiet mode if MODE_DAEMON */
2605
0
  if ((!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) &&
2606
0
    (global.mode & MODE_DAEMON)) {
2607
    /* detach from the tty, this is required to properly daemonize. */
2608
0
    if ((getenv("HAPROXY_MWORKER_REEXEC") == NULL))
2609
0
      stdio_quiet(devnullfd);
2610
0
    global.mode &= ~MODE_VERBOSE;
2611
0
    global.mode |= MODE_QUIET; /* ensure that we won't say anything from now */
2612
0
  }
2613
2614
0
  mworker_unblock_signals();
2615
  /* enter in master polling loop */
2616
0
  mworker_run_master();
2617
0
}
2618
2619
/* parse conf in discovery mode and set modes from config */
2620
static void read_cfg_in_discovery_mode(int argc, char **argv)
2621
0
{
2622
0
  struct cfgfile *cfg, *cfg_tmp;
2623
2624
  /* load configs in memory and parse only global section (MODE_DISCOVERY) */
2625
0
  global.mode |= MODE_DISCOVERY;
2626
2627
0
  usermsgs_clr("config");
2628
0
  if (load_cfg() < 0) {
2629
0
    if (getenv("HAPROXY_MWORKER_REEXEC") != NULL) {
2630
0
      ha_warning("Master failed to load new configuration and "
2631
0
           "can't start a new worker. Already running worker "
2632
0
           "will be kept. Please, check configuration file path "
2633
0
           "and memory limits and reload %s.\n", progname);
2634
      /* failed to load new conf, so setup master CLI for master side,
2635
       * do some init steps and just enter in mworker_loop
2636
       * to monitor the existed worker from previous start
2637
       */
2638
0
      run_master_in_recovery_mode(argc, argv);
2639
      /* never get there */
2640
0
    } else
2641
0
      exit(1);
2642
0
  }
2643
2644
0
  if (read_cfg() < 0) {
2645
0
    list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list) {
2646
0
      ha_free(&cfg->content);
2647
0
      ha_free(&cfg->filename);
2648
0
    }
2649
0
    if (getenv("HAPROXY_MWORKER_REEXEC") != NULL) {
2650
0
      ha_warning("Master failed to parse new configuration and "
2651
0
           "can't start a new worker. Already running worker "
2652
0
           "will be kept. Please, check global section settings "
2653
0
           "and memory limits and reload %s.\n", progname);
2654
      /* failed to load new conf, so setup master CLI for master side,
2655
       * do some init steps and just enter in mworker_loop
2656
       * to monitor the existed worker from previous start
2657
       */
2658
0
      run_master_in_recovery_mode(argc, argv);
2659
      /* never get there */
2660
0
    } else
2661
0
      exit(1);
2662
0
  }
2663
0
  usermsgs_clr(NULL);
2664
2665
0
  global.mode &= ~MODE_DISCOVERY;
2666
2667
0
  if (!LIST_ISEMPTY(&mworker_cli_conf) && !(arg_mode & MODE_MWORKER)) {
2668
0
    ha_alert("a master CLI socket was defined, but master-worker mode (-W) is not enabled.\n");
2669
0
    exit(EXIT_FAILURE);
2670
0
  }
2671
2672
  /* in MODE_CHECK and in MODE_DUMP_CFG we just need to parse the
2673
   * configuration and exit, see step_init_2()
2674
   */
2675
0
  if ((global.mode & MODE_MWORKER) && (global.mode & (MODE_CHECK | MODE_DUMP_CFG)))
2676
0
    global.mode &= ~MODE_MWORKER;
2677
0
}
2678
2679
void deinit(void)
2680
0
{
2681
0
  struct proxy *p = proxies_list, *p0;
2682
0
  struct cfgfile *cfg, *cfg_tmp;
2683
0
  struct logger *log, *logb;
2684
0
  struct build_opts_str *bol, *bolb;
2685
0
  struct post_deinit_fct *pdf, *pdfb;
2686
0
  struct proxy_deinit_fct *pxdf, *pxdfb;
2687
0
  struct server_deinit_fct *srvdf, *srvdfb;
2688
0
  struct per_thread_init_fct *tif, *tifb;
2689
0
  struct per_thread_deinit_fct *tdf, *tdfb;
2690
0
  struct per_thread_alloc_fct *taf, *tafb;
2691
0
  struct per_thread_free_fct *tff, *tffb;
2692
0
  struct post_server_check_fct *pscf, *pscfb;
2693
0
  struct post_check_fct *pcf, *pcfb;
2694
0
  struct post_proxy_check_fct *ppcf, *ppcfb;
2695
0
  struct pre_check_fct *prcf, *prcfb;
2696
0
  struct cfg_postparser *pprs, *pprsb;
2697
0
  char **tmp = init_env;
2698
0
  int cur_fd;
2699
2700
  /* the user may want to skip this phase */
2701
0
  if (global.tune.options & GTUNE_QUICK_EXIT)
2702
0
    return;
2703
2704
  /* At this point the listeners state is weird:
2705
   *  - most listeners are still bound and referenced in their protocol
2706
   *  - some might be zombies that are not in their proto anymore, but
2707
   *    still appear in their proxy's listeners with a valid FD.
2708
   *  - some might be stopped and still appear in their proxy as FD #-1
2709
   *  - among all of them, some might be inherited hence shared and we're
2710
   *    not allowed to pause them or whatever, we must just close them.
2711
   *  - finally some are not listeners (pipes, logs, stdout, etc) and
2712
   *    must be left intact.
2713
   *
2714
   * The safe way to proceed is to unbind (and close) whatever is not yet
2715
   * unbound so that no more receiver/listener remains alive. Then close
2716
   * remaining listener FDs, which correspond to zombie listeners (those
2717
   * belonging to disabled proxies that were in another process).
2718
   * objt_listener() would be cleaner here but not converted yet.
2719
   */
2720
0
  protocol_unbind_all();
2721
2722
0
  for (cur_fd = 0; cur_fd < global.maxsock; cur_fd++) {
2723
0
    if (!fdtab || !fdtab[cur_fd].owner)
2724
0
      continue;
2725
2726
0
    if (fdtab[cur_fd].iocb == &sock_accept_iocb) {
2727
0
      struct listener *l = fdtab[cur_fd].owner;
2728
2729
0
      BUG_ON(l->state != LI_INIT);
2730
0
      unbind_listener(l);
2731
0
    }
2732
0
  }
2733
2734
0
  deinit_signals();
2735
0
  while (p) {
2736
0
    p0 = p;
2737
0
    p = p->next;
2738
0
    free_proxy(p0);
2739
0
  }/* end while(p) */
2740
2741
  /* we don't need to free sink_proxies_list nor cfg_log_forward proxies since
2742
   * they are respectively cleaned up in sink_deinit() and deinit_log_forward()
2743
   */
2744
2745
  /* destroy all referenced defaults proxies  */
2746
0
  proxy_destroy_all_unref_defaults();
2747
2748
0
  userlist_free(userlist);
2749
2750
0
  cfg_unregister_sections();
2751
2752
0
  deinit_log_buffers();
2753
2754
0
  list_for_each_entry(pdf, &post_deinit_list, list)
2755
0
    pdf->fct();
2756
2757
0
  ha_free(&global.log_send_hostname);
2758
0
  chunk_destroy(&global.log_tag);
2759
0
  ha_free(&global.chroot);
2760
0
  ha_free(&global.pidfile);
2761
0
  ha_free(&global.node);
2762
0
  ha_free(&global.desc);
2763
0
  ha_free(&oldpids);
2764
0
  ha_free(&old_argv);
2765
0
  ha_free(&localpeer);
2766
0
  ha_free(&global.server_state_base);
2767
0
  ha_free(&global.server_state_file);
2768
0
  ha_free(&global.stats_file);
2769
0
  task_destroy(idle_conn_task);
2770
0
  idle_conn_task = NULL;
2771
2772
0
  list_for_each_entry_safe(log, logb, &global.loggers, list) {
2773
0
    LIST_DEL_INIT(&log->list);
2774
0
    free_logger(log);
2775
0
  }
2776
2777
0
  list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list) {
2778
0
    ha_free(&cfg->filename);
2779
0
    LIST_DELETE(&cfg->list);
2780
0
    ha_free(&cfg);
2781
0
  }
2782
2783
0
  list_for_each_entry_safe(bol, bolb, &build_opts_list, list) {
2784
0
    if (bol->must_free)
2785
0
      free((void *)bol->str);
2786
0
    LIST_DELETE(&bol->list);
2787
0
    free(bol);
2788
0
  }
2789
2790
0
  list_for_each_entry_safe(pxdf, pxdfb, &proxy_deinit_list, list) {
2791
0
    LIST_DELETE(&pxdf->list);
2792
0
    free(pxdf);
2793
0
  }
2794
2795
0
  list_for_each_entry_safe(pdf, pdfb, &post_deinit_list, list) {
2796
0
    LIST_DELETE(&pdf->list);
2797
0
    free(pdf);
2798
0
  }
2799
2800
0
  list_for_each_entry_safe(srvdf, srvdfb, &server_deinit_list, list) {
2801
0
    LIST_DELETE(&srvdf->list);
2802
0
    free(srvdf);
2803
0
  }
2804
2805
0
  list_for_each_entry_safe(pcf, pcfb, &post_check_list, list) {
2806
0
    LIST_DELETE(&pcf->list);
2807
0
    free(pcf);
2808
0
  }
2809
2810
0
  list_for_each_entry_safe(pscf, pscfb, &post_server_check_list, list) {
2811
0
    LIST_DELETE(&pscf->list);
2812
0
    free(pscf);
2813
0
  }
2814
2815
0
  list_for_each_entry_safe(ppcf, ppcfb, &post_proxy_check_list, list) {
2816
0
    LIST_DELETE(&ppcf->list);
2817
0
    free(ppcf);
2818
0
  }
2819
2820
0
  list_for_each_entry_safe(prcf, prcfb, &pre_check_list, list) {
2821
0
    LIST_DELETE(&prcf->list);
2822
0
    free(prcf);
2823
0
  }
2824
2825
0
  list_for_each_entry_safe(tif, tifb, &per_thread_init_list, list) {
2826
0
    LIST_DELETE(&tif->list);
2827
0
    free(tif);
2828
0
  }
2829
2830
0
  list_for_each_entry_safe(tdf, tdfb, &per_thread_deinit_list, list) {
2831
0
    LIST_DELETE(&tdf->list);
2832
0
    free(tdf);
2833
0
  }
2834
2835
0
  list_for_each_entry_safe(taf, tafb, &per_thread_alloc_list, list) {
2836
0
    LIST_DELETE(&taf->list);
2837
0
    free(taf);
2838
0
  }
2839
2840
0
  list_for_each_entry_safe(tff, tffb, &per_thread_free_list, list) {
2841
0
    LIST_DELETE(&tff->list);
2842
0
    free(tff);
2843
0
  }
2844
2845
0
  list_for_each_entry_safe(pprs, pprsb, &postparsers, list) {
2846
0
    LIST_DELETE(&pprs->list);
2847
0
    free(pprs);
2848
0
  }
2849
2850
0
  vars_prune(&proc_vars, NULL, NULL);
2851
0
  free_all_file_names();
2852
0
  pool_destroy_all();
2853
0
  deinit_pollers();
2854
2855
  /* free env variables backup */
2856
0
  if (init_env) {
2857
0
    while (*tmp) {
2858
0
      free(*tmp);
2859
0
      tmp++;
2860
0
    }
2861
0
    free(init_env);
2862
0
  }
2863
0
  free(progname);
2864
2865
0
} /* end deinit() */
2866
2867
__attribute__((noreturn)) void deinit_and_exit(int status)
2868
0
{
2869
0
  global.mode |= MODE_STOPPING;
2870
0
  deinit();
2871
0
  exit(status);
2872
0
}
2873
2874
/* Runs the polling loop */
2875
void run_poll_loop()
2876
0
{
2877
0
  int next, wake;
2878
2879
0
  _HA_ATOMIC_OR(&th_ctx->flags, TH_FL_IN_LOOP);
2880
2881
0
  clock_update_date(0,1);
2882
0
  while (1) {
2883
0
    wake_expired_tasks();
2884
2885
    /* check if we caught some signals and process them in the
2886
     first thread */
2887
0
    if (signal_queue_len && tid == 0) {
2888
0
      activity[tid].wake_signal++;
2889
0
      signal_process_queue();
2890
0
    }
2891
2892
    /* Process a few tasks */
2893
0
    process_runnable_tasks();
2894
2895
    /* also stop  if we failed to cleanly stop all tasks */
2896
0
    if (killed > 1)
2897
0
      break;
2898
2899
    /* expire immediately if events or signals are pending */
2900
0
    wake = 1;
2901
0
    if (thread_has_tasks())
2902
0
      activity[tid].wake_tasks++;
2903
0
    else {
2904
0
      _HA_ATOMIC_OR(&th_ctx->flags, TH_FL_SLEEPING);
2905
0
      _HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_NOTIFIED);
2906
0
      __ha_barrier_atomic_store();
2907
0
      if (thread_has_tasks()) {
2908
0
        activity[tid].wake_tasks++;
2909
0
        _HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_SLEEPING);
2910
0
      } else if (signal_queue_len && tid == 0) {
2911
        /* this check is required after setting TH_FL_SLEEPING to avoid
2912
         * a race with wakeup on signals using wake_threads() */
2913
0
        _HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_SLEEPING);
2914
0
      } else
2915
0
        wake = 0;
2916
0
    }
2917
2918
    /* Note below: threads only check the quit condition when idle,
2919
     * but for tid>0 we also need to skip that if the signal queue
2920
     * is non-empty otherwise we risk quitting too early.
2921
     */
2922
0
    if (!wake && !signal_queue_len) {
2923
0
      int i;
2924
2925
0
      if (stopping) {
2926
0
        int old_detected;
2927
2928
        /* stop muxes/quic-conns before acknowledging stopping */
2929
0
        if (!(tg_ctx->stopping_threads & ti->ltid_bit)) {
2930
0
          task_wakeup(mux_stopping_data[tid].task, TASK_WOKEN_OTHER);
2931
0
          wake = 1;
2932
0
        }
2933
2934
0
        old_detected = stop_detected;
2935
2936
        /*
2937
         * Check if ze're the first to detect the
2938
         * stop
2939
         */
2940
0
        while (old_detected == 0 &&
2941
0
               !_HA_ATOMIC_CAS(&stop_detected, &old_detected, 1));
2942
2943
0
        if (old_detected == 0) {
2944
          /* first one to detect it, notify all threads that stopping was just set */
2945
0
          for (i = 0; i < global.nbthread; i++) {
2946
0
            if (_HA_ATOMIC_LOAD(&ha_thread_info[i].tg->threads_enabled) &
2947
0
                ha_thread_info[i].ltid_bit &
2948
0
                ~_HA_ATOMIC_LOAD(&ha_thread_info[i].tg_ctx->stopping_threads))
2949
0
              wake_thread(i);
2950
0
          }
2951
0
        }
2952
0
        if (!(tg_ctx->stopping_threads & ti->ltid_bit) &&
2953
0
            _HA_ATOMIC_OR_FETCH(&tg_ctx->stopping_threads,
2954
0
              ti->ltid_bit) == tg->threads_enabled) {
2955
          /*
2956
           * All threads from the thread group
2957
           * are stopped, let it been known.
2958
           */
2959
0
          _HA_ATOMIC_INC(&stopped_tgroups);
2960
0
        }
2961
0
      }
2962
2963
      /* stop when there's nothing left to do */
2964
0
      if ((jobs - unstoppable_jobs) == 0 &&
2965
0
          (_HA_ATOMIC_LOAD(&stopped_tgroups) == global.nbtgroups)) {
2966
#ifdef USE_THREAD
2967
        for (i = 0; i < global.nbthread; i++)
2968
          if (i != tid && _HA_ATOMIC_LOAD(&ha_thread_info[i].tg->threads_enabled) & ha_thread_info[i].ltid_bit)
2969
            wake_thread(i);
2970
#endif
2971
0
        break;
2972
0
      }
2973
0
    }
2974
2975
    /* If we have to sleep, measure how long */
2976
0
    next = wake ? TICK_ETERNITY : next_timer_expiry();
2977
2978
    /* The poller will ensure it returns around <next> */
2979
0
    cur_poller.poll(&cur_poller, next, wake);
2980
2981
0
    activity[tid].loops++;
2982
0
  }
2983
2984
0
  _HA_ATOMIC_AND(&th_ctx->flags, ~TH_FL_IN_LOOP);
2985
0
}
2986
2987
void *run_thread_poll_loop(void *data)
2988
0
{
2989
0
  struct per_thread_alloc_fct  *ptaf;
2990
0
  struct per_thread_init_fct   *ptif;
2991
0
  struct per_thread_deinit_fct *ptdf;
2992
0
  struct per_thread_free_fct   *ptff;
2993
0
  static int init_left = 0;
2994
0
  __decl_thread(static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER);
2995
0
  __decl_thread(static pthread_cond_t  init_cond  = PTHREAD_COND_INITIALIZER);
2996
2997
0
  ha_set_thread(data);
2998
0
  set_thread_cpu_affinity();
2999
0
  clock_set_local_source();
3000
3001
#ifdef USE_THREAD
3002
  ha_thread_info[tid].pth_id = ha_get_pthread_id(tid);
3003
#endif
3004
0
  ha_thread_info[tid].stack_top = __builtin_frame_address(0);
3005
3006
  /* Assign the ring queue. Contrary to an intuitive thought, this does
3007
   * not benefit from locality and it's counter-productive to group
3008
   * threads from a same group or range number in the same queue. In some
3009
   * sense it arranges us because it means we can use a modulo and ensure
3010
   * that even small numbers of threads are well spread.
3011
   */
3012
0
  ha_thread_info[tid].ring_queue =
3013
0
    (tid % MIN(global.nbthread,
3014
0
         (global.tune.ring_queues ?
3015
0
          global.tune.ring_queues :
3016
0
          RING_DFLT_QUEUES))) % RING_WAIT_QUEUES;
3017
3018
  /* thread is started, from now on it is not idle nor harmless */
3019
0
  thread_harmless_end();
3020
0
  thread_idle_end();
3021
0
  _HA_ATOMIC_OR(&th_ctx->flags, TH_FL_STARTED);
3022
3023
  /* Now, initialize one thread init at a time. This is better since
3024
   * some init code is a bit tricky and may release global resources
3025
   * after reallocating them locally. This will also ensure there is
3026
   * no race on file descriptors allocation.
3027
   */
3028
#ifdef USE_THREAD
3029
  pthread_mutex_lock(&init_mutex);
3030
#endif
3031
  /* The first thread must set the number of threads left */
3032
0
  if (!init_left)
3033
0
    init_left = global.nbthread;
3034
0
  init_left--;
3035
3036
0
  clock_init_thread_date();
3037
3038
  /* per-thread alloc calls performed here are not allowed to snoop on
3039
   * other threads, so they are free to initialize at their own rhythm
3040
   * as long as they act as if they were alone. None of them may rely
3041
   * on resources initialized by the other ones.
3042
   */
3043
0
  list_for_each_entry(ptaf, &per_thread_alloc_list, list) {
3044
0
    if (!ptaf->fct()) {
3045
0
      ha_alert("failed to allocate resources for thread %u.\n", tid);
3046
#ifdef USE_THREAD
3047
      pthread_mutex_unlock(&init_mutex);
3048
#endif
3049
0
      exit(1);
3050
0
    }
3051
0
  }
3052
3053
  /* per-thread init calls performed here are not allowed to snoop on
3054
   * other threads, so they are free to initialize at their own rhythm
3055
   * as long as they act as if they were alone.
3056
   */
3057
0
  list_for_each_entry(ptif, &per_thread_init_list, list) {
3058
0
    if (!ptif->fct()) {
3059
0
      ha_alert("failed to initialize thread %u.\n", tid);
3060
#ifdef USE_THREAD
3061
      pthread_mutex_unlock(&init_mutex);
3062
#endif
3063
0
      exit(1);
3064
0
    }
3065
0
  }
3066
3067
  /* enabling protocols will result in fd_insert() calls to be performed,
3068
   * we want all threads to have already allocated their local fd tables
3069
   * before doing so, thus only the last thread does it.
3070
   */
3071
0
  if (init_left == 0)
3072
0
    protocol_enable_all();
3073
3074
#ifdef USE_THREAD
3075
  pthread_cond_broadcast(&init_cond);
3076
  pthread_mutex_unlock(&init_mutex);
3077
3078
  /* now wait for other threads to finish starting */
3079
  pthread_mutex_lock(&init_mutex);
3080
  while (init_left)
3081
    pthread_cond_wait(&init_cond, &init_mutex);
3082
  pthread_mutex_unlock(&init_mutex);
3083
#endif
3084
3085
#if defined(PR_SET_NO_NEW_PRIVS) && defined(USE_PRCTL)
3086
  /* Let's refrain from using setuid executables. This way the impact of
3087
   * an eventual vulnerability in a library remains limited. It may
3088
   * impact external checks but who cares about them anyway ? In the
3089
   * worst case it's possible to disable the option. Obviously we do this
3090
   * in workers only. We can't hard-fail on this one as it really is
3091
   * implementation dependent though we're interested in feedback, hence
3092
   * the warning.
3093
   */
3094
  if (!(global.tune.options & GTUNE_INSECURE_SETUID) && !master) {
3095
    static int warn_fail;
3096
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1 && !_HA_ATOMIC_FETCH_ADD(&warn_fail, 1)) {
3097
      ha_warning("Failed to disable setuid, please report to developers with detailed "
3098
           "information about your operating system. You can silence this warning "
3099
           "by adding 'insecure-setuid-wanted' in the 'global' section.\n");
3100
    }
3101
  }
3102
#endif
3103
3104
0
#if defined(RLIMIT_NPROC)
3105
  /* all threads have started, it's now time to prevent any new thread
3106
   * or process from starting. Obviously we do this in workers only. We
3107
   * can't hard-fail on this one as it really is implementation dependent
3108
   * though we're interested in feedback, hence the warning.
3109
   */
3110
0
  if (!(global.tune.options & GTUNE_INSECURE_FORK) && !master) {
3111
0
    struct rlimit limit = { .rlim_cur = 0, .rlim_max = 0 };
3112
0
    static int warn_fail;
3113
3114
0
    if (setrlimit(RLIMIT_NPROC, &limit) == -1 && !_HA_ATOMIC_FETCH_ADD(&warn_fail, 1)) {
3115
0
      ha_warning("Failed to disable forks, please report to developers with detailed "
3116
0
           "information about your operating system. You can silence this warning "
3117
0
           "by adding 'insecure-fork-wanted' in the 'global' section.\n");
3118
0
    }
3119
0
  }
3120
0
#endif
3121
0
  run_poll_loop();
3122
3123
0
  list_for_each_entry(ptdf, &per_thread_deinit_list, list)
3124
0
    ptdf->fct();
3125
3126
0
  list_for_each_entry(ptff, &per_thread_free_list, list)
3127
0
    ptff->fct();
3128
3129
#ifdef USE_THREAD
3130
  if (!_HA_ATOMIC_AND_FETCH(&ha_tgroup_info[ti->tgid-1].threads_enabled, ~ti->ltid_bit))
3131
    _HA_ATOMIC_AND(&all_tgroups_mask, ~tg->tgid_bit);
3132
  _HA_ATOMIC_AND_FETCH(&tg_ctx->stopping_threads, ~ti->ltid_bit);
3133
  if (tid > 0)
3134
    pthread_exit(NULL);
3135
#endif
3136
0
  return NULL;
3137
0
}
3138
3139
/* set uid/gid depending on global settings */
3140
static void set_identity(const char *program_name)
3141
0
{
3142
0
  int from_uid __maybe_unused = geteuid();
3143
3144
0
  if (global.gid > 0) {
3145
0
    if (getgroups(0, NULL) > 0 && setgroups(0, NULL) == -1)
3146
0
      ha_warning("[%s.main()] Failed to drop supplementary groups. Using 'gid'/'group'"
3147
0
           " without 'uid'/'user' is generally useless.\n", program_name);
3148
3149
0
    if (setgid(global.gid) == -1) {
3150
0
      ha_alert("[%s.main()] Cannot set gid %d.\n", program_name, global.gid);
3151
0
      protocol_unbind_all();
3152
0
      exit(1);
3153
0
    }
3154
0
  }
3155
3156
#if defined(USE_LINUX_CAP)
3157
  if (prepare_caps_for_setuid(from_uid, global.uid) < 0) {
3158
    ha_alert("[%s.main()] Cannot switch uid to %d.\n", program_name, global.uid);
3159
    protocol_unbind_all();
3160
    exit(1);
3161
  }
3162
#endif
3163
3164
0
  if (global.uid > 0 && setuid(global.uid) == -1) {
3165
0
    ha_alert("[%s.main()] Cannot set uid %d.\n", program_name, global.uid);
3166
0
    protocol_unbind_all();
3167
0
    exit(1);
3168
0
  }
3169
3170
#if defined(USE_LINUX_CAP)
3171
  if (finalize_caps_after_setuid(from_uid, global.uid) < 0) {
3172
    ha_alert("[%s.main()] Cannot switch uid to %d.\n", program_name, global.uid);
3173
    protocol_unbind_all();
3174
    exit(1);
3175
  }
3176
#endif
3177
0
}
3178
3179
int main2(int argc, char **argv)
3180
0
{
3181
0
  struct rlimit limit;
3182
0
  int intovf = (unsigned char)argc + 1; /* let the compiler know it's strictly positive */
3183
0
  struct cfgfile *cfg, *cfg_tmp;
3184
0
  struct ring *tmp_startup_logs = NULL;
3185
0
  struct mworker_proc *proc;
3186
3187
  /* Catch broken toolchains */
3188
0
  if (sizeof(long) != sizeof(void *) || (intovf + 0x7FFFFFFF >= intovf)) {
3189
0
    const char *msg;
3190
3191
0
    if (sizeof(long) != sizeof(void *))
3192
      /* Apparently MingW64 was not made for us and can also break openssl */
3193
0
      msg = "The compiler this program was built with uses unsupported integral type sizes.\n"
3194
0
            "Most likely it follows the unsupported LLP64 model. Never try to link HAProxy\n"
3195
0
            "against libraries built with that compiler either! Please only use a compiler\n"
3196
0
            "producing ILP32 or LP64 programs for both programs and libraries.\n";
3197
0
    else if (intovf + 0x7FFFFFFF >= intovf)
3198
      /* Catch forced CFLAGS that miss 2-complement integer overflow */
3199
0
      msg = "The source code was miscompiled by the compiler, which usually indicates that\n"
3200
0
            "some of the CFLAGS needed to work around overzealous compiler optimizations\n"
3201
0
            "were overwritten at build time. Please do not force CFLAGS, and read Makefile\n"
3202
0
            "and INSTALL files to decide on the best way to pass your local build options.\n";
3203
0
    else
3204
0
      msg = "Bug in the compiler bug detection code, please report it to developers!\n";
3205
3206
0
    fprintf(stderr,
3207
0
            "FATAL ERROR: invalid code detected -- cannot go further, please recompile!\n"
3208
0
            "%s"
3209
0
      "\nBuild options :%s"
3210
0
            "\n\n", msg, build_opts_string);
3211
3212
0
    return 1;
3213
0
  }
3214
3215
0
  setvbuf(stdout, NULL, _IONBF, 0);
3216
3217
  /* take a copy of initial limits before we possibly change them */
3218
0
  getrlimit(RLIMIT_NOFILE, &limit);
3219
3220
0
  if (limit.rlim_max == RLIM_INFINITY)
3221
0
    limit.rlim_max = limit.rlim_cur;
3222
0
  rlim_fd_cur_at_boot = limit.rlim_cur;
3223
0
  rlim_fd_max_at_boot = limit.rlim_max;
3224
3225
#ifdef USE_OPENSSL
3226
3227
  /* Initialize SSL random generator. Must be called before chroot for
3228
   * access to /dev/urandom, and before ha_random_boot() which may use
3229
   * RAND_bytes().
3230
   */
3231
  if (!ssl_initialize_random()) {
3232
    ha_alert("OpenSSL random data generator initialization failed.\n");
3233
    exit(EXIT_FAILURE);
3234
  }
3235
#endif
3236
0
  ha_random_boot(argv); // the argv pointer brings some kernel-fed entropy
3237
3238
  /* process all initcalls in order of potential dependency */
3239
0
  RUN_INITCALLS(STG_PREPARE);
3240
0
  RUN_INITCALLS(STG_LOCK);
3241
0
  RUN_INITCALLS(STG_REGISTER);
3242
3243
  /* now's time to initialize early boot variables */
3244
0
  init_early(argc, argv);
3245
3246
  /* handles argument parsing */
3247
0
  init_args(argc, argv);
3248
3249
0
  RUN_INITCALLS(STG_ALLOC);
3250
0
  RUN_INITCALLS(STG_POOL);
3251
3252
  /* some code really needs to have the trash properly allocated */
3253
0
  if (!trash.area) {
3254
0
    ha_alert("failed to initialize trash buffers.\n");
3255
0
    exit(1);
3256
0
  }
3257
3258
0
  RUN_INITCALLS(STG_INIT);
3259
3260
  /* Late init step: SSL crypto libs init and check, Lua lib init, ACL init,
3261
   * set modes from cmdline and change dir, if this option is provided via
3262
   * cmdline.
3263
   */
3264
0
  step_init_1();
3265
3266
  /* call a function to be called with -U in order to make some tests */
3267
#ifdef DEBUG_UNIT
3268
  if (unittest_argc > -1) {
3269
    struct unittest_fct *unit;
3270
    int ret = 1;
3271
    int argc_start = argc - unittest_argc;
3272
3273
    list_for_each_entry(unit, &unittest_list, list) {
3274
3275
      if (strcmp(unit->name, argv[argc_start]) == 0) {
3276
        ret = unit->fct(unittest_argc, argv + argc_start);
3277
        break;
3278
      }
3279
    }
3280
3281
    exit(ret);
3282
  }
3283
#endif
3284
3285
3286
  /* deserialize processes list, if we do reload in master-worker mode */
3287
0
  if ((getenv("HAPROXY_MWORKER_REEXEC") != NULL)) {
3288
0
    if (mworker_env_to_proc_list() < 0) {
3289
0
      ha_alert("Master failed to deserialize monitored processes list, "
3290
0
         "it's a non-recoverable error, exiting.\n");
3291
0
      exit(EXIT_FAILURE);
3292
0
    }
3293
0
  }
3294
3295
  /* backup initial process env, because parse_cfg() could modify it with
3296
   * setenv/unsetenv/presetenv/resetenv keywords.
3297
   */
3298
0
  if (backup_env() != 0)
3299
0
    exit(EXIT_FAILURE);
3300
3301
  /* parse conf in discovery mode and set modes from config */
3302
0
  read_cfg_in_discovery_mode(argc, argv);
3303
3304
  /* From this stage all runtime modes are known. So let's do below some
3305
   * preparation steps and then let's apply all discovered modes.
3306
   */
3307
0
  set_verbosity();
3308
3309
  /* We might need to use this devnullfd during configuration parsing. */
3310
0
  devnullfd = open("/dev/null", O_RDWR, 0);
3311
0
  if (devnullfd < 0) {
3312
0
    ha_alert("Cannot open /dev/null\n");
3313
0
    exit(EXIT_FAILURE);
3314
0
  }
3315
0
  if (fcntl(devnullfd, FD_CLOEXEC) != 0) {
3316
0
    ha_alert("Cannot make /dev/null CLOEXEC\n");
3317
0
    close(devnullfd);
3318
0
    exit(EXIT_FAILURE);
3319
0
  }
3320
3321
  /* Add entries for master and worker in proc_list, create sockpair,
3322
   * that will be copied to both processes after master-worker fork to
3323
   * enable the master CLI at worker side (worker can send messages to master),
3324
   * setenv("HAPROXY_MWORKER", "1", 1).
3325
   */
3326
0
  if (global.mode & MODE_MWORKER)
3327
0
    mworker_prepare_master();
3328
3329
  /* If we are in a daemon mode and we might be also in master-worker mode:
3330
   * we should do daemonization fork here to put the main process (which
3331
   * will become then a master) in background, before it will fork a
3332
   * worker, because the worker should be also in background for this case.
3333
   */
3334
0
  if ((getenv("HAPROXY_MWORKER_REEXEC") == NULL) && (global.mode & MODE_DAEMON)
3335
0
      && !(global.mode & MODE_CHECK))
3336
0
    apply_daemon_mode();
3337
3338
  /* Master-worker and program forks */
3339
0
  if (global.mode & MODE_MWORKER) {
3340
    /* fork worker */
3341
0
    mworker_apply_master_worker_mode();
3342
0
  }
3343
3344
  /* Worker, daemon, foreground modes read the rest of the config */
3345
0
  if (!master) {
3346
0
    usermsgs_clr("config");
3347
0
    if (global.mode & MODE_MWORKER) {
3348
0
      if (clean_env() != 0) {
3349
0
        ha_alert("Worker failed to clean its env, exiting.\n");
3350
0
        exit(EXIT_FAILURE);
3351
0
      }
3352
3353
0
      if (restore_env() != 0) {
3354
0
        ha_alert("Worker failed to restore its env, exiting.\n");
3355
0
        exit(EXIT_FAILURE);
3356
0
      }
3357
0
      setenv("HAPROXY_MWORKER", "1", 1);
3358
0
    }
3359
3360
    /* localpeer default value could be redefined via 'localpeer' keyword
3361
     * from the global section, which has already parsed in MODE_DISCOVERY by
3362
     * read_cfg_in_discovery_mode(). So, let's set HAPROXY_LOCALPEER explicitly
3363
     * here.
3364
     */
3365
0
    setenv("HAPROXY_LOCALPEER", localpeer, 1);
3366
3367
    /* nbthread and *thread keywords parsers are sensible to global
3368
     * section position, it should be placed as the first in
3369
     * the configuration, if these keywords are inside. So, let's
3370
     * reset non_global_section_parsed counter for the second
3371
     * configuration reading
3372
     */
3373
0
    non_global_section_parsed = 0;
3374
0
    if (read_cfg() < 0) {
3375
0
      list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list) {
3376
0
        ha_free(&cfg->content);
3377
0
        ha_free(&cfg->filename);
3378
0
      }
3379
0
      exit(1);
3380
0
    }
3381
    /* all sections have been parsed, we can free the content */
3382
0
    list_for_each_entry_safe(cfg, cfg_tmp, &cfg_cfgfiles, list)
3383
0
      ha_free(&cfg->content);
3384
3385
0
    usermsgs_clr(NULL);
3386
0
  }
3387
3388
  /* Late init step: routines from pre_check_list, functions, which
3389
   * allocate pools, initialize proxies, compute ideal maxconn and
3390
   * initialize postmortem structure.
3391
   */
3392
0
  step_init_2(argc, argv);
3393
3394
0
  RUN_INITCALLS(STG_INIT_2);
3395
  /* Late init step: register signals for worker and standalon modes, apply
3396
   * nofile and memory limits, apply capabilities from binary, if any.
3397
   */
3398
0
  step_init_3();
3399
3400
  /* In standalone or in worker mode get the listeners fds from the previous
3401
   * process using _getsocks on stat socket or on the master CLI socket
3402
   * respectively.
3403
   */
3404
0
  if (!master && old_unixsocket)
3405
0
    get_listeners_fd();
3406
3407
0
  bind_listeners();
3408
3409
  /* worker context: now listeners fds were transferred from the previous
3410
   * worker, all listeners fd are bound. So we can close ipc_fd[0]s of all
3411
   * previous workers, which are still referenced in the proc_list, i.e.
3412
   * they are not exited yet at the moment, when this current worker was
3413
   * forked. Thus the current worker inherits ipc_fd[0]s from the previous
3414
   * ones by it's parent, master, because we have to keep shared sockpair
3415
   * ipc_fd[0] always opened in master (master CLI server is listening on
3416
   * this fd). It's safe to call close() at this point on these inherited
3417
   * ipc_fd[0]s, as they are inherited after master re-exec unbound, we
3418
   * keep them like this during bind_listeners() call. So, these fds were
3419
   * never referenced in the current worker's fdtab.
3420
   */
3421
0
  if ((global.mode & MODE_MWORKER) && !master) {
3422
0
    list_for_each_entry(proc, &proc_list, list) {
3423
0
      if ((proc->options & PROC_O_TYPE_WORKER) && (proc->options & PROC_O_LEAVING)) {
3424
0
        close(proc->ipc_fd[0]);
3425
0
        proc->ipc_fd[0] = -1;
3426
0
      }
3427
0
    }
3428
0
  }
3429
3430
  /* Exit in standalone mode, if no listeners found */
3431
0
  if (!(global.mode & MODE_MWORKER) && listeners == 0) {
3432
0
    ha_alert("[%s.main()] No enabled listener found (check for 'bind' directives) ! Exiting.\n", argv[0]);
3433
    /* Note: we don't have to send anything to the old pids because we
3434
     * never stopped them. */
3435
0
    exit(1);
3436
0
  }
3437
3438
  /* Ok, all listeners should now be bound, close any leftover sockets
3439
   * the previous process gave us, we don't need them anymore
3440
   */
3441
0
  sock_drop_unused_old_sockets();
3442
3443
  /* prepare pause/play signals */
3444
0
  signal_register_fct(SIGTTOU, sig_pause, SIGTTOU);
3445
0
  signal_register_fct(SIGTTIN, sig_listen, SIGTTIN);
3446
3447
  /* Apply verbosity modes, check the process current nofile limit,
3448
   * update the ready date and close the pidfile.
3449
   */
3450
0
  step_init_4();
3451
3452
  /* Master enters in its polling loop */
3453
0
  if (master) {
3454
0
    mworker_run_master();
3455
    /* never get there in master context */
3456
0
  }
3457
3458
  /* End of initialization for standalone and worker modes */
3459
3460
        /* applies the renice value in the worker or standalone after configuration parsing
3461
         * but before changing identity */
3462
0
        if (!master && global.tune.renice_runtime) {
3463
0
    if (setpriority(PRIO_PROCESS, 0, global.tune.renice_runtime - 100) == -1) {
3464
0
      ha_warning("[%s.main()] couldn't set the runtime nice value to %d: %s\n",
3465
0
                 argv[0], global.tune.renice_runtime - 100, strerror(errno));
3466
0
    }
3467
0
  }
3468
3469
  /* Open PID file before the chroot. In master-worker mode, it's master
3470
   * who will create the pidfile, see _send_status().
3471
   */
3472
0
  if (!(global.mode & MODE_MWORKER)) {
3473
0
    if (global.mode & MODE_DAEMON && (global.pidfile != NULL)) {
3474
0
      if (handle_pidfile() < 0) {
3475
0
        if (nb_oldpids) {
3476
0
          tell_old_pids(SIGTTIN);
3477
0
          protocol_unbind_all();
3478
0
        }
3479
0
        exit(1);
3480
0
      }
3481
0
    }
3482
0
  }
3483
3484
  /* Must chroot and setgid/setuid in the children */
3485
  /* chroot if needed */
3486
0
  if (global.chroot != NULL) {
3487
0
    if (chroot(global.chroot) == -1 || chdir("/") == -1) {
3488
0
      ha_alert("[%s.main()] Cannot chroot(%s).\n", argv[0], global.chroot);
3489
0
      if (nb_oldpids)
3490
0
        tell_old_pids(SIGTTIN);
3491
0
      protocol_unbind_all();
3492
0
      exit(1);
3493
0
    }
3494
0
  }
3495
3496
0
  ha_free(&global.chroot);
3497
3498
3499
  /* In standalone mode send USR1/TERM to the previous worker,
3500
   * launched with -sf $(cat pidfile).
3501
   * In master-worker mode, see _send_status(): master process sends
3502
   * USR1/TERM to previous workers up to receiving status READY from the
3503
   * worker, which is newly forked. Then master sends USR1 or TERM to previous
3504
   * master, if it was launched with (-W -D -sf $(cat pidfile).
3505
   */
3506
0
  if (!(global.mode & MODE_MWORKER) && (nb_oldpids > 0)) {
3507
0
    nb_oldpids = tell_old_pids(oldpids_sig);
3508
0
  }
3509
3510
  /* oldpids_sig was sent to the previous process, can change uid/gid now */
3511
0
  set_identity(argv[0]);
3512
3513
  /* set_identity() above might have dropped LSTCHK_NETADM or/and
3514
   * LSTCHK_SYSADM if it changed to a new UID while preserving enough
3515
   * permissions to honnor LSTCHK_NETADM/LSTCHK_SYSADM.
3516
   */
3517
0
  if ((global.last_checks & (LSTCHK_NETADM|LSTCHK_SYSADM)) && getuid()) {
3518
    /* If global.uid is present in config, it is already set as euid
3519
     * and ruid by set_identity() just above, so it's better to
3520
     * remind the user to fix uncoherent settings.
3521
     */
3522
0
    if (global.uid > 0) {
3523
0
      ha_alert("[%s.main()] Some configuration options require full "
3524
0
         "privileges, so global.uid cannot be changed.\n", argv[0]);
3525
#if defined(USE_LINUX_CAP)
3526
      ha_alert("[%s.main()] Alternately, if your system supports "
3527
               "Linux capabilities, you may also consider using "
3528
               "'setcap cap_net_raw', 'setcap cap_net_admin' or "
3529
               "'setcap cap_sys_admin' in the 'global' section.\n", argv[0]);
3530
#endif
3531
0
      protocol_unbind_all();
3532
0
      exit(1);
3533
0
    }
3534
    /* If the user is not root, we'll still let them try the configuration
3535
     * but we inform them that unexpected behaviour may occur.
3536
     */
3537
0
    ha_warning("[%s.main()] Some options which require full privileges"
3538
0
         " might not work well.\n", argv[0]);
3539
0
  }
3540
3541
0
  if (global.uid < 0 && geteuid() == 0)
3542
0
    ha_warning("[%s.main()] HAProxy was started as the root user and does "
3543
0
         "not make use of 'user' nor 'uid' global options to drop the "
3544
0
         "privileges. This is generally considered as a bad practice "
3545
0
         "security-wise. If running as root is intentional, please make "
3546
0
         "it explicit using 'uid 0' or 'user root', and also please "
3547
0
         "consider using the 'chroot' directive to isolate the process "
3548
0
         "into a totally empty and read-only directory if possible."
3549
#if defined(USE_LINUX_CAP)
3550
         " Also, since your operating system supports it, always prefer "
3551
         "relying on capabilities with unprivileged users than running "
3552
         "with full privileges (look for 'setcap' in the configuration"
3553
         "manual)."
3554
#endif
3555
0
         "\n", argv[0]);
3556
3557
  /*
3558
   * This is only done in daemon mode because we might want the
3559
   * logs on stdout in mworker mode. If we're NOT in QUIET mode,
3560
   * we should now close the 3 first FDs to ensure that we can
3561
   * detach from the TTY. We MUST NOT do it in other cases since
3562
   * it would have already be done, and 0-2 would have been
3563
   * affected to listening sockets
3564
   */
3565
0
  if ((global.mode & MODE_DAEMON) &&
3566
0
    (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
3567
    /* detach from the tty */
3568
0
    stdio_quiet(devnullfd);
3569
0
    global.mode &= ~MODE_VERBOSE;
3570
0
    global.mode |= MODE_QUIET; /* ensure that we won't say anything from now */
3571
0
  }
3572
0
  close(devnullfd);
3573
0
  devnullfd = -1;
3574
0
  pid = getpid(); /* update pid */
3575
3576
  /* This call is expensive, as it creates a new poller, scans and tries
3577
   * to migrate to it all existing FDs until the highest known one. With
3578
   * very high numbers of FDs, this can take several seconds to start.
3579
   * So, it's only desirable for modes, when we perform a fork().
3580
   */
3581
0
  if (global.mode & MODE_DAEMON)
3582
0
    fork_poller();
3583
3584
  /* pass through every cli socket, and check if it's bound to
3585
   * the current process and if it exposes listeners sockets.
3586
   * Caution: the GTUNE_SOCKET_TRANSFER is now set after the fork.
3587
   * */
3588
3589
0
  if (global.cli_fe) {
3590
0
    struct bind_conf *bind_conf;
3591
3592
0
    list_for_each_entry(bind_conf, &global.cli_fe->conf.bind, by_fe) {
3593
0
      if (bind_conf->level & ACCESS_FD_LISTENERS) {
3594
0
        global.tune.options |= GTUNE_SOCKET_TRANSFER;
3595
0
        break;
3596
0
      }
3597
0
    }
3598
0
  }
3599
3600
  /* Note that here we can't be in the parent/master anymore */
3601
#if !defined(USE_THREAD) && defined(USE_CPU_AFFINITY)
3602
  if (ha_cpuset_count(&cpu_map[0].thread[0])) {   /* only do this if the process has a CPU map */
3603
3604
#if defined(CPUSET_USE_CPUSET) || defined(__DragonFly__)
3605
    struct hap_cpuset *set = &cpu_map[0].thread[0];
3606
    sched_setaffinity(0, sizeof(set->cpuset), &set->cpuset);
3607
#elif defined(__FreeBSD__)
3608
    struct hap_cpuset *set = &cpu_map[0].thread[0];
3609
    ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set->cpuset), &set->cpuset);
3610
#endif
3611
  }
3612
#endif
3613
  /* try our best to re-enable core dumps depending on system capabilities.
3614
   * What is addressed here :
3615
   *   - remove file size limits
3616
   *   - remove core size limits
3617
   *   - mark the process dumpable again if it lost it due to user/group
3618
   */
3619
0
  if (global.tune.options & GTUNE_SET_DUMPABLE) {
3620
0
    limit.rlim_cur = limit.rlim_max = RLIM_INFINITY;
3621
3622
0
#if defined(RLIMIT_FSIZE)
3623
0
    if (setrlimit(RLIMIT_FSIZE, &limit) == -1) {
3624
0
      if (global.tune.options & GTUNE_STRICT_LIMITS) {
3625
0
        ha_alert("[%s.main()] Failed to set the raise the maximum "
3626
0
           "file size.\n", argv[0]);
3627
0
        exit(1);
3628
0
      }
3629
0
      else
3630
0
        ha_warning("[%s.main()] Failed to set the raise the maximum "
3631
0
             "file size.\n", argv[0]);
3632
0
    }
3633
0
#endif
3634
3635
0
#if defined(RLIMIT_CORE)
3636
0
    if (setrlimit(RLIMIT_CORE, &limit) == -1) {
3637
0
      if (global.tune.options & GTUNE_STRICT_LIMITS) {
3638
0
        ha_alert("[%s.main()] Failed to set the raise the core "
3639
0
           "dump size.\n", argv[0]);
3640
0
        exit(1);
3641
0
      }
3642
0
      else
3643
0
        ha_warning("[%s.main()] Failed to set the raise the core "
3644
0
             "dump size.\n", argv[0]);
3645
0
    }
3646
0
#endif
3647
3648
#if defined(USE_PRCTL)
3649
    if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1)
3650
      ha_warning("[%s.main()] Failed to set the dumpable flag, "
3651
           "no core will be dumped.\n", argv[0]);
3652
#elif defined(USE_PROCCTL)
3653
    {
3654
      int traceable = PROC_TRACE_CTL_ENABLE;
3655
      if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &traceable) == -1)
3656
        ha_warning("[%s.main()] Failed to set the traceable flag, "
3657
             "no core will be dumped.\n", argv[0]);
3658
    }
3659
#endif
3660
0
  }
3661
3662
3663
  /* start threads 2 and above */
3664
0
  setup_extra_threads(&run_thread_poll_loop);
3665
3666
  /* when multithreading we need to let only the thread 0 handle the signals */
3667
0
  haproxy_unblock_signals();
3668
3669
  /* send "READY" message to remove status PROC_O_INIT for the newly forked worker,
3670
   * master will send TERM to the previous in _send_status()
3671
   */
3672
0
  if (global.mode & MODE_MWORKER) {
3673
0
    struct mworker_proc *proc;
3674
0
    int sock_pair[2];
3675
0
    char *msg = NULL;
3676
0
    char c;
3677
0
    int r __maybe_unused;
3678
3679
0
    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sock_pair) == -1) {
3680
0
      ha_alert("[%s.main()] Cannot create socketpair to update the new worker state\n",
3681
0
         argv[0]);
3682
3683
0
      exit(1);
3684
0
    }
3685
3686
0
    list_for_each_entry(proc, &proc_list, list) {
3687
0
      if (proc->pid == -1)
3688
0
        break;
3689
0
    }
3690
3691
0
    if (send_fd_uxst(proc->ipc_fd[1], sock_pair[0]) == -1) {
3692
0
      ha_alert("[%s.main()] Cannot transfer connection fd %d over the sockpair@%d\n",
3693
0
         argv[0], sock_pair[0], proc->ipc_fd[1]);
3694
0
      close(sock_pair[0]);
3695
0
      close(sock_pair[1]);
3696
3697
0
      exit(1);
3698
0
    }
3699
3700
0
    memprintf(&msg, "_send_status READY %d\n", getpid());
3701
0
    if (send(sock_pair[1], msg, strlen(msg), 0) != strlen(msg)) {
3702
0
      ha_alert("[%s.main()] Failed to send READY status to master\n", argv[0]);
3703
3704
0
      exit(1);
3705
0
    }
3706
3707
    /* in macOS, the sock_pair[0] might be received in the master
3708
     * process after it was closed in the worker, which is a
3709
     * documented bug in sendmsg(2). We need to close the fd only
3710
     * after confirming receipt of the "\n" from the CLI applet, so
3711
     * we make sure that the fd is received correctly.
3712
     */
3713
0
    shutdown(sock_pair[1], SHUT_WR);
3714
0
    r = read(sock_pair[1], &c, 1);
3715
0
    close(sock_pair[1]);
3716
0
    close(sock_pair[0]);
3717
0
    ha_free(&msg);
3718
3719
    /* at this point the worker must have his own startup_logs buffer */
3720
0
    tmp_startup_logs = startup_logs_dup(startup_logs);
3721
0
    if (tmp_startup_logs == NULL)
3722
0
      exit(EXIT_FAILURE);
3723
0
    startup_logs_free(startup_logs);
3724
0
    startup_logs = tmp_startup_logs;
3725
0
  }
3726
3727
  /* worker is already sent its READY message to master. This applies only
3728
   * for daemon standalone mode. Master in daemon mode will "forward" the READY
3729
   * message received from the worker to the launching process, see _send_status().
3730
   */
3731
0
  if ((global.mode & MODE_DAEMON) && !(global.mode & MODE_MWORKER)) {
3732
0
    const char *msg = "READY\n";
3733
3734
0
    if (write(daemon_fd[1], msg, strlen(msg)) < 0) {
3735
0
      ha_alert("[%s.main()] Failed to write into pipe with parent process: %s\n", progname, strerror(errno));
3736
0
      exit(1);
3737
0
    }
3738
0
    close(daemon_fd[1]);
3739
0
    daemon_fd[1] = -1;
3740
0
  }
3741
  /* can't unset MODE_STARTING earlier, otherwise worker's last alerts
3742
   * should be not written in startup logs.
3743
   */
3744
0
  global.mode &= ~MODE_STARTING;
3745
0
  reset_usermsgs_ctx();
3746
3747
  /* Finally, start the poll loop for the first thread */
3748
0
  run_thread_poll_loop(&ha_thread_info[0]);
3749
3750
  /* wait for all threads to terminate */
3751
0
  wait_for_threads_completion();
3752
3753
0
  deinit_and_exit(0);
3754
0
}
3755
3756
/*
3757
 * Local variables:
3758
 *  c-indent-level: 8
3759
 *  c-basic-offset: 8
3760
 * End:
3761
 */