404
415
else if (!strcmp(args[0], "tune.maxpollevents")) {
405
416
if (global.tune.maxpollevents != 0) {
406
417
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
418
err_code |= ERR_ALERT;
409
421
if (*(args[1]) == 0) {
410
422
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
423
err_code |= ERR_ALERT | ERR_FATAL;
413
426
global.tune.maxpollevents = atol(args[1]);
415
428
else if (!strcmp(args[0], "tune.maxaccept")) {
416
429
if (global.tune.maxaccept != 0) {
417
430
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
431
err_code |= ERR_ALERT;
420
434
if (*(args[1]) == 0) {
421
435
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
436
err_code |= ERR_ALERT | ERR_FATAL;
424
439
global.tune.maxaccept = atol(args[1]);
426
441
else if (!strcmp(args[0], "uid")) {
427
442
if (global.uid != 0) {
428
443
Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
444
err_code |= ERR_ALERT;
431
447
if (*(args[1]) == 0) {
432
448
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
449
err_code |= ERR_ALERT | ERR_FATAL;
435
452
global.uid = atol(args[1]);
437
454
else if (!strcmp(args[0], "gid")) {
438
455
if (global.gid != 0) {
439
456
Alert("parsing [%s:%d] : group/gid already specified. Continuing.\n", file, linenum);
457
err_code |= ERR_ALERT;
442
460
if (*(args[1]) == 0) {
443
461
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
462
err_code |= ERR_ALERT | ERR_FATAL;
446
465
global.gid = atol(args[1]);
477
498
Alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
499
err_code |= ERR_ALERT | ERR_FATAL;
481
502
/* end of user/group name handling*/
482
503
else if (!strcmp(args[0], "nbproc")) {
483
504
if (global.nbproc != 0) {
484
505
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
506
err_code |= ERR_ALERT;
487
509
if (*(args[1]) == 0) {
488
510
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
511
err_code |= ERR_ALERT | ERR_FATAL;
491
514
global.nbproc = atol(args[1]);
493
516
else if (!strcmp(args[0], "maxconn")) {
494
517
if (global.maxconn != 0) {
495
518
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
519
err_code |= ERR_ALERT;
498
522
if (*(args[1]) == 0) {
499
523
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
524
err_code |= ERR_ALERT | ERR_FATAL;
502
527
global.maxconn = atol(args[1]);
503
528
#ifdef SYSTEM_MAXCONN
504
529
if (global.maxconn > DEFAULT_MAXCONN && cfg_maxconn <= DEFAULT_MAXCONN) {
505
530
Alert("parsing [%s:%d] : maxconn value %d too high for this system.\nLimiting to %d. Please use '-n' to force the value.\n", file, linenum, global.maxconn, DEFAULT_MAXCONN);
506
531
global.maxconn = DEFAULT_MAXCONN;
532
err_code |= ERR_ALERT;
508
534
#endif /* SYSTEM_MAXCONN */
510
536
else if (!strcmp(args[0], "maxpipes")) {
511
537
if (global.maxpipes != 0) {
512
538
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
539
err_code |= ERR_ALERT;
515
542
if (*(args[1]) == 0) {
516
543
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
544
err_code |= ERR_ALERT | ERR_FATAL;
519
547
global.maxpipes = atol(args[1]);
521
549
else if (!strcmp(args[0], "ulimit-n")) {
522
550
if (global.rlimit_nofile != 0) {
523
551
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
552
err_code |= ERR_ALERT;
526
555
if (*(args[1]) == 0) {
527
556
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
557
err_code |= ERR_ALERT | ERR_FATAL;
530
560
global.rlimit_nofile = atol(args[1]);
532
562
else if (!strcmp(args[0], "chroot")) {
533
563
if (global.chroot != NULL) {
534
564
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
565
err_code |= ERR_ALERT;
537
568
if (*(args[1]) == 0) {
538
569
Alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
570
err_code |= ERR_ALERT | ERR_FATAL;
541
573
global.chroot = strdup(args[1]);
575
else if (!strcmp(args[0], "description")) {
580
Alert("parsing [%s:%d]: '%s' expects a string argument.\n",
581
file, linenum, args[0]);
582
err_code |= ERR_ALERT | ERR_FATAL;
586
for(i=1; *args[i]; i++)
587
len += strlen(args[i])+1;
592
global.desc = d = (char *)calloc(1, len);
594
d += sprintf(d, "%s", args[1]);
595
for(i=2; *args[i]; i++)
596
d += sprintf(d, " %s", args[i]);
598
else if (!strcmp(args[0], "node")) {
602
for (i=0; args[1][i]; i++) {
604
if (!isupper(c) && !islower(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
608
if (!i || args[1][i]) {
609
Alert("parsing [%s:%d]: '%s' requires valid node name - non-empty string"
610
" with digits(0-9), letters(A-Z, a-z), dot(.), hyphen(-) or underscode(_).\n",
611
file, linenum, args[0]);
612
err_code |= ERR_ALERT | ERR_FATAL;
619
global.node = strdup(args[1]);
543
621
else if (!strcmp(args[0], "pidfile")) {
544
622
if (global.pidfile != NULL) {
545
623
Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
624
err_code |= ERR_ALERT;
548
627
if (*(args[1]) == 0) {
549
628
Alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
629
err_code |= ERR_ALERT | ERR_FATAL;
552
632
global.pidfile = strdup(args[1]);
961
1069
Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
962
1070
file, linenum, args[0], args[cur_arg]);
1071
err_code |= ERR_ALERT | ERR_FATAL;
966
1075
Alert("parsing [%s:%d] : '%s' only supports the 'transparent' and 'interface' options.\n",
967
1076
file, linenum, args[0]);
1077
err_code |= ERR_ALERT | ERR_FATAL;
970
1080
global.maxsock++;
973
1083
else if (!strcmp(args[0], "monitor-net")) { /* set the range of IPs to ignore */
974
1084
if (!*args[1] || !str2net(args[1], &curproxy->mon_net, &curproxy->mon_mask)) {
975
1085
Alert("parsing [%s:%d] : '%s' expects address[/mask].\n",
976
1086
file, linenum, args[0]);
1087
err_code |= ERR_ALERT | ERR_FATAL;
979
1090
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
1091
err_code |= ERR_WARN;
982
1093
/* flush useless bits */
983
1094
curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
986
1097
else if (!strcmp(args[0], "monitor-uri")) { /* set the URI to intercept */
987
1098
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
1099
err_code |= ERR_WARN;
990
1101
if (!*args[1]) {
991
1102
Alert("parsing [%s:%d] : '%s' expects an URI.\n",
992
1103
file, linenum, args[0]);
1104
err_code |= ERR_ALERT | ERR_FATAL;
996
1108
free(curproxy->monitor_uri);
1016
1129
if (curproxy == &defproxy) {
1017
1130
Alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
1018
1131
file, linenum, args[0]);
1132
err_code |= ERR_ALERT | ERR_FATAL;
1022
1136
if (!*args[1]) {
1023
1137
Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
1024
1138
file, linenum, args[0]);
1139
err_code |= ERR_ALERT | ERR_FATAL;
1028
1143
curproxy->uuid = atol(args[1]);
1030
1145
if (curproxy->uuid < 1001) {
1031
Alert("parsing [%s:%d]: custom id has to be > 1000",
1146
Alert("parsing [%s:%d]: custom id has to be > 1000.\n",
1032
1147
file, linenum);
1148
err_code |= ERR_ALERT | ERR_FATAL;
1036
1152
for (target = proxy; target; target = target->next)
1037
1153
if (curproxy != target && curproxy->uuid == target->uuid) {
1038
1154
Alert("parsing [%s:%d]: custom id has to be unique but is duplicated in %s and %s.\n",
1039
1155
file, linenum, curproxy->id, target->id);
1156
err_code |= ERR_ALERT | ERR_FATAL;
1160
else if (!strcmp(args[0], "description")) {
1165
Alert("parsing [%s:%d]: '%s' expects a string argument.\n",
1166
file, linenum, args[0]);
1170
for(i=1; *args[i]; i++)
1171
len += strlen(args[i])+1;
1173
d = (char *)calloc(1, len);
1176
d += sprintf(d, "%s", args[1]);
1177
for(i=2; *args[i]; i++)
1178
d += sprintf(d, " %s", args[i]);
1043
1181
else if (!strcmp(args[0], "disabled")) { /* disables this proxy */
1044
1182
curproxy->state = PR_STSTOPPED;
1512
1688
else if (!strcmp(args[0], "stats")) {
1513
1689
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1690
err_code |= ERR_WARN;
1516
1692
if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
1517
1693
curproxy->uri_auth = NULL; /* we must detach from the default config */
1519
1695
if (*(args[1]) == 0) {
1520
Alert("parsing [%s:%d] : '%s' expects 'uri', 'realm', 'auth', 'scope' or 'enable'.\n", file, linenum, args[0]);
1696
Alert("parsing [%s:%d] : '%s' expects 'uri', 'realm', 'auth', 'scope' or 'enable', 'hide-version', 'show-node', 'show-desc'.\n", file, linenum, args[0]);
1697
err_code |= ERR_ALERT | ERR_FATAL;
1522
1699
} else if (!strcmp(args[1], "uri")) {
1523
1700
if (*(args[2]) == 0) {
1524
1701
Alert("parsing [%s:%d] : 'uri' needs an URI prefix.\n", file, linenum);
1702
err_code |= ERR_ALERT | ERR_FATAL;
1526
1704
} else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
1527
1705
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1706
err_code |= ERR_ALERT | ERR_ABORT;
1530
1709
} else if (!strcmp(args[1], "realm")) {
1531
1710
if (*(args[2]) == 0) {
1532
1711
Alert("parsing [%s:%d] : 'realm' needs an realm name.\n", file, linenum);
1712
err_code |= ERR_ALERT | ERR_FATAL;
1534
1714
} else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
1535
1715
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1716
err_code |= ERR_ALERT | ERR_ABORT;
1538
1719
} else if (!strcmp(args[1], "refresh")) {
1539
1720
unsigned interval;
1543
1724
Alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
1544
1725
file, linenum, *err);
1726
err_code |= ERR_ALERT | ERR_FATAL;
1546
1728
} else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
1547
1729
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1730
err_code |= ERR_ALERT | ERR_ABORT;
1550
1733
} else if (!strcmp(args[1], "auth")) {
1551
1734
if (*(args[2]) == 0) {
1552
1735
Alert("parsing [%s:%d] : 'auth' needs a user:password account.\n", file, linenum);
1736
err_code |= ERR_ALERT | ERR_FATAL;
1554
1738
} else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
1555
1739
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1740
err_code |= ERR_ALERT | ERR_ABORT;
1558
1743
} else if (!strcmp(args[1], "scope")) {
1559
1744
if (*(args[2]) == 0) {
1560
1745
Alert("parsing [%s:%d] : 'scope' needs a proxy name.\n", file, linenum);
1746
err_code |= ERR_ALERT | ERR_FATAL;
1562
1748
} else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
1563
1749
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1750
err_code |= ERR_ALERT | ERR_ABORT;
1566
1753
} else if (!strcmp(args[1], "enable")) {
1567
1754
if (!stats_check_init_uri_auth(&curproxy->uri_auth)) {
1568
1755
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1756
err_code |= ERR_ALERT | ERR_ABORT;
1571
1759
} else if (!strcmp(args[1], "hide-version")) {
1572
1760
if (!stats_set_flag(&curproxy->uri_auth, ST_HIDEVER)) {
1573
1761
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1762
err_code |= ERR_ALERT | ERR_ABORT;
1765
} else if (!strcmp(args[1], "show-node")) {
1771
for (i=0; args[2][i]; i++) {
1773
if (!isupper(c) && !islower(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
1777
if (!i || args[2][i]) {
1778
Alert("parsing [%s:%d]: '%s %s' invalid node name - should be a string"
1779
"with digits(0-9), letters(A-Z, a-z), hyphen(-) or underscode(_).\n",
1780
file, linenum, args[0], args[1]);
1781
err_code |= ERR_ALERT | ERR_FATAL;
1786
if (!stats_set_node(&curproxy->uri_auth, args[2])) {
1787
Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
1788
err_code |= ERR_ALERT | ERR_ABORT;
1791
} else if (!strcmp(args[1], "show-desc")) {
1798
for(i=2; *args[i]; i++)
1799
len += strlen(args[i])+1;
1801
desc = d = (char *)calloc(1, len);
1803
d += sprintf(d, "%s", args[2]);
1804
for(i=3; *args[i]; i++)
1805
d += sprintf(d, " %s", args[i]);
1808
if (!*args[2] && !global.desc)
1809
Warning("parsing [%s:%d]: '%s' requires a parameter or 'desc' to be set in the global section.\n",
1810
file, linenum, args[1]);
1812
if (!stats_set_desc(&curproxy->uri_auth, desc)) {
1814
Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
1815
err_code |= ERR_ALERT | ERR_ABORT;
1577
1821
Alert("parsing [%s:%d] : unknown stats parameter '%s' (expects 'hide-version', 'uri', 'realm', 'auth' or 'enable').\n",
1578
1822
file, linenum, args[0]);
1823
err_code |= ERR_ALERT | ERR_FATAL;
1582
1827
else if (!strcmp(args[0], "option")) {
1585
1830
if (*(args[1]) == '\0') {
1586
1831
Alert("parsing [%s:%d]: '%s' expects an option name.\n",
1587
1832
file, linenum, args[0]);
1833
err_code |= ERR_ALERT | ERR_FATAL;
1591
1837
for (optnum = 0; cfg_opts[optnum].name; optnum++) {
1592
1838
if (!strcmp(args[1], cfg_opts[optnum].name)) {
1593
if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL))
1839
if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
1840
err_code |= ERR_WARN;
1597
1845
curproxy->options |= cfg_opts[optnum].val;
1599
1847
curproxy->options &= ~cfg_opts[optnum].val;
1605
1853
for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
1606
1854
if (!strcmp(args[1], cfg_opts2[optnum].name)) {
1607
if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL))
1855
if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
1856
err_code |= ERR_WARN;
1611
1861
curproxy->options2 |= cfg_opts2[optnum].val;
1613
1863
curproxy->options2 &= ~cfg_opts2[optnum].val;
1620
1870
Alert("parsing [%s:%d]: negation is not supported for option '%s'.\n",
1621
1871
file, linenum, args[1]);
1872
err_code |= ERR_ALERT | ERR_FATAL;
1625
1876
if (!strcmp(args[1], "httplog"))
1786
2043
/* unknown suboption - catchall */
1787
2044
Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
1788
2045
file, linenum, args[0], args[1]);
2046
err_code |= ERR_ALERT | ERR_FATAL;
1791
2049
} /* end while loop */
1794
2052
Alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
2053
err_code |= ERR_ALERT | ERR_FATAL;
1799
2058
else if (!strcmp(args[0], "default_backend")) {
1800
2059
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
2060
err_code |= ERR_WARN;
1803
2062
if (*(args[1]) == 0) {
1804
2063
Alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
2064
err_code |= ERR_ALERT | ERR_FATAL;
1807
2067
free(curproxy->defbe.name);
1808
2068
curproxy->defbe.name = strdup(args[1]);
1810
2070
else if (!strcmp(args[0], "redispatch") || !strcmp(args[0], "redisp")) {
1811
2071
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2072
err_code |= ERR_WARN;
1814
2074
Warning("parsing [%s:%d]: keyword '%s' is deprecated, please use 'option redispatch' instead.\n",
1815
2075
file, linenum, args[0]);
2076
err_code |= ERR_WARN;
1817
2077
/* enable reconnections to dispatch */
1818
2078
curproxy->options |= PR_O_REDISP;
1820
2080
else if (!strcmp(args[0], "http-check")) {
1821
2081
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2082
err_code |= ERR_WARN;
1824
2084
if (strcmp(args[1], "disable-on-404") == 0) {
1825
2085
/* enable a graceful server shutdown on an HTTP 404 response */
1877
2142
else if (!strcmp(args[0], "maxconn")) { /* maxconn */
1878
2143
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?"))
2144
err_code |= ERR_WARN;
1881
2146
if (*(args[1]) == 0) {
1882
2147
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
2148
err_code |= ERR_ALERT | ERR_FATAL;
1885
2151
curproxy->maxconn = atol(args[1]);
1887
2153
else if (!strcmp(args[0], "backlog")) { /* backlog */
1888
2154
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
2155
err_code |= ERR_WARN;
1891
2157
if (*(args[1]) == 0) {
1892
2158
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
2159
err_code |= ERR_ALERT | ERR_FATAL;
1895
2162
curproxy->backlog = atol(args[1]);
1897
2164
else if (!strcmp(args[0], "fullconn")) { /* fullconn */
1898
2165
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], " Maybe you want 'maxconn' instead ?"))
2166
err_code |= ERR_WARN;
1901
2168
if (*(args[1]) == 0) {
1902
2169
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
2170
err_code |= ERR_ALERT | ERR_FATAL;
1905
2173
curproxy->fullconn = atol(args[1]);
1907
2175
else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
1908
2176
if (*(args[1]) == 0) {
1909
2177
Alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
2178
err_code |= ERR_ALERT | ERR_FATAL;
1912
2181
err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1914
2183
Alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
1915
2184
file, linenum, *err);
2185
err_code |= ERR_ALERT | ERR_FATAL;
1918
2188
curproxy->grace = val;
1920
2190
else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
1921
2191
if (curproxy == &defproxy) {
1922
2192
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2193
err_code |= ERR_ALERT | ERR_FATAL;
1925
2196
else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2197
err_code |= ERR_WARN;
1928
2199
if (strchr(args[1], ':') == NULL) {
1929
2200
Alert("parsing [%s:%d] : '%s' expects <addr:port> as argument.\n", file, linenum, args[0]);
2201
err_code |= ERR_ALERT | ERR_FATAL;
1932
2204
curproxy->dispatch_addr = *str2sa(args[1]);
1934
2206
else if (!strcmp(args[0], "balance")) { /* set balancing with optional algorithm */
1935
2207
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2208
err_code |= ERR_WARN;
1938
2210
memcpy(trash, "error near 'balance'", 21);
1939
2211
if (backend_parse_balance((const char **)args + 1, trash, sizeof(trash), curproxy) < 0) {
1940
2212
Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
2213
err_code |= ERR_ALERT | ERR_FATAL;
1944
2217
else if (!strcmp(args[0], "server")) { /* server address */
2059
2339
else if (!strcmp(args[cur_arg], "rise")) {
2340
if (!*args[cur_arg + 1]) {
2341
Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
2342
file, linenum, args[cur_arg]);
2343
err_code |= ERR_ALERT | ERR_FATAL;
2060
2347
newsrv->rise = atol(args[cur_arg + 1]);
2348
if (newsrv->rise <= 0) {
2349
Alert("parsing [%s:%d]: '%s' has to be > 0.\n",
2350
file, linenum, args[cur_arg]);
2351
err_code |= ERR_ALERT | ERR_FATAL;
2061
2355
newsrv->health = newsrv->rise;
2064
2358
else if (!strcmp(args[cur_arg], "fall")) {
2065
2359
newsrv->fall = atol(args[cur_arg + 1]);
2361
if (!*args[cur_arg + 1]) {
2362
Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
2363
file, linenum, args[cur_arg]);
2364
err_code |= ERR_ALERT | ERR_FATAL;
2368
if (newsrv->fall <= 0) {
2369
Alert("parsing [%s:%d]: '%s' has to be > 0.\n",
2370
file, linenum, args[cur_arg]);
2371
err_code |= ERR_ALERT | ERR_FATAL;
2068
2377
else if (!strcmp(args[cur_arg], "inter")) {
2181
2500
else if (!strcmp(args[cur_arg], "source")) { /* address to which we bind when connecting */
2501
int port_low, port_high;
2182
2502
if (!*args[cur_arg + 1]) {
2183
2503
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
2184
Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optional '%s' <addr> as argument.\n",
2504
Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>[-<port>]], and optional '%s' <addr> as argument.\n",
2185
2505
file, linenum, "source", "usesrc");
2187
Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>] as argument.\n",
2507
Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>[-<port>]] as argument.\n",
2188
2508
file, linenum, "source");
2510
err_code |= ERR_ALERT | ERR_FATAL;
2192
2513
newsrv->state |= SRV_BIND_SRC;
2193
newsrv->source_addr = *str2sa(args[cur_arg + 1]);
2514
newsrv->source_addr = *str2sa_range(args[cur_arg + 1], &port_low, &port_high);
2516
if (port_low != port_high) {
2518
if (port_low <= 0 || port_low > 65535 ||
2519
port_high <= 0 || port_high > 65535 ||
2520
port_low > port_high) {
2521
Alert("parsing [%s:%d] : invalid source port range %d-%d.\n",
2522
file, linenum, port_low, port_high);
2523
err_code |= ERR_ALERT | ERR_FATAL;
2526
newsrv->sport_range = port_range_alloc_range(port_high - port_low + 1);
2527
for (i = 0; i < newsrv->sport_range->size; i++)
2528
newsrv->sport_range->ports[i] = port_low + i;
2195
2532
while (*(args[cur_arg])) {
2196
2533
if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside */
2459
2812
Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
2460
2813
file, linenum, args[0], args[cur_arg]);
2814
err_code |= ERR_ALERT | ERR_FATAL;
2466
2820
Alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
2467
2821
file, linenum, args[0], "inteface", "usesrc");
2822
err_code |= ERR_ALERT | ERR_FATAL;
2471
2826
else if (!strcmp(args[0], "usesrc")) { /* address to use outside: needs "source" first */
2472
2827
Alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
2473
2828
file, linenum, "usesrc", "source");
2829
err_code |= ERR_ALERT | ERR_FATAL;
2476
2832
else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
2478
2834
if (curproxy == &defproxy) {
2479
2835
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2836
err_code |= ERR_ALERT | ERR_FATAL;
2482
2839
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2840
err_code |= ERR_WARN;
2485
2842
if (*(args[1]) == 0 || *(args[2]) == 0) {
2486
2843
Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
2487
2844
file, linenum, args[0]);
2845
err_code |= ERR_ALERT | ERR_FATAL;
2491
2849
preg = calloc(1, sizeof(regex_t));
2492
2850
if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2493
2851
Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2852
err_code |= ERR_ALERT | ERR_FATAL;
2497
2856
err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]));
2499
2858
Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2500
2859
file, linenum, *err);
2860
err_code |= ERR_ALERT | ERR_FATAL;
2503
2862
warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
2668
3050
if (curproxy == &defproxy) {
2669
3051
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
3052
err_code |= ERR_ALERT | ERR_FATAL;
2672
3055
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
3056
err_code |= ERR_WARN;
2675
3058
if (*(args[1]) == 0 || *(args[2]) == 0) {
2676
3059
Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
2677
3060
file, linenum, args[0]);
3061
err_code |= ERR_ALERT | ERR_FATAL;
2681
3065
preg = calloc(1, sizeof(regex_t));
2682
3066
if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2683
3067
Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
3068
err_code |= ERR_ALERT | ERR_FATAL;
2687
3072
err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]));
2689
3074
Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2690
3075
file, linenum, *err);
3076
err_code |= ERR_ALERT | ERR_FATAL;
2693
3079
warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
2858
3265
if (curproxy == &defproxy) {
2859
3266
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
3267
err_code |= ERR_ALERT | ERR_FATAL;
2862
3270
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
3271
err_code |= ERR_WARN;
2865
3273
if (*(args[1]) == 0) {
2866
3274
Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
3275
err_code |= ERR_ALERT | ERR_FATAL;
2870
3279
preg = calloc(1, sizeof(regex_t));
2871
3280
if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2872
3281
Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
3282
err_code |= ERR_ALERT | ERR_FATAL;
2876
3286
err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]));
2878
3288
Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2879
3289
file, linenum, *err);
3290
err_code |= ERR_ALERT | ERR_FATAL;
2883
3294
else if (!strcmp(args[0], "rspdeny")) { /* block response header from a regex */
2885
3296
if (curproxy == &defproxy) {
2886
3297
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
3298
err_code |= ERR_ALERT | ERR_FATAL;
2889
3301
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
3302
err_code |= ERR_WARN;
2892
3304
if (*(args[1]) == 0) {
2893
3305
Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
3306
err_code |= ERR_ALERT | ERR_FATAL;
2897
3310
preg = calloc(1, sizeof(regex_t));
2898
3311
if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2899
3312
Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
3313
err_code |= ERR_ALERT | ERR_FATAL;
2903
3317
err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]));
2905
3319
Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2906
3320
file, linenum, *err);
3321
err_code |= ERR_ALERT | ERR_FATAL;
2910
3325
else if (!strcmp(args[0], "rspirep")) { /* replace response header from a regex ignoring case */
2912
3327
if (curproxy == &defproxy) {
2913
3328
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
3329
err_code |= ERR_ALERT | ERR_FATAL;
2916
3332
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
3333
err_code |= ERR_WARN;
2919
3335
if (*(args[1]) == 0 || *(args[2]) == 0) {
2920
3336
Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
2921
3337
file, linenum, args[0]);
3338
err_code |= ERR_ALERT | ERR_FATAL;
2925
3342
preg = calloc(1, sizeof(regex_t));
2926
3343
if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2927
3344
Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
3345
err_code |= ERR_ALERT | ERR_FATAL;
2931
3349
err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2]));
2933
3351
Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2934
3352
file, linenum, *err);
3353
err_code |= ERR_ALERT | ERR_FATAL;
2938
3357
else if (!strcmp(args[0], "rspidel")) { /* delete response header from a regex ignoring case */
2940
3359
if (curproxy == &defproxy) {
2941
3360
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
3361
err_code |= ERR_ALERT | ERR_FATAL;
2944
3364
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
3365
err_code |= ERR_WARN;
2947
3367
if (*(args[1]) == 0) {
2948
3368
Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
3369
err_code |= ERR_ALERT | ERR_FATAL;
2952
3373
preg = calloc(1, sizeof(regex_t));
2953
3374
if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2954
3375
Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
3376
err_code |= ERR_ALERT | ERR_FATAL;
2958
3380
err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]));
2960
3382
Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2961
3383
file, linenum, *err);
3384
err_code |= ERR_ALERT | ERR_FATAL;
2965
3388
else if (!strcmp(args[0], "rspideny")) { /* block response header from a regex ignoring case */
2967
3390
if (curproxy == &defproxy) {
2968
3391
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
3392
err_code |= ERR_ALERT | ERR_FATAL;
2971
3395
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
3396
err_code |= ERR_WARN;
2974
3398
if (*(args[1]) == 0) {
2975
3399
Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
3400
err_code |= ERR_ALERT | ERR_FATAL;
2979
3404
preg = calloc(1, sizeof(regex_t));
2980
3405
if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2981
3406
Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
3407
err_code |= ERR_ALERT | ERR_FATAL;
2985
3411
err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]));
2987
3413
Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2988
3414
file, linenum, *err);
3415
err_code |= ERR_ALERT | ERR_FATAL;
2992
3419
else if (!strcmp(args[0], "rspadd")) { /* add response header */
2993
3420
if (curproxy == &defproxy) {
2994
3421
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
3422
err_code |= ERR_ALERT | ERR_FATAL;
2997
3425
else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
3426
err_code |= ERR_WARN;
3000
3428
if (curproxy->nb_rspadd >= MAX_NEWHDR) {
3001
3429
Alert("parsing [%s:%d] : too many '%s'. Continuing.\n", file, linenum, args[0]);
3430
err_code |= ERR_ALERT | ERR_FATAL;
3005
3434
if (*(args[1]) == 0) {
3006
3435
Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
3436
err_code |= ERR_ALERT | ERR_FATAL;
3010
3440
curproxy->rsp_add[curproxy->nb_rspadd++] = strdup(args[1]);
3119
3555
rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, sizeof(trash));
3121
3557
Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
3558
err_code |= ERR_ALERT | ERR_FATAL;
3124
3561
else if (rc > 0) {
3125
3562
Warning("parsing [%s:%d] : %s\n", file, linenum, trash);
3563
err_code |= ERR_WARN;
3133
3571
Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
3572
err_code |= ERR_ALERT | ERR_FATAL;
3141
3581
* This function reads and parses the configuration file given in the argument.
3142
* returns 0 if OK, -1 if error.
3582
* Returns the error code, 0 if OK, or any combination of :
3583
* - ERR_ABORT: must abort ASAP
3584
* - ERR_FATAL: we can continue parsing but not start the service
3585
* - ERR_WARN: a warning has been emitted
3586
* - ERR_ALERT: an alert has been emitted
3587
* Only the two first ones can stop processing, the two others are just
3144
3590
int readcfgfile(const char *file)
3146
3592
char thisline[LINESIZE];
3148
3594
int linenum = 0;
3150
3595
int confsect = CFG_NONE;
3152
struct proxy *curproxy = NULL;
3153
struct server *newsrv = NULL;
3155
3598
if ((f=fopen(file,"r")) == NULL)
3158
init_default_instance();
3160
3601
while (fgets(thisline, sizeof(thisline), f) != NULL) {
3161
3602
int arg, inv = 0 ;
3284
3725
switch (confsect) {
3285
3726
case CFG_LISTEN:
3286
if (cfg_parse_listen(file, linenum, args, inv) < 0)
3727
err_code |= cfg_parse_listen(file, linenum, args, inv);
3289
3729
case CFG_GLOBAL:
3290
if (cfg_parse_global(file, linenum, args, inv) < 0)
3730
err_code |= cfg_parse_global(file, linenum, args, inv);
3294
3733
Alert("parsing [%s:%d] : unknown keyword '%s' out of section.\n", file, linenum, args[0]);
3734
err_code |= ERR_ALERT | ERR_FATAL;
3737
if (err_code & ERR_ABORT)
3298
3740
free(cursection);
3299
3741
cursection = NULL;
3747
* Returns the error code, 0 if OK, or any combination of :
3748
* - ERR_ABORT: must abort ASAP
3749
* - ERR_FATAL: we can continue parsing but not start the service
3750
* - ERR_WARN: a warning has been emitted
3751
* - ERR_ALERT: an alert has been emitted
3752
* Only the two first ones can stop processing, the two others are just
3755
int check_config_validity()
3758
struct proxy *curproxy = NULL;
3759
struct server *newsrv = NULL;
3303
3763
* Now, check for the integrity of all that we have collected.
3339
3799
switch (curproxy->mode) {
3340
3800
case PR_MODE_HEALTH:
3341
cfgerr += proxy_cfg_ensure_no_http(curproxy, file);
3801
cfgerr += proxy_cfg_ensure_no_http(curproxy);
3342
3802
if (!(curproxy->cap & PR_CAP_FE)) {
3343
Alert("parsing %s : %s '%s' cannot be in health mode as it has no frontend capability.\n",
3344
file, proxy_type_str(curproxy), curproxy->id);
3803
Alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
3804
proxy_type_str(curproxy), curproxy->id);
3348
3808
if (curproxy->srv != NULL)
3349
Warning("parsing %s : servers will be ignored for %s '%s'.\n",
3350
file, proxy_type_str(curproxy), curproxy->id);
3809
Warning("config : servers will be ignored for %s '%s'.\n",
3810
proxy_type_str(curproxy), curproxy->id);
3353
3813
case PR_MODE_TCP:
3354
cfgerr += proxy_cfg_ensure_no_http(curproxy, file);
3814
cfgerr += proxy_cfg_ensure_no_http(curproxy);
3357
3817
case PR_MODE_HTTP:
3358
3818
if ((curproxy->cookie_name != NULL) && (curproxy->srv == NULL)) {
3359
Alert("parsing %s : HTTP proxy %s has a cookie but no server list !\n",
3360
file, curproxy->id);
3819
Alert("config : HTTP proxy %s has a cookie but no server list !\n",
3366
3826
if ((curproxy->cap & PR_CAP_FE) && (curproxy->listen == NULL)) {
3367
Alert("parsing %s : %s '%s' has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n",
3368
file, proxy_type_str(curproxy), curproxy->id);
3827
Alert("config : %s '%s' has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n",
3828
proxy_type_str(curproxy), curproxy->id);
3372
3832
if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
3373
3833
if (curproxy->lbprm.algo & BE_LB_ALGO) {
3374
3834
if (curproxy->options & PR_O_TRANSP) {
3375
Alert("parsing %s : %s '%s' cannot use both transparent and balance mode.\n",
3376
file, proxy_type_str(curproxy), curproxy->id);
3835
Alert("config : %s '%s' cannot use both transparent and balance mode.\n",
3836
proxy_type_str(curproxy), curproxy->id);
3379
3839
#ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
3380
3840
else if (curproxy->srv == NULL) {
3381
Alert("parsing %s : %s '%s' needs at least 1 server in balance mode.\n",
3382
file, proxy_type_str(curproxy), curproxy->id);
3841
Alert("config : %s '%s' needs at least 1 server in balance mode.\n",
3842
proxy_type_str(curproxy), curproxy->id);
3386
3846
else if (*(int *)&curproxy->dispatch_addr.sin_addr != 0) {
3387
Warning("parsing %s : dispatch address of %s '%s' will be ignored in balance mode.\n",
3388
file, proxy_type_str(curproxy), curproxy->id);
3847
Warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
3848
proxy_type_str(curproxy), curproxy->id);
3849
err_code |= ERR_WARN;
3391
3852
else if (!(curproxy->options & (PR_O_TRANSP | PR_O_HTTP_PROXY)) &&
3635
4106
px = findproxy(pname, curproxy->mode, PR_CAP_BE);
3637
Alert("parsing %s, %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
3638
file, proxy_type_str(curproxy), curproxy->id,
4108
Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
4109
proxy_type_str(curproxy), curproxy->id,
3639
4110
newsrv->id, pname);
3645
4117
srv = findserver(px, sname);
3647
Alert("parsing %s, %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
3648
file, proxy_type_str(curproxy), curproxy->id,
4119
Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
4120
proxy_type_str(curproxy), curproxy->id,
3649
4121
newsrv->id, sname);
3653
4126
if (!(srv->state & SRV_CHECKED)) {
3654
Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for "
4127
Alert("config : %s '%s', server '%s': unable to use %s/%s for "
3655
4128
"tracing as it does not have checks enabled.\n",
3656
file, proxy_type_str(curproxy), curproxy->id,
4129
proxy_type_str(curproxy), curproxy->id,
3657
4130
newsrv->id, px->id, srv->id);
3661
4135
if (curproxy != px &&
3662
4136
(curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
3663
Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for"
4137
Alert("config : %s '%s', server '%s': unable to use %s/%s for"
3664
4138
"tracing: disable-on-404 option inconsistency.\n",
3665
file, proxy_type_str(curproxy), curproxy->id,
4139
proxy_type_str(curproxy), curproxy->id,
3666
4140
newsrv->id, px->id, srv->id);
3670
4145
newsrv->tracked = srv;