Coverage Report

Created: 2026-02-26 07:07

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