~ubuntu-branches/ubuntu/trusty/haproxy/trusty-updates

« back to all changes in this revision

Viewing changes to src/cfgparse.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Cornet
  • Date: 2009-10-19 22:31:45 UTC
  • mfrom: (1.2.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20091019223145-rymupk5njs544bvp
ImportĀ upstreamĀ versionĀ 1.3.22

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
#include <common/cfgparse.h>
27
27
#include <common/config.h>
 
28
#include <common/errors.h>
28
29
#include <common/memory.h>
29
30
#include <common/standard.h>
30
31
#include <common/time.h>
40
41
#include <proto/dumpstats.h>
41
42
#include <proto/httperr.h>
42
43
#include <proto/log.h>
 
44
#include <proto/port_range.h>
43
45
#include <proto/protocols.h>
44
46
#include <proto/proto_tcp.h>
45
47
#include <proto/proto_http.h>
127
129
        { "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0 },
128
130
        { "dontlog-normal",               PR_O2_NOLOGNORM, PR_CAP_FE, 0 },
129
131
        { "log-separate-errors",          PR_O2_LOGERRORS, PR_CAP_FE, 0 },
 
132
        { "independant-streams",          PR_O2_INDEPSTR,  PR_CAP_FE|PR_CAP_BE, 0 },
130
133
        { NULL, 0, 0, 0 }
131
134
};
132
135
 
368
371
}
369
372
 
370
373
/*
371
 
 * parse a line in a <global> section. Returns 0 if OK, -1 if error.
 
374
 * parse a line in a <global> section. Returns the error code, 0 if OK, or
 
375
 * any combination of :
 
376
 *  - ERR_ABORT: must abort ASAP
 
377
 *  - ERR_FATAL: we can continue parsing but not start the service
 
378
 *  - ERR_WARN: a warning has been emitted
 
379
 *  - ERR_ALERT: an alert has been emitted
 
380
 * Only the two first ones can stop processing, the two others are just
 
381
 * indicators.
372
382
 */
373
383
int cfg_parse_global(const char *file, int linenum, char **args, int inv)
374
384
{
 
385
        int err_code = 0;
375
386
 
376
387
        if (!strcmp(args[0], "global")) {  /* new section */
377
388
                /* no option, nothing special to do */
378
 
                return 0;
 
389
                goto out;
379
390
        }
380
391
        else if (!strcmp(args[0], "daemon")) {
381
392
                global.mode |= MODE_DAEMON;
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]);
407
 
                        return 0;
 
418
                        err_code |= ERR_ALERT;
 
419
                        goto out;
408
420
                }
409
421
                if (*(args[1]) == 0) {
410
422
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
411
 
                        return -1;
 
423
                        err_code |= ERR_ALERT | ERR_FATAL;
 
424
                        goto out;
412
425
                }
413
426
                global.tune.maxpollevents = atol(args[1]);
414
427
        }
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]);
418
 
                        return 0;
 
431
                        err_code |= ERR_ALERT;
 
432
                        goto out;
419
433
                }
420
434
                if (*(args[1]) == 0) {
421
435
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
422
 
                        return -1;
 
436
                        err_code |= ERR_ALERT | ERR_FATAL;
 
437
                        goto out;
423
438
                }
424
439
                global.tune.maxaccept = atol(args[1]);
425
440
        }
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);
429
 
                        return 0;
 
444
                        err_code |= ERR_ALERT;
 
445
                        goto out;
430
446
                }
431
447
                if (*(args[1]) == 0) {
432
448
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
433
 
                        return -1;
 
449
                        err_code |= ERR_ALERT | ERR_FATAL;
 
450
                        goto out;
434
451
                }
435
452
                global.uid = atol(args[1]);
436
453
        }
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);
440
 
                        return 0;
 
457
                        err_code |= ERR_ALERT;
 
458
                        goto out;
441
459
                }
442
460
                if (*(args[1]) == 0) {
443
461
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
444
 
                        return -1;
 
462
                        err_code |= ERR_ALERT | ERR_FATAL;
 
463
                        goto out;
445
464
                }
446
465
                global.gid = atol(args[1]);
447
466
        }
450
469
                struct passwd *ha_user;
451
470
                if (global.uid != 0) {
452
471
                        Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum);
453
 
                        return 0;
 
472
                        err_code |= ERR_ALERT;
 
473
                        goto out;
454
474
                }
455
475
                errno = 0;
456
476
                ha_user = getpwnam(args[1]);
459
479
                }
460
480
                else {
461
481
                        Alert("parsing [%s:%d] : cannot find user id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
462
 
                        exit(1);
 
482
                        err_code |= ERR_ALERT | ERR_FATAL;
463
483
                }
464
484
        }
465
485
        else if (!strcmp(args[0], "group")) {
466
486
                struct group *ha_group;
467
487
                if (global.gid != 0) {
468
488
                        Alert("parsing [%s:%d] : gid/group was already specified. Continuing.\n", file, linenum);
469
 
                        return 0;
 
489
                        err_code |= ERR_ALERT;
 
490
                        goto out;
470
491
                }
471
492
                errno = 0;
472
493
                ha_group = getgrnam(args[1]);
475
496
                }
476
497
                else {
477
498
                        Alert("parsing [%s:%d] : cannot find group id for '%s' (%d:%s)\n", file, linenum, args[1], errno, strerror(errno));
478
 
                        exit(1);
 
499
                        err_code |= ERR_ALERT | ERR_FATAL;
479
500
                }
480
501
        }
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]);
485
 
                        return 0;
 
506
                        err_code |= ERR_ALERT;
 
507
                        goto out;
486
508
                }
487
509
                if (*(args[1]) == 0) {
488
510
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
489
 
                        return -1;
 
511
                        err_code |= ERR_ALERT | ERR_FATAL;
 
512
                        goto out;
490
513
                }
491
514
                global.nbproc = atol(args[1]);
492
515
        }
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]);
496
 
                        return 0;
 
519
                        err_code |= ERR_ALERT;
 
520
                        goto out;
497
521
                }
498
522
                if (*(args[1]) == 0) {
499
523
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
500
 
                        return -1;
 
524
                        err_code |= ERR_ALERT | ERR_FATAL;
 
525
                        goto out;
501
526
                }
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;
507
533
                }
508
534
#endif /* SYSTEM_MAXCONN */
509
535
        }
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]);
513
 
                        return 0;
 
539
                        err_code |= ERR_ALERT;
 
540
                        goto out;
514
541
                }
515
542
                if (*(args[1]) == 0) {
516
543
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
517
 
                        return -1;
 
544
                        err_code |= ERR_ALERT | ERR_FATAL;
 
545
                        goto out;
518
546
                }
519
547
                global.maxpipes = atol(args[1]);
520
548
        }
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]);
524
 
                        return 0;
 
552
                        err_code |= ERR_ALERT;
 
553
                        goto out;
525
554
                }
526
555
                if (*(args[1]) == 0) {
527
556
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
528
 
                        return -1;
 
557
                        err_code |= ERR_ALERT | ERR_FATAL;
 
558
                        goto out;
529
559
                }
530
560
                global.rlimit_nofile = atol(args[1]);
531
561
        }
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]);
535
 
                        return 0;
 
565
                        err_code |= ERR_ALERT;
 
566
                        goto out;
536
567
                }
537
568
                if (*(args[1]) == 0) {
538
569
                        Alert("parsing [%s:%d] : '%s' expects a directory as an argument.\n", file, linenum, args[0]);
539
 
                        return -1;
 
570
                        err_code |= ERR_ALERT | ERR_FATAL;
 
571
                        goto out;
540
572
                }
541
573
                global.chroot = strdup(args[1]);
542
574
        }
 
575
        else if (!strcmp(args[0], "description")) {
 
576
                int i, len=0;
 
577
                char *d;
 
578
 
 
579
                if (!*args[1]) {
 
580
                        Alert("parsing [%s:%d]: '%s' expects a string argument.\n",
 
581
                                file, linenum, args[0]);
 
582
                        err_code |= ERR_ALERT | ERR_FATAL;
 
583
                        goto out;
 
584
                }
 
585
 
 
586
                for(i=1; *args[i]; i++)
 
587
                        len += strlen(args[i])+1;
 
588
 
 
589
                if (global.desc)
 
590
                        free(global.desc);
 
591
 
 
592
                global.desc = d = (char *)calloc(1, len);
 
593
 
 
594
                d += sprintf(d, "%s", args[1]);
 
595
                for(i=2; *args[i]; i++)
 
596
                        d += sprintf(d, " %s", args[i]);
 
597
        }
 
598
        else if (!strcmp(args[0], "node")) {
 
599
                int i;
 
600
                char c;
 
601
 
 
602
                for (i=0; args[1][i]; i++) {
 
603
                        c = args[1][i];
 
604
                        if (!isupper(c) && !islower(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
 
605
                                break;
 
606
                }
 
607
 
 
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;
 
613
                        goto out;
 
614
                }
 
615
 
 
616
                if (global.node)
 
617
                        free(global.node);
 
618
 
 
619
                global.node = strdup(args[1]);
 
620
        }
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]);
546
 
                        return 0;
 
624
                        err_code |= ERR_ALERT;
 
625
                        goto out;
547
626
                }
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]);
550
 
                        return -1;
 
629
                        err_code |= ERR_ALERT | ERR_FATAL;
 
630
                        goto out;
551
631
                }
552
632
                global.pidfile = strdup(args[1]);
553
633
        }
557
637
        
558
638
                if (*(args[1]) == 0 || *(args[2]) == 0) {
559
639
                        Alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
560
 
                        return -1;
 
640
                        err_code |= ERR_ALERT | ERR_FATAL;
 
641
                        goto out;
561
642
                }
562
643
        
563
644
                facility = get_log_facility(args[2]);
564
645
                if (facility < 0) {
565
646
                        Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
566
 
                        exit(1);
 
647
                        err_code |= ERR_ALERT | ERR_FATAL;
 
648
                        facility = 0;
567
649
                }
568
650
 
569
651
                level = 7; /* max syslog level = debug */
571
653
                        level = get_log_level(args[3]);
572
654
                        if (level < 0) {
573
655
                                Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
574
 
                                exit(1);
 
656
                                err_code |= ERR_ALERT | ERR_FATAL;
 
657
                                level = 0;
575
658
                        }
576
659
                }
577
660
 
578
661
                minlvl = 0; /* limit syslog level to this level (emerg) */
579
662
                if (*(args[4])) {
580
663
                        minlvl = get_log_level(args[4]);
581
 
                        if (level < 0) {
 
664
                        if (minlvl < 0) {
582
665
                                Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
583
 
                                exit(1);
 
666
                                err_code |= ERR_ALERT | ERR_FATAL;
 
667
                                minlvl = 0;
584
668
                        }
585
669
                }
586
670
 
608
692
                }
609
693
                else {
610
694
                        Alert("parsing [%s:%d] : too many syslog servers\n", file, linenum);
611
 
                        return -1;
 
695
                        err_code |= ERR_ALERT | ERR_FATAL;
612
696
                }
613
697
        }
614
698
        else if (!strcmp(args[0], "spread-checks")) {  /* random time between checks (0-50) */
615
699
                if (global.spread_checks != 0) {
616
700
                        Alert("parsing [%s:%d]: spread-checks already specified. Continuing.\n", file, linenum);
617
 
                        return 0;
 
701
                        err_code |= ERR_ALERT;
 
702
                        goto out;
618
703
                }
619
704
                if (*(args[1]) == 0) {
620
705
                        Alert("parsing [%s:%d]: '%s' expects an integer argument (0..50).\n", file, linenum, args[0]);
621
 
                        return -1;
 
706
                        err_code |= ERR_ALERT | ERR_FATAL;
 
707
                        goto out;
622
708
                }
623
709
                global.spread_checks = atol(args[1]);
624
710
                if (global.spread_checks < 0 || global.spread_checks > 50) {
625
711
                        Alert("parsing [%s:%d]: 'spread-checks' needs a positive value in range 0..50.\n", file, linenum);
626
 
                        return -1;
 
712
                        err_code |= ERR_ALERT | ERR_FATAL;
627
713
                }
628
714
        }
629
715
        else {
642
728
                                        rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, trash, sizeof(trash));
643
729
                                        if (rc < 0) {
644
730
                                                Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
645
 
                                                return -1;
 
731
                                                err_code |= ERR_ALERT | ERR_FATAL;
646
732
                                        }
647
733
                                        else if (rc > 0) {
648
734
                                                Warning("parsing [%s:%d] : %s\n", file, linenum, trash);
649
 
                                                return 0;
 
735
                                                err_code |= ERR_WARN;
 
736
                                                goto out;
650
737
                                        }
651
 
                                        return 0;
 
738
                                        goto out;
652
739
                                }
653
740
                        }
654
741
                }
655
742
                
656
743
                Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global");
657
 
                return -1;
 
744
                err_code |= ERR_ALERT | ERR_FATAL;
658
745
        }
659
 
        return 0;
 
746
 
 
747
 out:
 
748
        return err_code;
660
749
}
661
750
 
662
751
 
663
 
static void init_default_instance()
 
752
void init_default_instance()
664
753
{
665
754
        memset(&defproxy, 0, sizeof(defproxy));
666
755
        defproxy.mode = PR_MODE_TCP;
680
769
 
681
770
/*
682
771
 * Parse a line in a <listen>, <frontend>, <backend> or <ruleset> section.
683
 
 * Returns 0 if OK, -1 if error.
 
772
 * Returns the error code, 0 if OK, or any combination of :
 
773
 *  - ERR_ABORT: must abort ASAP
 
774
 *  - ERR_FATAL: we can continue parsing but not start the service
 
775
 *  - ERR_WARN: a warning has been emitted
 
776
 *  - ERR_ALERT: an alert has been emitted
 
777
 * Only the two first ones can stop processing, the two others are just
 
778
 * indicators.
684
779
 */
685
780
int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
686
781
{
689
784
        const char *err;
690
785
        int rc;
691
786
        unsigned val;
 
787
        int err_code = 0;
692
788
 
693
789
        if (!strcmp(args[0], "listen"))
694
790
                rc = PR_CAP_LISTEN;
706
802
                        Alert("parsing [%s:%d] : '%s' expects an <id> argument and\n"
707
803
                              "  optionnally supports [addr1]:port1[-end1]{,[addr]:port[-end]}...\n",
708
804
                              file, linenum, args[0]);
709
 
                        return -1;
 
805
                        err_code |= ERR_ALERT | ERR_ABORT;
 
806
                        goto out;
710
807
                }
711
808
 
712
809
                err = invalid_char(args[1]);
713
810
                if (err) {
714
811
                        Alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
715
812
                              file, linenum, *err, args[0], args[1]);
716
 
                        return -1;
 
813
                        err_code |= ERR_ALERT | ERR_FATAL;
717
814
                }
718
815
 
719
816
                for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {
733
830
                                (rc!=(PR_CAP_BE|PR_CAP_RS) || curproxy->cap!=(PR_CAP_FE|PR_CAP_RS))) {
734
831
                                Warning("Parsing [%s:%d]: %s '%s' has same name as another %s.\n",
735
832
                                        file, linenum, proxy_cap_str(rc), args[1], proxy_type_str(curproxy));
 
833
                                err_code |= ERR_WARN;
736
834
                        }
737
835
                }
738
836
 
739
837
                if ((curproxy = (struct proxy *)calloc(1, sizeof(struct proxy))) == NULL) {
740
838
                        Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
741
 
                        return -1;
 
839
                        err_code |= ERR_ALERT | ERR_ABORT;
 
840
                        goto out;
742
841
                }
743
842
 
744
843
                curproxy->next = proxy;
763
862
                /* parse the listener address if any */
764
863
                if ((curproxy->cap & PR_CAP_FE) && *args[2]) {
765
864
                        curproxy->listen = str2listener(args[2], curproxy->listen);
766
 
                        if (!curproxy->listen)
767
 
                                return -1;
 
865
                        if (!curproxy->listen) {
 
866
                                err_code |= ERR_FATAL;
 
867
                                goto out;
 
868
                        }
768
869
                        global.maxsock++;
769
870
                }
770
871
 
824
925
                        curproxy->iface_len  = defproxy.iface_len;
825
926
                }
826
927
 
827
 
                if (curproxy->cap & PR_CAP_RS) {
 
928
                if (curproxy->cap & PR_CAP_FE) {
828
929
                        if (defproxy.capture_name)
829
930
                                curproxy->capture_name = strdup(defproxy.capture_name);
830
931
                        curproxy->capture_namelen = defproxy.capture_namelen;
867
968
                curproxy->uuid = next_pxid++;   /* generate a uuid for this proxy */
868
969
                curproxy->next_svid = 1;        /* server id 0 is reserved */
869
970
 
870
 
                return 0;
 
971
                goto out;
871
972
        }
872
973
        else if (!strcmp(args[0], "defaults")) {  /* use this one to assign default values */
873
974
                /* some variables may have already been initialized earlier */
892
993
                init_default_instance();
893
994
                curproxy = &defproxy;
894
995
                defproxy.cap = PR_CAP_LISTEN; /* all caps for now */
895
 
                return 0;
 
996
                goto out;
896
997
        }
897
998
        else if (curproxy == NULL) {
898
999
                Alert("parsing [%s:%d] : 'listen' or 'defaults' expected.\n", file, linenum);
899
 
                return -1;
 
1000
                err_code |= ERR_ALERT | ERR_FATAL;
 
1001
                goto out;
900
1002
        }
901
1003
    
902
1004
 
907
1009
 
908
1010
                if (curproxy == &defproxy) {
909
1011
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
910
 
                        return -1;
 
1012
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1013
                        goto out;
911
1014
                }
912
1015
                if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
913
 
                        return 0;
 
1016
                        err_code |= ERR_WARN;
914
1017
 
915
1018
                if (strchr(args[1], ':') == NULL) {
916
1019
                        Alert("parsing [%s:%d] : '%s' expects [addr1]:port1[-end1]{,[addr]:port[-end]}... as arguments.\n",
917
1020
                              file, linenum, args[0]);
918
 
                        return -1;
 
1021
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1022
                        goto out;
919
1023
                }
920
1024
 
921
1025
                last_listen = curproxy->listen;
922
1026
                curproxy->listen = str2listener(args[1], last_listen);
923
 
                if (!curproxy->listen)
924
 
                        return -1;
 
1027
                if (!curproxy->listen) {
 
1028
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1029
                        goto out;
 
1030
                }
925
1031
 
926
1032
                cur_arg = 2;
927
1033
                while (*(args[cur_arg])) {
932
1038
                                if (!*args[cur_arg + 1]) {
933
1039
                                        Alert("parsing [%s:%d] : '%s' : missing interface name.\n",
934
1040
                                              file, linenum, args[0]);
935
 
                                        return -1;
 
1041
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1042
                                        goto out;
936
1043
                                }
937
1044
                                
938
1045
                                for (l = curproxy->listen; l != last_listen; l = l->next)
945
1052
#else
946
1053
                                Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
947
1054
                                      file, linenum, args[0], args[cur_arg]);
948
 
                                return -1;
 
1055
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1056
                                goto out;
949
1057
#endif
950
1058
                        }
951
1059
                        if (!strcmp(args[cur_arg], "transparent")) { /* transparently bind to these addresses */
960
1068
#else
961
1069
                                Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
962
1070
                                      file, linenum, args[0], args[cur_arg]);
963
 
                                return -1;
 
1071
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1072
                                goto out;
964
1073
#endif
965
1074
                        }
966
1075
                        Alert("parsing [%s:%d] : '%s' only supports the 'transparent' and 'interface' options.\n",
967
1076
                              file, linenum, args[0]);
968
 
                        return -1;
 
1077
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1078
                        goto out;
969
1079
                }
970
1080
                global.maxsock++;
971
 
                return 0;
 
1081
                goto out;
972
1082
        }
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]);
977
 
                        return -1;
 
1087
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1088
                        goto out;
978
1089
                }
979
1090
                if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
980
 
                        return 0;
 
1091
                        err_code |= ERR_WARN;
981
1092
 
982
1093
                /* flush useless bits */
983
1094
                curproxy->mon_net.s_addr &= curproxy->mon_mask.s_addr;
984
 
                return 0;
 
1095
                goto out;
985
1096
        }
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))
988
 
                        return 0;
 
1099
                        err_code |= ERR_WARN;
989
1100
 
990
1101
                if (!*args[1]) {
991
1102
                        Alert("parsing [%s:%d] : '%s' expects an URI.\n",
992
1103
                              file, linenum, args[0]);
993
 
                        return -1;
 
1104
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1105
                        goto out;
994
1106
                }
995
1107
 
996
1108
                free(curproxy->monitor_uri);
999
1111
                memcpy(curproxy->monitor_uri, args[1], curproxy->monitor_uri_len);
1000
1112
                curproxy->monitor_uri[curproxy->monitor_uri_len] = '\0';
1001
1113
 
1002
 
                return 0;
 
1114
                goto out;
1003
1115
        }
1004
1116
        else if (!strcmp(args[0], "mode")) {  /* sets the proxy mode */
1005
1117
                if (!strcmp(args[1], "http")) curproxy->mode = PR_MODE_HTTP;
1007
1119
                else if (!strcmp(args[1], "health")) curproxy->mode = PR_MODE_HEALTH;
1008
1120
                else {
1009
1121
                        Alert("parsing [%s:%d] : unknown proxy mode '%s'.\n", file, linenum, args[1]);
1010
 
                        return -1;
 
1122
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1123
                        goto out;
1011
1124
                }
1012
1125
        }
1013
1126
        else if (!strcmp(args[0], "id")) {
1016
1129
                if (curproxy == &defproxy) {
1017
1130
                        Alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n",
1018
1131
                                 file, linenum, args[0]);
1019
 
                        return -1;
 
1132
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1133
                        goto out;
1020
1134
                }
1021
1135
 
1022
1136
                if (!*args[1]) {
1023
1137
                        Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
1024
1138
                                file, linenum, args[0]);
1025
 
                        return -1;
 
1139
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1140
                        goto out;
1026
1141
                }
1027
1142
 
1028
1143
                curproxy->uuid = atol(args[1]);
1029
1144
 
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);
1033
 
                        return -1;
 
1148
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1149
                        goto out;
1034
1150
                }
1035
1151
 
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);
1040
 
                                return -1;
 
1156
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1157
                                goto out;
1041
1158
                        }
1042
1159
        }
 
1160
        else if (!strcmp(args[0], "description")) {
 
1161
                int i, len=0;
 
1162
                char *d;
 
1163
 
 
1164
                if (!*args[1]) {
 
1165
                        Alert("parsing [%s:%d]: '%s' expects a string argument.\n",
 
1166
                                file, linenum, args[0]);
 
1167
                        return -1;
 
1168
                }
 
1169
 
 
1170
                for(i=1; *args[i]; i++)
 
1171
                        len += strlen(args[i])+1;
 
1172
 
 
1173
                d = (char *)calloc(1, len);
 
1174
                curproxy->desc = d;
 
1175
 
 
1176
                d += sprintf(d, "%s", args[1]);
 
1177
                for(i=2; *args[i]; i++)
 
1178
                        d += sprintf(d, " %s", args[i]);
 
1179
 
 
1180
        }
1043
1181
        else if (!strcmp(args[0], "disabled")) {  /* disables this proxy */
1044
1182
                curproxy->state = PR_STSTOPPED;
1045
1183
        }
1067
1205
                                if (u < 1 || u > 32) {
1068
1206
                                        Alert("parsing [%s:%d]: %s expects 'all', 'odd', 'even', or process numbers from 1 to 32.\n",
1069
1207
                                              file, linenum, args[0]);
1070
 
                                        return -1;
 
1208
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1209
                                        goto out;
1071
1210
                                }
1072
1211
                                if (u > global.nbproc) {
1073
1212
                                        Warning("parsing [%s:%d]: %s references process number higher than global.nbproc.\n",
1074
1213
                                                file, linenum, args[0]);
 
1214
                                        err_code |= ERR_WARN;
1075
1215
                                }
1076
1216
                                set |= 1 << (u - 1);
1077
1217
                        }
1082
1222
        else if (!strcmp(args[0], "acl")) {  /* add an ACL */
1083
1223
                if (curproxy == &defproxy) {
1084
1224
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
1085
 
                        return -1;
 
1225
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1226
                        goto out;
1086
1227
                }
1087
1228
 
1088
1229
                err = invalid_char(args[1]);
1089
1230
                if (err) {
1090
1231
                        Alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
1091
1232
                              file, linenum, *err, args[1]);
1092
 
                        return -1;
 
1233
                        err_code |= ERR_ALERT | ERR_FATAL;
1093
1234
                }
1094
1235
 
1095
1236
                if (parse_acl((const char **)args + 1, &curproxy->acl) == NULL) {
1096
1237
                        Alert("parsing [%s:%d] : error detected while parsing ACL '%s'.\n",
1097
1238
                              file, linenum, args[1]);
1098
 
                        return -1;
 
1239
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1240
                        goto out;
1099
1241
                }
1100
1242
        }
1101
1243
        else if (!strcmp(args[0], "cookie")) {  /* cookie name */
1102
1244
                int cur_arg;
1103
1245
 
1104
1246
                if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1105
 
                        return 0;
 
1247
                        err_code |= ERR_WARN;
1106
1248
 
1107
1249
                if (*(args[1]) == 0) {
1108
1250
                        Alert("parsing [%s:%d] : '%s' expects <cookie_name> as argument.\n",
1109
1251
                              file, linenum, args[0]);
1110
 
                        return -1;
 
1252
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1253
                        goto out;
1111
1254
                }
1112
1255
 
1113
1256
                free(curproxy->cookie_name);
1138
1281
                                if (!*args[cur_arg + 1]) {
1139
1282
                                        Alert("parsing [%s:%d]: '%s' expects <domain> as argument.\n",
1140
1283
                                                file, linenum, args[cur_arg]);
1141
 
                                        return -1;
 
1284
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1285
                                        goto out;
1142
1286
                                }
1143
1287
 
1144
1288
                                if (*args[cur_arg + 1] != '.' || !strchr(args[cur_arg + 1] + 1, '.')) {
1146
1290
                                        Alert("parsing [%s:%d]: domain '%s' contains no embedded"
1147
1291
                                                " dots or does not start with a dot.\n",
1148
1292
                                                file, linenum, args[cur_arg + 1]);
1149
 
                                        return -1;
 
1293
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1294
                                        goto out;
1150
1295
                                }
1151
1296
 
1152
1297
                                err = invalid_domainchar(args[cur_arg + 1]);
1153
1298
                                if (err) {
1154
1299
                                        Alert("parsing [%s:%d]: character '%c' is not permitted in domain name '%s'.\n",
1155
1300
                                                file, linenum, *err, args[cur_arg + 1]);
1156
 
                                        return -1;
 
1301
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1302
                                        goto out;
1157
1303
                                }
1158
1304
 
1159
1305
                                curproxy->cookie_domain = strdup(args[cur_arg + 1]);
1162
1308
                        else {
1163
1309
                                Alert("parsing [%s:%d] : '%s' supports 'rewrite', 'insert', 'prefix', 'indirect', 'nocache' and 'postonly', 'domain' options.\n",
1164
1310
                                      file, linenum, args[0]);
1165
 
                                return -1;
 
1311
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1312
                                goto out;
1166
1313
                        }
1167
1314
                        cur_arg++;
1168
1315
                }
1169
1316
                if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_IND))) {
1170
1317
                        Alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
1171
1318
                              file, linenum);
1172
 
                        return -1;
 
1319
                        err_code |= ERR_ALERT | ERR_FATAL;
1173
1320
                }
1174
1321
 
1175
1322
                if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_INS|PR_O_COOK_PFX))) {
1176
1323
                        Alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
1177
1324
                              file, linenum);
1178
 
                        return -1;
 
1325
                        err_code |= ERR_ALERT | ERR_FATAL;
1179
1326
                }
1180
1327
        }/* end else if (!strcmp(args[0], "cookie"))  */
1181
1328
        else if (!strcmp(args[0], "appsession")) {  /* cookie name */
1182
1329
 
1183
1330
                if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1184
 
                        return 0;
 
1331
                        err_code |= ERR_WARN;
1185
1332
 
1186
1333
                if (*(args[5]) == 0) {
1187
1334
                        Alert("parsing [%s:%d] : '%s' expects 'appsession' <cookie_name> 'len' <len> 'timeout' <timeout>.\n",
1188
1335
                              file, linenum, args[0]);
1189
 
                        return -1;
 
1336
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1337
                        goto out;
1190
1338
                }
1191
1339
                have_appsession = 1;
1192
1340
                free(curproxy->appsession_name);
1197
1345
                if (err) {
1198
1346
                        Alert("parsing [%s:%d] : unexpected character '%c' in %s timeout.\n",
1199
1347
                              file, linenum, *err, args[0]);
1200
 
                        return -1;
 
1348
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1349
                        goto out;
1201
1350
                }
1202
1351
                curproxy->timeout.appsession = val;
1203
1352
 
1204
1353
                if (appsession_hash_init(&(curproxy->htbl_proxy), destroy) == 0) {
1205
1354
                        Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1206
 
                        return -1;
 
1355
                        err_code |= ERR_ALERT | ERR_ABORT;
 
1356
                        goto out;
1207
1357
                }
1208
1358
        } /* Url App Session */
1209
1359
        else if (!strcmp(args[0], "capture")) {
1210
 
                if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
1211
 
                        return 0;
 
1360
                if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
 
1361
                        err_code |= ERR_WARN;
1212
1362
 
1213
1363
                if (!strcmp(args[1], "cookie")) {  /* name of a cookie to capture */
1214
1364
                        if (*(args[4]) == 0) {
1215
1365
                                Alert("parsing [%s:%d] : '%s' expects 'cookie' <cookie_name> 'len' <len>.\n",
1216
1366
                                      file, linenum, args[0]);
1217
 
                                return -1;
 
1367
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1368
                                goto out;
1218
1369
                        }
1219
1370
                        free(curproxy->capture_name);
1220
1371
                        curproxy->capture_name = strdup(args[2]);
1223
1374
                        if (curproxy->capture_len >= CAPTURE_LEN) {
1224
1375
                                Warning("parsing [%s:%d] : truncating capture length to %d bytes.\n",
1225
1376
                                        file, linenum, CAPTURE_LEN - 1);
 
1377
                                err_code |= ERR_WARN;
1226
1378
                                curproxy->capture_len = CAPTURE_LEN - 1;
1227
1379
                        }
1228
1380
                        curproxy->to_log |= LW_COOKIE;
1232
1384
 
1233
1385
                        if (curproxy == &defproxy) {
1234
1386
                                Alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n", file, linenum, args[0], args[1]);
1235
 
                                return -1;
 
1387
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1388
                                goto out;
1236
1389
                        }
1237
1390
 
1238
1391
                        if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
1239
1392
                                Alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
1240
1393
                                      file, linenum, args[0], args[1]);
1241
 
                                return -1;
 
1394
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1395
                                goto out;
1242
1396
                        }
1243
1397
 
1244
1398
                        hdr = calloc(sizeof(struct cap_hdr), 1);
1256
1410
 
1257
1411
                        if (curproxy == &defproxy) {
1258
1412
                                Alert("parsing [%s:%d] : '%s %s' not allowed in 'defaults' section.\n", file, linenum, args[0], args[1]);
1259
 
                                return -1;
 
1413
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1414
                                goto out;
1260
1415
                        }
1261
1416
 
1262
1417
                        if (*(args[3]) == 0 || strcmp(args[4], "len") != 0 || *(args[5]) == 0) {
1263
1418
                                Alert("parsing [%s:%d] : '%s %s' expects 'header' <header_name> 'len' <len>.\n",
1264
1419
                                      file, linenum, args[0], args[1]);
1265
 
                                return -1;
 
1420
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1421
                                goto out;
1266
1422
                        }
1267
1423
                        hdr = calloc(sizeof(struct cap_hdr), 1);
1268
1424
                        hdr->next = curproxy->rsp_cap;
1277
1433
                else {
1278
1434
                        Alert("parsing [%s:%d] : '%s' expects 'cookie' or 'request header' or 'response header'.\n",
1279
1435
                              file, linenum, args[0]);
1280
 
                        return -1;
 
1436
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1437
                        goto out;
1281
1438
                }
1282
1439
        }
1283
1440
        else if (!strcmp(args[0], "retries")) {  /* connection retries */
1284
1441
                if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1285
 
                        return 0;
 
1442
                        err_code |= ERR_WARN;
1286
1443
 
1287
1444
                if (*(args[1]) == 0) {
1288
1445
                        Alert("parsing [%s:%d] : '%s' expects an integer argument (dispatch counts for one).\n",
1289
1446
                              file, linenum, args[0]);
1290
 
                        return -1;
 
1447
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1448
                        goto out;
1291
1449
                }
1292
1450
                curproxy->conn_retries = atol(args[1]);
1293
1451
        }
1297
1455
 
1298
1456
                if (curproxy == &defproxy) {
1299
1457
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
1300
 
                        return -1;
 
1458
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1459
                        goto out;
1301
1460
                }
1302
1461
 
1303
1462
                if (!strcmp(args[1], "if"))
1308
1467
                if (pol == ACL_COND_NONE) {
1309
1468
                        Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
1310
1469
                              file, linenum, args[0]);
1311
 
                        return -1;
 
1470
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1471
                        goto out;
1312
1472
                }
1313
1473
 
1314
1474
                if ((cond = parse_acl_cond((const char **)args + 2, &curproxy->acl, pol)) == NULL) {
1315
1475
                        Alert("parsing [%s:%d] : error detected while parsing blocking condition.\n",
1316
1476
                              file, linenum);
1317
 
                        return -1;
 
1477
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1478
                        goto out;
1318
1479
                }
1319
1480
                cond->line = linenum;
1320
1481
                LIST_ADDQ(&curproxy->block_cond, &cond->list);
1338
1499
                                if (!*args[cur_arg + 1]) {
1339
1500
                                        Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1340
1501
                                              file, linenum, args[0], args[cur_arg]);
1341
 
                                        return -1;
 
1502
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1503
                                        goto out;
1342
1504
                                }
1343
1505
 
1344
1506
                                type = REDIRECT_TYPE_LOCATION;
1349
1511
                                if (!*args[cur_arg + 1]) {
1350
1512
                                        Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1351
1513
                                              file, linenum, args[0], args[cur_arg]);
1352
 
                                        return -1;
 
1514
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1515
                                        goto out;
1353
1516
                                }
1354
1517
 
1355
1518
                                type = REDIRECT_TYPE_PREFIX;
1360
1523
                                if (!*args[cur_arg + 1]) {
1361
1524
                                        Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1362
1525
                                              file, linenum, args[0], args[cur_arg]);
1363
 
                                        return -1;
 
1526
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1527
                                        goto out;
1364
1528
                                }
1365
1529
 
1366
1530
                                cur_arg++;
1371
1535
                                if (!*args[cur_arg + 1]) {
1372
1536
                                        Alert("parsing [%s:%d] : '%s': missing argument for '%s'.\n",
1373
1537
                                              file, linenum, args[0], args[cur_arg]);
1374
 
                                        return -1;
 
1538
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1539
                                        goto out;
1375
1540
                                }
1376
1541
 
1377
1542
                                cur_arg++;
1382
1547
                                if (!*args[cur_arg + 1]) {
1383
1548
                                        Alert("parsing [%s:%d] : '%s': missing HTTP code.\n",
1384
1549
                                              file, linenum, args[0]);
1385
 
                                        return -1;
 
1550
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1551
                                        goto out;
1386
1552
                                }
1387
1553
                                cur_arg++;
1388
1554
                                code = atol(args[cur_arg]);
1389
1555
                                if (code < 301 || code > 303) {
1390
1556
                                        Alert("parsing [%s:%d] : '%s': unsupported HTTP code '%d'.\n",
1391
1557
                                              file, linenum, args[0], code);
1392
 
                                        return -1;
 
1558
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1559
                                        goto out;
1393
1560
                                }
1394
1561
                        }
1395
1562
                        else if (!strcmp(args[cur_arg],"drop-query")) {
1408
1575
                        else {
1409
1576
                                Alert("parsing [%s:%d] : '%s' expects 'code', 'prefix' or 'location' (was '%s').\n",
1410
1577
                                      file, linenum, args[0], args[cur_arg]);
1411
 
                                return -1;
 
1578
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1579
                                goto out;
1412
1580
                        }
1413
1581
                        cur_arg++;
1414
1582
                }
1416
1584
                if (type == REDIRECT_TYPE_NONE) {
1417
1585
                        Alert("parsing [%s:%d] : '%s' expects a redirection type ('prefix' or 'location').\n",
1418
1586
                              file, linenum, args[0]);
1419
 
                        return -1;
 
1587
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1588
                        goto out;
1420
1589
                }
1421
1590
 
1422
1591
                if (pol == ACL_COND_NONE) {
1423
1592
                        Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
1424
1593
                              file, linenum, args[0]);
1425
 
                        return -1;
 
1594
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1595
                        goto out;
1426
1596
                }
1427
1597
 
1428
1598
                if ((cond = parse_acl_cond((const char **)args + cur_arg, &curproxy->acl, pol)) == NULL) {
1429
1599
                        Alert("parsing [%s:%d] : '%s': error detected while parsing redirect condition.\n",
1430
1600
                              file, linenum, args[0]);
1431
 
                        return -1;
 
1601
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1602
                        goto out;
1432
1603
                }
1433
1604
 
1434
1605
                cond->line = linenum;
1464
1635
 
1465
1636
                if (curproxy == &defproxy) {
1466
1637
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
1467
 
                        return -1;
 
1638
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1639
                        goto out;
1468
1640
                }
1469
1641
 
1470
1642
                if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
1471
 
                        return 0;
 
1643
                        err_code |= ERR_WARN;
1472
1644
 
1473
1645
                if (*(args[1]) == 0) {
1474
1646
                        Alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
1475
 
                        return -1;
 
1647
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1648
                        goto out;
1476
1649
                }
1477
1650
 
1478
1651
                if (!strcmp(args[2], "if"))
1483
1656
                if (pol == ACL_COND_NONE) {
1484
1657
                        Alert("parsing [%s:%d] : '%s' requires either 'if' or 'unless' followed by a condition.\n",
1485
1658
                              file, linenum, args[0]);
1486
 
                        return -1;
 
1659
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1660
                        goto out;
1487
1661
                }
1488
1662
 
1489
1663
                if ((cond = parse_acl_cond((const char **)args + 3, &curproxy->acl, pol)) == NULL) {
1490
1664
                        Alert("parsing [%s:%d] : error detected while parsing switching rule.\n",
1491
1665
                              file, linenum);
1492
 
                        return -1;
 
1666
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1667
                        goto out;
1493
1668
                }
1494
1669
 
1495
1670
                cond->line = linenum;
1501
1676
                        name = acl ? acl->name : "(unknown)";
1502
1677
                        Warning("parsing [%s:%d] : acl '%s' involves some response-only criteria which will be ignored.\n",
1503
1678
                                file, linenum, name);
 
1679
                        err_code |= ERR_WARN;
1504
1680
                }
1505
1681
 
1506
1682
                rule = (struct switching_rule *)calloc(1, sizeof(*rule));
1511
1687
        }
1512
1688
        else if (!strcmp(args[0], "stats")) {
1513
1689
                if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1514
 
                        return 0;
 
1690
                        err_code |= ERR_WARN;
1515
1691
 
1516
1692
                if (curproxy != &defproxy && curproxy->uri_auth == defproxy.uri_auth)
1517
1693
                        curproxy->uri_auth = NULL; /* we must detach from the default config */
1518
1694
 
1519
1695
                if (*(args[1]) == 0) {
1520
 
                        Alert("parsing [%s:%d] : '%s' expects 'uri', 'realm', 'auth', 'scope' or 'enable'.\n", file, linenum, args[0]);
1521
 
                        return -1;
 
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;
 
1698
                        goto out;
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);
1525
 
                                return -1;
 
1702
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1703
                                goto out;
1526
1704
                        } else if (!stats_set_uri(&curproxy->uri_auth, args[2])) {
1527
1705
                                Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1528
 
                                return -1;
 
1706
                                err_code |= ERR_ALERT | ERR_ABORT;
 
1707
                                goto out;
1529
1708
                        }
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);
1533
 
                                return -1;
 
1712
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1713
                                goto out;
1534
1714
                        } else if (!stats_set_realm(&curproxy->uri_auth, args[2])) {
1535
1715
                                Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1536
 
                                return -1;
 
1716
                                err_code |= ERR_ALERT | ERR_ABORT;
 
1717
                                goto out;
1537
1718
                        }
1538
1719
                } else if (!strcmp(args[1], "refresh")) {
1539
1720
                        unsigned interval;
1542
1723
                        if (err) {
1543
1724
                                Alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
1544
1725
                                      file, linenum, *err);
1545
 
                                return -1;
 
1726
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1727
                                goto out;
1546
1728
                        } else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
1547
1729
                                Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1548
 
                                return -1;
 
1730
                                err_code |= ERR_ALERT | ERR_ABORT;
 
1731
                                goto out;
1549
1732
                        }
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);
1553
 
                                return -1;
 
1736
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1737
                                goto out;
1554
1738
                        } else if (!stats_add_auth(&curproxy->uri_auth, args[2])) {
1555
1739
                                Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1556
 
                                return -1;
 
1740
                                err_code |= ERR_ALERT | ERR_ABORT;
 
1741
                                goto out;
1557
1742
                        }
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);
1561
 
                                return -1;
 
1746
                                err_code |= ERR_ALERT | ERR_FATAL;
 
1747
                                goto out;
1562
1748
                        } else if (!stats_add_scope(&curproxy->uri_auth, args[2])) {
1563
1749
                                Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1564
 
                                return -1;
 
1750
                                err_code |= ERR_ALERT | ERR_ABORT;
 
1751
                                goto out;
1565
1752
                        }
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);
1569
 
                                return -1;
 
1756
                                err_code |= ERR_ALERT | ERR_ABORT;
 
1757
                                goto out;
1570
1758
                        }
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);
1574
 
                                return -1;
 
1762
                                err_code |= ERR_ALERT | ERR_ABORT;
 
1763
                                goto out;
 
1764
                        }
 
1765
                } else if (!strcmp(args[1], "show-node")) {
 
1766
 
 
1767
                        if (*args[2]) {
 
1768
                                int i;
 
1769
                                char c;
 
1770
 
 
1771
                                for (i=0; args[2][i]; i++) {
 
1772
                                        c = args[2][i];
 
1773
                                        if (!isupper(c) && !islower(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
 
1774
                                                break;
 
1775
                                }
 
1776
 
 
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;
 
1782
                                        goto out;
 
1783
                                }
 
1784
                        }
 
1785
 
 
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;
 
1789
                                goto out;
 
1790
                        }
 
1791
                } else if (!strcmp(args[1], "show-desc")) {
 
1792
                        char *desc = NULL;
 
1793
 
 
1794
                        if (*args[2]) {
 
1795
                                int i, len=0;
 
1796
                                char *d;
 
1797
 
 
1798
                                for(i=2; *args[i]; i++)
 
1799
                                        len += strlen(args[i])+1;
 
1800
 
 
1801
                                desc = d = (char *)calloc(1, len);
 
1802
 
 
1803
                                d += sprintf(d, "%s", args[2]);
 
1804
                                for(i=3; *args[i]; i++)
 
1805
                                        d += sprintf(d, " %s", args[i]);
 
1806
                        }
 
1807
 
 
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]);
 
1811
                        else {
 
1812
                                if (!stats_set_desc(&curproxy->uri_auth, desc)) {
 
1813
                                        free(desc);
 
1814
                                        Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
 
1815
                                        err_code |= ERR_ALERT | ERR_ABORT;
 
1816
                                        goto out;
 
1817
                                }
 
1818
                                free(desc);
1575
1819
                        }
1576
1820
                } else {
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]);
1579
 
                        return -1;
 
1823
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1824
                        goto out;
1580
1825
                }
1581
1826
        }
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]);
1588
 
                        return -1;
 
1833
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1834
                        goto out;
1589
1835
                }
1590
1836
 
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))
1594
 
                                        return 0;
 
1839
                                if (warnifnotcap(curproxy, cfg_opts[optnum].cap, file, linenum, args[1], NULL)) {
 
1840
                                        err_code |= ERR_WARN;
 
1841
                                        goto out;
 
1842
                                }
1595
1843
 
1596
1844
                                if (!inv)
1597
1845
                                        curproxy->options |= cfg_opts[optnum].val;
1598
1846
                                else
1599
1847
                                        curproxy->options &= ~cfg_opts[optnum].val;
1600
1848
 
1601
 
                                return 0;
 
1849
                                goto out;
1602
1850
                        }
1603
1851
                }
1604
1852
 
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))
1608
 
                                        return 0;
 
1855
                                if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL)) {
 
1856
                                        err_code |= ERR_WARN;
 
1857
                                        goto out;
 
1858
                                }
1609
1859
 
1610
1860
                                if (!inv)
1611
1861
                                        curproxy->options2 |= cfg_opts2[optnum].val;
1612
1862
                                else
1613
1863
                                        curproxy->options2 &= ~cfg_opts2[optnum].val;
1614
1864
 
1615
 
                                return 0;
 
1865
                                goto out;
1616
1866
                        }
1617
1867
                }
1618
1868
 
1619
1869
                if (inv) {
1620
1870
                        Alert("parsing [%s:%d]: negation is not supported for option '%s'.\n",
1621
1871
                                file, linenum, args[1]);
1622
 
                        return -1;
 
1872
                        err_code |= ERR_ALERT | ERR_FATAL;
 
1873
                        goto out;
1623
1874
                }
1624
1875
 
1625
1876
                if (!strcmp(args[1], "httplog"))
1631
1882
                else if (!strcmp(args[1], "tcpka")) {
1632
1883
                        /* enable TCP keep-alives on client and server sessions */
1633
1884
                        if (warnifnotcap(curproxy, PR_CAP_BE | PR_CAP_FE, file, linenum, args[1], NULL))
1634
 
                                return 0;
 
1885
                                err_code |= ERR_WARN;
1635
1886
 
1636
1887
                        if (curproxy->cap & PR_CAP_FE)
1637
1888
                                curproxy->options |= PR_O_TCP_CLI_KA;
1640
1891
                }
1641
1892
                else if (!strcmp(args[1], "httpchk")) {
1642
1893
                        if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
1643
 
                                return 0;
 
1894
                                err_code |= ERR_WARN;
 
1895
 
1644
1896
                        /* use HTTP request to check servers' health */
1645
1897
                        free(curproxy->check_req);
1646
1898
                        curproxy->options &= ~PR_O_SSL3_CHK;
1669
1921
                else if (!strcmp(args[1], "ssl-hello-chk")) {
1670
1922
                        /* use SSLv3 CLIENT HELLO to check servers' health */
1671
1923
                        if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
1672
 
                                return 0;
 
1924
                                err_code |= ERR_WARN;
1673
1925
 
1674
1926
                        free(curproxy->check_req);
1675
1927
                        curproxy->options &= ~PR_O_HTTP_CHK;
1721
1973
                                        if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], &curproxy->except_net, &curproxy->except_mask)) {
1722
1974
                                                Alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
1723
1975
                                                      file, linenum, args[0], args[1], args[cur_arg]);
1724
 
                                                return -1;
 
1976
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
1977
                                                goto out;
1725
1978
                                        }
1726
1979
                                        /* flush useless bits */
1727
1980
                                        curproxy->except_net.s_addr &= curproxy->except_mask.s_addr;
1731
1984
                                        if (*(args[cur_arg+1]) == 0) {
1732
1985
                                                Alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
1733
1986
                                                      file, linenum, args[0], args[1], args[cur_arg]);
1734
 
                                                return -1;
 
1987
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
1988
                                                goto out;
1735
1989
                                        }
1736
1990
                                        free(curproxy->fwdfor_hdr_name);
1737
1991
                                        curproxy->fwdfor_hdr_name = strdup(args[cur_arg+1]);
1741
1995
                                        /* unknown suboption - catchall */
1742
1996
                                        Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'except' and 'header'.\n",
1743
1997
                                              file, linenum, args[0], args[1]);
1744
 
                                        return -1;
 
1998
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
1999
                                        goto out;
1745
2000
                                }
1746
2001
                        } /* end while loop */
1747
2002
                }
1766
2021
                                        if (!*(args[cur_arg+1]) || !str2net(args[cur_arg+1], &curproxy->except_to, &curproxy->except_mask_to)) {
1767
2022
                                                Alert("parsing [%s:%d] : '%s %s %s' expects <address>[/mask] as argument.\n",
1768
2023
                                                      file, linenum, args[0], args[1], args[cur_arg]);
1769
 
                                                return -1;
 
2024
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
2025
                                                goto out;
1770
2026
                                        }
1771
2027
                                        /* flush useless bits */
1772
2028
                                        curproxy->except_to.s_addr &= curproxy->except_mask_to.s_addr;
1776
2032
                                        if (*(args[cur_arg+1]) == 0) {
1777
2033
                                                Alert("parsing [%s:%d] : '%s %s %s' expects <header_name> as argument.\n",
1778
2034
                                                      file, linenum, args[0], args[1], args[cur_arg]);
1779
 
                                                return -1;
 
2035
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
2036
                                                goto out;
1780
2037
                                        }
1781
2038
                                        free(curproxy->orgto_hdr_name);
1782
2039
                                        curproxy->orgto_hdr_name = strdup(args[cur_arg+1]);
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]);
1789
 
                                        return -1;
 
2046
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2047
                                        goto out;
1790
2048
                                }
1791
2049
                        } /* end while loop */
1792
2050
                }
1793
2051
                else {
1794
2052
                        Alert("parsing [%s:%d] : unknown option '%s'.\n", file, linenum, args[1]);
1795
 
                        return -1;
 
2053
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2054
                        goto out;
1796
2055
                }
1797
 
                return 0;
 
2056
                goto out;
1798
2057
        }
1799
2058
        else if (!strcmp(args[0], "default_backend")) {
1800
2059
                if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
1801
 
                        return 0;
 
2060
                        err_code |= ERR_WARN;
1802
2061
 
1803
2062
                if (*(args[1]) == 0) {
1804
2063
                        Alert("parsing [%s:%d] : '%s' expects a backend name.\n", file, linenum, args[0]);
1805
 
                        return -1;
 
2064
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2065
                        goto out;
1806
2066
                }
1807
2067
                free(curproxy->defbe.name);
1808
2068
                curproxy->defbe.name = strdup(args[1]);
1809
2069
        }
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))
1812
 
                        return 0;
 
2072
                        err_code |= ERR_WARN;
1813
2073
 
1814
2074
                Warning("parsing [%s:%d]: keyword '%s' is deprecated, please use 'option redispatch' instead.\n",
1815
2075
                                file, linenum, args[0]);
1816
 
 
 
2076
                err_code |= ERR_WARN;
1817
2077
                /* enable reconnections to dispatch */
1818
2078
                curproxy->options |= PR_O_REDISP;
1819
2079
        }
1820
2080
        else if (!strcmp(args[0], "http-check")) {
1821
2081
                if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1822
 
                        return 0;
 
2082
                        err_code |= ERR_WARN;
1823
2083
 
1824
2084
                if (strcmp(args[1], "disable-on-404") == 0) {
1825
2085
                        /* enable a graceful server shutdown on an HTTP 404 response */
1827
2087
                }
1828
2088
                else {
1829
2089
                        Alert("parsing [%s:%d] : '%s' only supports 'disable-on-404'.\n", file, linenum, args[0]);
1830
 
                        return -1;
 
2090
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2091
                        goto out;
1831
2092
                }
1832
2093
        }
1833
2094
        else if (!strcmp(args[0], "monitor")) {
1834
2095
                if (curproxy == &defproxy) {
1835
2096
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
1836
 
                        return -1;
 
2097
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2098
                        goto out;
1837
2099
                }
1838
2100
 
1839
2101
                if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
1840
 
                        return 0;
 
2102
                        err_code |= ERR_WARN;
1841
2103
 
1842
2104
                if (strcmp(args[1], "fail") == 0) {
1843
2105
                        /* add a condition to fail monitor requests */
1852
2114
                        if (pol == ACL_COND_NONE) {
1853
2115
                                Alert("parsing [%s:%d] : '%s %s' requires either 'if' or 'unless' followed by a condition.\n",
1854
2116
                                      file, linenum, args[0], args[1]);
1855
 
                                return -1;
 
2117
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2118
                                goto out;
1856
2119
                        }
1857
2120
 
1858
2121
                        if ((cond = parse_acl_cond((const char **)args + 3, &curproxy->acl, pol)) == NULL) {
1859
2122
                                Alert("parsing [%s:%d] : error detected while parsing a '%s %s' condition.\n",
1860
2123
                                      file, linenum, args[0], args[1]);
1861
 
                                return -1;
 
2124
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2125
                                goto out;
1862
2126
                        }
1863
2127
                        cond->line = linenum;
1864
2128
                        LIST_ADDQ(&curproxy->mon_fail_cond, &cond->list);
1865
2129
                }
1866
2130
                else {
1867
2131
                        Alert("parsing [%s:%d] : '%s' only supports 'fail'.\n", file, linenum, args[0]);
1868
 
                        return -1;
 
2132
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2133
                        goto out;
1869
2134
                }
1870
2135
        }
1871
2136
#ifdef TPROXY
1876
2141
#endif
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 ?"))
1879
 
                        return 0;
 
2144
                        err_code |= ERR_WARN;
1880
2145
 
1881
2146
                if (*(args[1]) == 0) {
1882
2147
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
1883
 
                        return -1;
 
2148
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2149
                        goto out;
1884
2150
                }
1885
2151
                curproxy->maxconn = atol(args[1]);
1886
2152
        }
1887
2153
        else if (!strcmp(args[0], "backlog")) {  /* backlog */
1888
2154
                if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
1889
 
                        return 0;
 
2155
                        err_code |= ERR_WARN;
1890
2156
 
1891
2157
                if (*(args[1]) == 0) {
1892
2158
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
1893
 
                        return -1;
 
2159
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2160
                        goto out;
1894
2161
                }
1895
2162
                curproxy->backlog = atol(args[1]);
1896
2163
        }
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 ?"))
1899
 
                        return 0;
 
2166
                        err_code |= ERR_WARN;
1900
2167
 
1901
2168
                if (*(args[1]) == 0) {
1902
2169
                        Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
1903
 
                        return -1;
 
2170
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2171
                        goto out;
1904
2172
                }
1905
2173
                curproxy->fullconn = atol(args[1]);
1906
2174
        }
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]);
1910
 
                        return -1;
 
2178
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2179
                        goto out;
1911
2180
                }
1912
2181
                err = parse_time_err(args[1], &val, TIME_UNIT_MS);
1913
2182
                if (err) {
1914
2183
                        Alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
1915
2184
                              file, linenum, *err);
1916
 
                        return -1;
 
2185
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2186
                        goto out;
1917
2187
                }
1918
2188
                curproxy->grace = val;
1919
2189
        }
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]);
1923
 
                        return -1;
 
2193
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2194
                        goto out;
1924
2195
                }
1925
2196
                else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1926
 
                        return 0;
 
2197
                        err_code |= ERR_WARN;
1927
2198
 
1928
2199
                if (strchr(args[1], ':') == NULL) {
1929
2200
                        Alert("parsing [%s:%d] : '%s' expects <addr:port> as argument.\n", file, linenum, args[0]);
1930
 
                        return -1;
 
2201
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2202
                        goto out;
1931
2203
                }
1932
2204
                curproxy->dispatch_addr = *str2sa(args[1]);
1933
2205
        }
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))
1936
 
                        return 0;
 
2208
                        err_code |= ERR_WARN;
1937
2209
 
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);
1941
 
                        return -1;
 
2213
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2214
                        goto out;
1942
2215
                }
1943
2216
        }
1944
2217
        else if (!strcmp(args[0], "server")) {  /* server address */
1950
2223
 
1951
2224
                if (curproxy == &defproxy) {
1952
2225
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
1953
 
                        return -1;
 
2226
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2227
                        goto out;
1954
2228
                }
1955
2229
                else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
1956
 
                        return 0;
 
2230
                        err_code |= ERR_ALERT | ERR_FATAL;
1957
2231
 
1958
2232
                if (!*args[2]) {
1959
2233
                        Alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
1960
2234
                              file, linenum, args[0]);
1961
 
                        return -1;
 
2235
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2236
                        goto out;
1962
2237
                }
1963
2238
 
1964
2239
                err = invalid_char(args[1]);
1965
2240
                if (err) {
1966
2241
                        Alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
1967
2242
                              file, linenum, *err, args[1]);
1968
 
                        return -1;
 
2243
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2244
                        goto out;
1969
2245
                }
1970
2246
 
1971
2247
                if ((newsrv = (struct server *)calloc(1, sizeof(struct server))) == NULL) {
1972
2248
                        Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
1973
 
                        return -1;
 
2249
                        err_code |= ERR_ALERT | ERR_ABORT;
 
2250
                        goto out;
1974
2251
                }
1975
2252
 
1976
2253
                /* the servers are linked backwards first */
2027
2304
                                if (!*args[cur_arg + 1]) {
2028
2305
                                        Alert("parsing [%s:%d]: '%s' expects an integer argument.\n",
2029
2306
                                                file, linenum, args[cur_arg]);
2030
 
                                        return -1;
 
2307
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2308
                                        goto out;
2031
2309
                                }
2032
2310
 
2033
2311
                                newsrv->puid = atol(args[cur_arg + 1]);
2034
2312
 
2035
2313
                                if (newsrv->puid< 1001) {
2036
 
                                        Alert("parsing [%s:%d]: custom id has to be > 1000",
 
2314
                                        Alert("parsing [%s:%d]: custom id has to be > 1000.\n",
2037
2315
                                                file, linenum);
2038
 
                                        return -1;
 
2316
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2317
                                        goto out;
2039
2318
                                }
2040
2319
 
2041
2320
                                for (target = proxy->srv; target; target = target->next)
2042
2321
                                        if (newsrv != target && newsrv->puid == target->puid) {
2043
2322
                                                Alert("parsing [%s:%d]: custom id has to be unique but is duplicated in %s and %s.\n",
2044
2323
                                                        file, linenum, newsrv->id, target->id);
2045
 
                                                return -1;
 
2324
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
2325
                                                goto out;
2046
2326
                                        }
2047
2327
                                cur_arg += 2;
2048
2328
                        }
2057
2337
                                cur_arg += 2;
2058
2338
                        }
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;
 
2344
                                        goto out;
 
2345
                                }
 
2346
 
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;
 
2352
                                        goto out;
 
2353
                                }
 
2354
 
2061
2355
                                newsrv->health = newsrv->rise;
2062
2356
                                cur_arg += 2;
2063
2357
                        }
2064
2358
                        else if (!strcmp(args[cur_arg], "fall")) {
2065
2359
                                newsrv->fall = atol(args[cur_arg + 1]);
 
2360
 
 
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;
 
2365
                                        goto out;
 
2366
                                }
 
2367
 
 
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;
 
2372
                                        goto out;
 
2373
                                }
 
2374
 
2066
2375
                                cur_arg += 2;
2067
2376
                        }
2068
2377
                        else if (!strcmp(args[cur_arg], "inter")) {
2070
2379
                                if (err) {
2071
2380
                                        Alert("parsing [%s:%d] : unexpected character '%c' in 'inter' argument of server %s.\n",
2072
2381
                                              file, linenum, *err, newsrv->id);
2073
 
                                        return -1;
 
2382
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2383
                                        goto out;
2074
2384
                                }
2075
2385
                                if (val <= 0) {
2076
2386
                                        Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2077
2387
                                              file, linenum, val, args[cur_arg], newsrv->id);
2078
 
                                        return -1;
 
2388
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2389
                                        goto out;
2079
2390
                                }
2080
2391
                                newsrv->inter = val;
2081
2392
                                cur_arg += 2;
2085
2396
                                if (err) {
2086
2397
                                        Alert("parsing [%s:%d]: unexpected character '%c' in 'fastinter' argument of server %s.\n",
2087
2398
                                              file, linenum, *err, newsrv->id);
2088
 
                                        return -1;
 
2399
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2400
                                        goto out;
2089
2401
                                }
2090
2402
                                if (val <= 0) {
2091
2403
                                        Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2092
2404
                                              file, linenum, val, args[cur_arg], newsrv->id);
2093
 
                                        return -1;
 
2405
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2406
                                        goto out;
2094
2407
                                }
2095
2408
                                newsrv->fastinter = val;
2096
2409
                                cur_arg += 2;
2100
2413
                                if (err) {
2101
2414
                                        Alert("parsing [%s:%d]: unexpected character '%c' in 'downinter' argument of server %s.\n",
2102
2415
                                              file, linenum, *err, newsrv->id);
2103
 
                                        return -1;
 
2416
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2417
                                        goto out;
2104
2418
                                }
2105
2419
                                if (val <= 0) {
2106
2420
                                        Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2107
2421
                                              file, linenum, val, args[cur_arg], newsrv->id);
2108
 
                                        return -1;
 
2422
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2423
                                        goto out;
2109
2424
                                }
2110
2425
                                newsrv->downinter = val;
2111
2426
                                cur_arg += 2;
2125
2440
                        else if (!strcmp(args[cur_arg], "weight")) {
2126
2441
                                int w;
2127
2442
                                w = atol(args[cur_arg + 1]);
2128
 
                                if (w < 1 || w > 256) {
2129
 
                                        Alert("parsing [%s:%d] : weight of server %s is not within 1 and 256 (%d).\n",
 
2443
                                if (w < 0 || w > 256) {
 
2444
                                        Alert("parsing [%s:%d] : weight of server %s is not within 0 and 256 (%d).\n",
2130
2445
                                              file, linenum, newsrv->id, w);
2131
 
                                        return -1;
 
2446
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2447
                                        goto out;
2132
2448
                                }
2133
2449
                                newsrv->uweight = w;
2134
2450
                                cur_arg += 2;
2151
2467
                                if (err) {
2152
2468
                                        Alert("parsing [%s:%d] : unexpected character '%c' in 'slowstart' argument of server %s.\n",
2153
2469
                                              file, linenum, *err, newsrv->id);
2154
 
                                        return -1;
 
2470
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2471
                                        goto out;
2155
2472
                                }
2156
2473
                                if (val <= 0) {
2157
2474
                                        Alert("parsing [%s:%d]: invalid value %d for argument '%s' of server %s.\n",
2158
2475
                                              file, linenum, val, args[cur_arg], newsrv->id);
2159
 
                                        return -1;
 
2476
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2477
                                        goto out;
2160
2478
                                }
2161
2479
                                newsrv->slowstart = (val + 999) / 1000;
2162
2480
                                cur_arg += 2;
2166
2484
                                if (!*args[cur_arg + 1]) {
2167
2485
                                        Alert("parsing [%s:%d]: 'track' expects [<proxy>/]<server> as argument.\n",
2168
2486
                                                file, linenum);
2169
 
                                        return -1;
 
2487
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2488
                                        goto out;
2170
2489
                                }
2171
2490
 
2172
2491
                                newsrv->trackit = strdup(args[cur_arg + 1]);
2179
2498
                                cur_arg += 1;
2180
2499
                        }
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");
2186
2506
#else
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");
2189
2509
#endif
2190
 
                                        return -1;
 
2510
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2511
                                        goto out;
2191
2512
                                }
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);
 
2515
 
 
2516
                                if (port_low != port_high) {
 
2517
                                        int i;
 
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;
 
2524
                                                goto out;
 
2525
                                        }
 
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;
 
2529
                                }
 
2530
 
2194
2531
                                cur_arg += 2;
2195
2532
                                while (*(args[cur_arg])) {
2196
2533
                                        if (!strcmp(args[cur_arg], "usesrc")) {  /* address to use outside */
2199
2536
                                                if (newsrv->source_addr.sin_addr.s_addr == INADDR_ANY) {
2200
2537
                                                        Alert("parsing [%s:%d] : '%s' requires an explicit '%s' address.\n",
2201
2538
                                                              file, linenum, "usesrc", "source");
2202
 
                                                        return -1;
 
2539
                                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2540
                                                        goto out;
2203
2541
                                                }
2204
2542
#endif
2205
2543
                                                if (!*args[cur_arg + 1]) {
2206
2544
                                                        Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
2207
2545
                                                              file, linenum, "usesrc");
2208
 
                                                        return -1;
 
2546
                                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2547
                                                        goto out;
2209
2548
                                                }
2210
2549
                                                if (!strcmp(args[cur_arg + 1], "client")) {
2211
2550
                                                        newsrv->state |= SRV_TPROXY_CLI;
2224
2563
#else   /* no TPROXY support */
2225
2564
                                                Alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
2226
2565
                                                      file, linenum, "usesrc");
2227
 
                                                return -1;
 
2566
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
2567
                                                goto out;
2228
2568
#endif /* defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY) */
2229
2569
                                        } /* "usesrc" */
2230
2570
 
2233
2573
                                                if (!*args[cur_arg + 1]) {
2234
2574
                                                        Alert("parsing [%s:%d] : '%s' : missing interface name.\n",
2235
2575
                                                              file, linenum, args[0]);
2236
 
                                                        return -1;
 
2576
                                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2577
                                                        goto out;
2237
2578
                                                }
2238
2579
                                                if (newsrv->iface_name)
2239
2580
                                                        free(newsrv->iface_name);
2244
2585
#else
2245
2586
                                                Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
2246
2587
                                                      file, linenum, args[0], args[cur_arg]);
2247
 
                                                return -1;
 
2588
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
2589
                                                goto out;
2248
2590
#endif
2249
2591
                                                cur_arg += 2;
2250
2592
                                                continue;
2256
2598
                        else if (!strcmp(args[cur_arg], "usesrc")) {  /* address to use outside: needs "source" first */
2257
2599
                                Alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
2258
2600
                                      file, linenum, "usesrc", "source");
2259
 
                                return -1;
 
2601
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2602
                                goto out;
2260
2603
                        }
2261
2604
                        else {
2262
2605
                                Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'track', 'id', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
2263
2606
                                      file, linenum, newsrv->id);
2264
 
                                return -1;
 
2607
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2608
                                goto out;
2265
2609
                        }
2266
2610
                }
2267
2611
 
2269
2613
                        if (newsrv->trackit) {
2270
2614
                                Alert("parsing [%s:%d]: unable to enable checks and tracking at the same time!\n",
2271
2615
                                        file, linenum);
2272
 
                                return -1;
 
2616
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2617
                                goto out;
2273
2618
                        }
2274
2619
 
2275
2620
                        if (!newsrv->check_port && newsrv->check_addr.sin_port)
2295
2640
                        if (!newsrv->check_port) {
2296
2641
                                Alert("parsing [%s:%d] : server %s has neither service port nor check port. Check has been disabled.\n",
2297
2642
                                      file, linenum, newsrv->id);
2298
 
                                return -1;
 
2643
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2644
                                goto out;
2299
2645
                        }
2300
2646
                        newsrv->state |= SRV_CHECKED;
2301
2647
                }
2374
2720
                        }
2375
2721
                        else {
2376
2722
                                Alert("parsing [%s:%d] : too many syslog servers\n", file, linenum);
2377
 
                                return -1;
 
2723
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2724
                                goto out;
2378
2725
                        }
2379
2726
                }
2380
2727
                else {
2381
2728
                        Alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
2382
2729
                              file, linenum);
2383
 
                        return -1;
 
2730
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2731
                        goto out;
2384
2732
                }
2385
2733
        }
2386
2734
        else if (!strcmp(args[0], "source")) {  /* address to which we bind when connecting */
2387
2735
                int cur_arg;
2388
2736
 
2389
2737
                if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
2390
 
                        return 0;
 
2738
                        err_code |= ERR_WARN;
2391
2739
 
2392
2740
                if (!*args[1]) {
2393
2741
                        Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], and optionally '%s' <addr>, and '%s' <name>.\n",
2394
2742
                              file, linenum, "source", "usesrc", "interface");
2395
 
                        return -1;
 
2743
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2744
                        goto out;
2396
2745
                }
2397
2746
 
2398
2747
                /* we must first clear any optional default setting */  
2412
2761
                                if (curproxy->source_addr.sin_addr.s_addr == INADDR_ANY) {
2413
2762
                                        Alert("parsing [%s:%d] : '%s' requires an explicit 'source' address.\n",
2414
2763
                                              file, linenum, "usesrc");
2415
 
                                        return -1;
 
2764
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2765
                                        goto out;
2416
2766
                                }
2417
2767
#endif
2418
2768
                                if (!*args[cur_arg + 1]) {
2419
2769
                                        Alert("parsing [%s:%d] : '%s' expects <addr>[:<port>], 'client', or 'clientip' as argument.\n",
2420
2770
                                              file, linenum, "usesrc");
2421
 
                                        return -1;
 
2771
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2772
                                        goto out;
2422
2773
                                }
2423
2774
 
2424
2775
                                if (!strcmp(args[cur_arg + 1], "client")) {
2436
2787
#else   /* no TPROXY support */
2437
2788
                                Alert("parsing [%s:%d] : '%s' not allowed here because support for TPROXY was not compiled in.\n",
2438
2789
                                      file, linenum, "usesrc");
2439
 
                                return -1;
 
2790
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2791
                                goto out;
2440
2792
#endif
2441
2793
                                cur_arg += 2;
2442
2794
                                continue;
2447
2799
                                if (!*args[cur_arg + 1]) {
2448
2800
                                        Alert("parsing [%s:%d] : '%s' : missing interface name.\n",
2449
2801
                                              file, linenum, args[0]);
2450
 
                                        return -1;
 
2802
                                        err_code |= ERR_ALERT | ERR_FATAL;
 
2803
                                        goto out;
2451
2804
                                }
2452
2805
                                if (curproxy->iface_name)
2453
2806
                                        free(curproxy->iface_name);
2458
2811
#else
2459
2812
                                Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
2460
2813
                                      file, linenum, args[0], args[cur_arg]);
2461
 
                                return -1;
 
2814
                                err_code |= ERR_ALERT | ERR_FATAL;
 
2815
                                goto out;
2462
2816
#endif
2463
2817
                                cur_arg += 2;
2464
2818
                                continue;
2465
2819
                        }
2466
2820
                        Alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
2467
2821
                              file, linenum, args[0], "inteface", "usesrc");
2468
 
                        return -1;
 
2822
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2823
                        goto out;
2469
2824
                }
2470
2825
        }
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");
2474
 
                return -1;
 
2829
                err_code |= ERR_ALERT | ERR_FATAL;
 
2830
                goto out;
2475
2831
        }
2476
2832
        else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) {  /* replace request header from a regex */
2477
2833
                regex_t *preg;
2478
2834
                if (curproxy == &defproxy) {
2479
2835
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2480
 
                        return -1;
 
2836
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2837
                        goto out;
2481
2838
                }
2482
2839
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2483
 
                        return 0;
 
2840
                        err_code |= ERR_WARN;
2484
2841
 
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]);
2488
 
                        return -1;
 
2845
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2846
                        goto out;
2489
2847
                }
2490
2848
        
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]);
2494
 
                        return -1;
 
2852
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2853
                        goto out;
2495
2854
                }
2496
2855
        
2497
2856
                err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]));
2498
2857
                if (err) {
2499
2858
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2500
2859
                              file, linenum, *err);
2501
 
                        return -1;
 
2860
                        err_code |= ERR_ALERT | ERR_FATAL;
2502
2861
                }
2503
2862
                warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
2504
2863
        }
2506
2865
                regex_t *preg;
2507
2866
                if (curproxy == &defproxy) {
2508
2867
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2509
 
                        return -1;
 
2868
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2869
                        goto out;
2510
2870
                }
2511
2871
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2512
 
                        return 0;
 
2872
                        err_code |= ERR_WARN;
2513
2873
 
2514
2874
                if (*(args[1]) == 0) {
2515
2875
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2516
 
                        return -1;
 
2876
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2877
                        goto out;
2517
2878
                }
2518
2879
        
2519
2880
                preg = calloc(1, sizeof(regex_t));
2520
2881
                if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2521
2882
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2522
 
                        return -1;
 
2883
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2884
                        goto out;
2523
2885
                }
2524
2886
        
2525
2887
                chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL);
2529
2891
                regex_t *preg;
2530
2892
                if (curproxy == &defproxy) {
2531
2893
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2532
 
                        return -1;
 
2894
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2895
                        goto out;
2533
2896
                }
2534
2897
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2535
 
                        return 0;
 
2898
                        err_code |= ERR_WARN;
2536
2899
 
2537
2900
                if (*(args[1]) == 0) {
2538
2901
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2539
 
                        return -1;
 
2902
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2903
                        goto out;
2540
2904
                }
2541
2905
        
2542
2906
                preg = calloc(1, sizeof(regex_t));
2543
2907
                if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2544
2908
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2545
 
                        return -1;
 
2909
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2910
                        goto out;
2546
2911
                }
2547
2912
        
2548
2913
                chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL);
2552
2917
                regex_t *preg;
2553
2918
                if (curproxy == &defproxy) {
2554
2919
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2555
 
                        return -1;
 
2920
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2921
                        goto out;
2556
2922
                }
2557
2923
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2558
 
                        return 0;
 
2924
                        err_code |= ERR_WARN;
2559
2925
 
2560
2926
                if (*(args[1]) == 0) {
2561
2927
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2562
 
                        return -1;
 
2928
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2929
                        goto out;
2563
2930
                }
2564
2931
        
2565
2932
                preg = calloc(1, sizeof(regex_t));
2566
2933
                if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2567
2934
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2568
 
                        return -1;
 
2935
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2936
                        goto out;
2569
2937
                }
2570
2938
        
2571
2939
                chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL);
2575
2943
                regex_t *preg;
2576
2944
                if (curproxy == &defproxy) {
2577
2945
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2578
 
                        return -1;
 
2946
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2947
                        goto out;
2579
2948
                }
2580
2949
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2581
 
                        return 0;
 
2950
                        err_code |= ERR_WARN;
2582
2951
 
2583
2952
                if (*(args[1]) == 0) {
2584
2953
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2585
 
                        return -1;
 
2954
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2955
                        goto out;
2586
2956
                }
2587
2957
        
2588
2958
                preg = calloc(1, sizeof(regex_t));
2589
2959
                if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2590
2960
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2591
 
                        return -1;
 
2961
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2962
                        goto out;
2592
2963
                }
2593
2964
        
2594
2965
                chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL);
2598
2969
                regex_t *preg;
2599
2970
                if (curproxy == &defproxy) {
2600
2971
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2601
 
                        return -1;
 
2972
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2973
                        goto out;
2602
2974
                }
2603
2975
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2604
 
                        return 0;
 
2976
                        err_code |= ERR_WARN;
2605
2977
 
2606
2978
                if (*(args[1]) == 0) {
2607
2979
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2608
 
                        return -1;
 
2980
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2981
                        goto out;
2609
2982
                }
2610
2983
        
2611
2984
                preg = calloc(1, sizeof(regex_t));
2612
2985
                if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2613
2986
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2614
 
                        return -1;
 
2987
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2988
                        goto out;
2615
2989
                }
2616
2990
        
2617
2991
                chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL);
2621
2995
                regex_t *preg;
2622
2996
                if (curproxy == &defproxy) {
2623
2997
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2624
 
                        return -1;
 
2998
                        err_code |= ERR_ALERT | ERR_FATAL;
 
2999
                        goto out;
2625
3000
                }
2626
3001
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2627
 
                        return 0;
 
3002
                        err_code |= ERR_WARN;
2628
3003
 
2629
3004
                if (*(args[1]) == 0 || *(args[2]) == 0) {
2630
3005
                        Alert("parsing [%s:%d] : '%s' expects <search> and <target> as arguments.\n", 
2631
3006
                                file, linenum, args[0]);
2632
 
                        return -1;      
 
3007
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3008
                        goto out;
2633
3009
                }
2634
3010
                
2635
3011
                preg = calloc(1, sizeof(regex_t));
2636
3012
                if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2637
3013
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
 
3014
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3015
                        goto out;
2638
3016
                }
2639
3017
 
2640
3018
                chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2]));
2644
3022
                regex_t *preg;
2645
3023
                if (curproxy == &defproxy) {
2646
3024
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2647
 
                        return -1;
 
3025
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3026
                        goto out;
2648
3027
                }
2649
3028
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2650
 
                        return 0;
 
3029
                        err_code |= ERR_WARN;
2651
3030
 
2652
3031
                if (*(args[1]) == 0 || *(args[2]) == 0) {
2653
3032
                        Alert("parsing [%s:%d] : '%s' expects <search> and <target> as arguments.\n", 
2654
3033
                              file, linenum, args[0]);
2655
 
                        return -1;      
 
3034
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3035
                        goto out;
2656
3036
                }
2657
3037
                
2658
3038
                preg = calloc(1, sizeof(regex_t));
2659
3039
                if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2660
3040
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
 
3041
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3042
                        goto out;
2661
3043
                }
2662
3044
 
2663
3045
                chain_regex(&curproxy->req_exp, preg, ACT_SETBE, strdup(args[2]));
2667
3049
                regex_t *preg;
2668
3050
                if (curproxy == &defproxy) {
2669
3051
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2670
 
                        return -1;
 
3052
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3053
                        goto out;
2671
3054
                }
2672
3055
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2673
 
                        return 0;
 
3056
                        err_code |= ERR_WARN;
2674
3057
 
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]);
2678
 
                        return -1;
 
3061
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3062
                        goto out;
2679
3063
                }
2680
3064
        
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]);
2684
 
                        return -1;
 
3068
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3069
                        goto out;
2685
3070
                }
2686
3071
        
2687
3072
                err = chain_regex(&curproxy->req_exp, preg, ACT_REPLACE, strdup(args[2]));
2688
3073
                if (err) {
2689
3074
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2690
3075
                              file, linenum, *err);
2691
 
                        return -1;
 
3076
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3077
                        goto out;
2692
3078
                }
2693
3079
                warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
2694
3080
        }
2696
3082
                regex_t *preg;
2697
3083
                if (curproxy == &defproxy) {
2698
3084
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2699
 
                        return -1;
 
3085
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3086
                        goto out;
2700
3087
                }
2701
3088
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2702
 
                        return 0;
 
3089
                        err_code |= ERR_WARN;
2703
3090
 
2704
3091
                if (*(args[1]) == 0) {
2705
3092
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2706
 
                        return -1;
 
3093
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3094
                        goto out;
2707
3095
                }
2708
3096
        
2709
3097
                preg = calloc(1, sizeof(regex_t));
2710
3098
                if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2711
3099
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2712
 
                        return -1;
 
3100
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3101
                        goto out;
2713
3102
                }
2714
3103
        
2715
3104
                chain_regex(&curproxy->req_exp, preg, ACT_REMOVE, NULL);
2719
3108
                regex_t *preg;
2720
3109
                if (curproxy == &defproxy) {
2721
3110
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2722
 
                        return -1;
 
3111
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3112
                        goto out;
2723
3113
                }
2724
3114
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2725
 
                        return 0;
 
3115
                        err_code |= ERR_WARN;
2726
3116
 
2727
3117
                if (*(args[1]) == 0) {
2728
3118
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2729
 
                        return -1;
 
3119
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3120
                        goto out;
2730
3121
                }
2731
3122
        
2732
3123
                preg = calloc(1, sizeof(regex_t));
2733
3124
                if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2734
3125
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2735
 
                        return -1;
 
3126
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3127
                        goto out;
2736
3128
                }
2737
3129
        
2738
3130
                chain_regex(&curproxy->req_exp, preg, ACT_DENY, NULL);
2742
3134
                regex_t *preg;
2743
3135
                if (curproxy == &defproxy) {
2744
3136
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2745
 
                        return -1;
 
3137
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3138
                        goto out;
2746
3139
                }
2747
3140
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2748
 
                        return 0;
 
3141
                        err_code |= ERR_WARN;
2749
3142
 
2750
3143
                if (*(args[1]) == 0) {
2751
3144
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2752
 
                        return -1;
 
3145
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3146
                        goto out;
2753
3147
                }
2754
3148
        
2755
3149
                preg = calloc(1, sizeof(regex_t));
2756
3150
                if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2757
3151
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2758
 
                        return -1;
 
3152
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3153
                        goto out;
2759
3154
                }
2760
3155
        
2761
3156
                chain_regex(&curproxy->req_exp, preg, ACT_PASS, NULL);
2765
3160
                regex_t *preg;
2766
3161
                if (curproxy == &defproxy) {
2767
3162
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2768
 
                        return -1;
 
3163
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3164
                        goto out;
2769
3165
                }
2770
3166
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2771
 
                        return 0;
 
3167
                        err_code |= ERR_WARN;
2772
3168
 
2773
3169
                if (*(args[1]) == 0) {
2774
3170
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2775
 
                        return -1;
 
3171
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3172
                        goto out;
2776
3173
                }
2777
3174
        
2778
3175
                preg = calloc(1, sizeof(regex_t));
2779
3176
                if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2780
3177
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2781
 
                        return -1;
 
3178
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3179
                        goto out;
2782
3180
                }
2783
3181
        
2784
3182
                chain_regex(&curproxy->req_exp, preg, ACT_ALLOW, NULL);
2788
3186
                regex_t *preg;
2789
3187
                if (curproxy == &defproxy) {
2790
3188
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2791
 
                        return -1;
 
3189
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3190
                        goto out;
2792
3191
                }
2793
3192
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2794
 
                        return 0;
 
3193
                        err_code |= ERR_WARN;
2795
3194
 
2796
3195
                if (*(args[1]) == 0) {
2797
3196
                        Alert("parsing [%s:%d] : '%s' expects <regex> as an argument.\n", file, linenum, args[0]);
2798
 
                        return -1;
 
3197
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3198
                        goto out;
2799
3199
                }
2800
3200
        
2801
3201
                preg = calloc(1, sizeof(regex_t));
2802
3202
                if (regcomp(preg, args[1], REG_EXTENDED | REG_ICASE) != 0) {
2803
3203
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2804
 
                        return -1;
 
3204
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3205
                        goto out;
2805
3206
                }
2806
3207
        
2807
3208
                chain_regex(&curproxy->req_exp, preg, ACT_TARPIT, NULL);
2810
3211
        else if (!strcmp(args[0], "reqadd")) {  /* add request header */
2811
3212
                if (curproxy == &defproxy) {
2812
3213
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2813
 
                        return -1;
 
3214
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3215
                        goto out;
2814
3216
                }
2815
3217
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2816
 
                        return 0;
 
3218
                        err_code |= ERR_WARN;
2817
3219
 
2818
3220
                if (curproxy->nb_reqadd >= MAX_NEWHDR) {
2819
3221
                        Alert("parsing [%s:%d] : too many '%s'. Continuing.\n", file, linenum, args[0]);
2820
 
                        return 0;
 
3222
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3223
                        goto out;
2821
3224
                }
2822
3225
        
2823
3226
                if (*(args[1]) == 0) {
2824
3227
                        Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
2825
 
                        return -1;
 
3228
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3229
                        goto out;
2826
3230
                }
2827
3231
        
2828
3232
                curproxy->req_add[curproxy->nb_reqadd++] = strdup(args[1]);
2834
3238
                if (*(args[1]) == 0 || *(args[2]) == 0) {
2835
3239
                        Alert("parsing [%s:%d] : '%s' expects <search> and <replace> as arguments.\n",
2836
3240
                              file, linenum, args[0]);
2837
 
                        return -1;
 
3241
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3242
                        goto out;
2838
3243
                }
2839
3244
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2840
 
                        return 0;
 
3245
                        err_code |= ERR_WARN;
2841
3246
 
2842
3247
                preg = calloc(1, sizeof(regex_t));
2843
3248
                if (regcomp(preg, args[1], REG_EXTENDED) != 0) {
2844
3249
                        Alert("parsing [%s:%d] : bad regular expression '%s'.\n", file, linenum, args[1]);
2845
 
                        return -1;
 
3250
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3251
                        goto out;
2846
3252
                }
2847
3253
        
2848
3254
                err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2]));
2849
3255
                if (err) {
2850
3256
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2851
3257
                              file, linenum, *err);
2852
 
                        return -1;
 
3258
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3259
                        goto out;
2853
3260
                }
2854
3261
                warnif_misplaced_reqxxx(curproxy, file, linenum, args[0]);
2855
3262
        }
2857
3264
                regex_t *preg;
2858
3265
                if (curproxy == &defproxy) {
2859
3266
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2860
 
                        return -1;
 
3267
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3268
                        goto out;
2861
3269
                }
2862
3270
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2863
 
                        return 0;
 
3271
                        err_code |= ERR_WARN;
2864
3272
 
2865
3273
                if (*(args[1]) == 0) {
2866
3274
                        Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
2867
 
                        return -1;
 
3275
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3276
                        goto out;
2868
3277
                }
2869
3278
 
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]);
2873
 
                        return -1;
 
3282
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3283
                        goto out;
2874
3284
                }
2875
3285
        
2876
3286
                err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]));
2877
3287
                if (err) {
2878
3288
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2879
3289
                              file, linenum, *err);
2880
 
                        return -1;
 
3290
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3291
                        goto out;
2881
3292
                }
2882
3293
        }
2883
3294
        else if (!strcmp(args[0], "rspdeny")) {  /* block response header from a regex */
2884
3295
                regex_t *preg;
2885
3296
                if (curproxy == &defproxy) {
2886
3297
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2887
 
                        return -1;
 
3298
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3299
                        goto out;
2888
3300
                }
2889
3301
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2890
 
                        return 0;
 
3302
                        err_code |= ERR_WARN;
2891
3303
 
2892
3304
                if (*(args[1]) == 0) {
2893
3305
                        Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
2894
 
                        return -1;
 
3306
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3307
                        goto out;
2895
3308
                }
2896
3309
 
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]);
2900
 
                        return -1;
 
3313
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3314
                        goto out;
2901
3315
                }
2902
3316
        
2903
3317
                err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]));
2904
3318
                if (err) {
2905
3319
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2906
3320
                              file, linenum, *err);
2907
 
                        return -1;
 
3321
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3322
                        goto out;
2908
3323
                }
2909
3324
        }
2910
3325
        else if (!strcmp(args[0], "rspirep")) {  /* replace response header from a regex ignoring case */
2911
3326
                regex_t *preg;
2912
3327
                if (curproxy == &defproxy) {
2913
3328
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2914
 
                        return -1;
 
3329
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3330
                        goto out;
2915
3331
                }
2916
3332
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2917
 
                        return 0;
 
3333
                        err_code |= ERR_WARN;
2918
3334
 
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]);
2922
 
                        return -1;
 
3338
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3339
                        goto out;
2923
3340
                }
2924
3341
 
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]);
2928
 
                        return -1;
 
3345
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3346
                        goto out;
2929
3347
                }
2930
3348
            
2931
3349
                err = chain_regex(&curproxy->rsp_exp, preg, ACT_REPLACE, strdup(args[2]));
2932
3350
                if (err) {
2933
3351
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2934
3352
                              file, linenum, *err);
2935
 
                        return -1;
 
3353
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3354
                        goto out;
2936
3355
                }
2937
3356
        }
2938
3357
        else if (!strcmp(args[0], "rspidel")) {  /* delete response header from a regex ignoring case */
2939
3358
                regex_t *preg;
2940
3359
                if (curproxy == &defproxy) {
2941
3360
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2942
 
                        return -1;
 
3361
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3362
                        goto out;
2943
3363
                }
2944
3364
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2945
 
                        return 0;
 
3365
                        err_code |= ERR_WARN;
2946
3366
 
2947
3367
                if (*(args[1]) == 0) {
2948
3368
                        Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
2949
 
                        return -1;
 
3369
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3370
                        goto out;
2950
3371
                }
2951
3372
 
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]);
2955
 
                        return -1;
 
3376
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3377
                        goto out;
2956
3378
                }
2957
3379
        
2958
3380
                err = chain_regex(&curproxy->rsp_exp, preg, ACT_REMOVE, strdup(args[2]));
2959
3381
                if (err) {
2960
3382
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2961
3383
                              file, linenum, *err);
2962
 
                        return -1;
 
3384
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3385
                        goto out;
2963
3386
                }
2964
3387
        }
2965
3388
        else if (!strcmp(args[0], "rspideny")) {  /* block response header from a regex ignoring case */
2966
3389
                regex_t *preg;
2967
3390
                if (curproxy == &defproxy) {
2968
3391
                        Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
2969
 
                        return -1;
 
3392
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3393
                        goto out;
2970
3394
                }
2971
3395
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2972
 
                        return 0;
 
3396
                        err_code |= ERR_WARN;
2973
3397
 
2974
3398
                if (*(args[1]) == 0) {
2975
3399
                        Alert("parsing [%s:%d] : '%s' expects <search> as an argument.\n", file, linenum, args[0]);
2976
 
                        return -1;
 
3400
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3401
                        goto out;
2977
3402
                }
2978
3403
 
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]);
2982
 
                        return -1;
 
3407
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3408
                        goto out;
2983
3409
                }
2984
3410
        
2985
3411
                err = chain_regex(&curproxy->rsp_exp, preg, ACT_DENY, strdup(args[2]));
2986
3412
                if (err) {
2987
3413
                        Alert("parsing [%s:%d] : invalid character or unterminated sequence in replacement string near '%c'.\n",
2988
3414
                              file, linenum, *err);
2989
 
                        return -1;
 
3415
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3416
                        goto out;
2990
3417
                }
2991
3418
        }
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]);
2995
 
                        return -1;
 
3422
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3423
                        goto out;
2996
3424
                }
2997
3425
                else if (warnifnotcap(curproxy, PR_CAP_RS, file, linenum, args[0], NULL))
2998
 
                        return 0;
 
3426
                        err_code |= ERR_WARN;
2999
3427
 
3000
3428
                if (curproxy->nb_rspadd >= MAX_NEWHDR) {
3001
3429
                        Alert("parsing [%s:%d] : too many '%s'. Continuing.\n", file, linenum, args[0]);
3002
 
                        return 0;
 
3430
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3431
                        goto out;
3003
3432
                }
3004
3433
        
3005
3434
                if (*(args[1]) == 0) {
3006
3435
                        Alert("parsing [%s:%d] : '%s' expects <header> as an argument.\n", file, linenum, args[0]);
3007
 
                        return -1;
 
3436
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3437
                        goto out;
3008
3438
                }
3009
3439
        
3010
3440
                curproxy->rsp_add[curproxy->nb_rspadd++] = strdup(args[1]);
3016
3446
                char *err;
3017
3447
 
3018
3448
                if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
3019
 
                        return 0;
 
3449
                        err_code |= ERR_WARN;
3020
3450
 
3021
3451
                if (*(args[2]) == 0) {
3022
3452
                        Alert("parsing [%s:%d] : <%s> expects <status_code> and <url> as arguments.\n", file, linenum, args[0]);
3023
 
                        return -1;
 
3453
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3454
                        goto out;
3024
3455
                }
3025
3456
 
3026
3457
                errnum = atol(args[1]);
3053
3484
                struct stat stat;
3054
3485
 
3055
3486
                if (warnifnotcap(curproxy, PR_CAP_FE | PR_CAP_BE, file, linenum, args[0], NULL))
3056
 
                        return 0;
 
3487
                        err_code |= ERR_WARN;
3057
3488
 
3058
3489
                if (*(args[2]) == 0) {
3059
3490
                        Alert("parsing [%s:%d] : <%s> expects <status_code> and <file> as arguments.\n", file, linenum, args[0]);
3060
 
                        return -1;
 
3491
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3492
                        goto out;
3061
3493
                }
3062
3494
 
3063
3495
                fd = open(args[2], O_RDONLY);
3066
3498
                              file, linenum, args[2], args[1]);
3067
3499
                        if (fd >= 0)
3068
3500
                                close(fd);
3069
 
                        return -1;
 
3501
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3502
                        goto out;
3070
3503
                }
3071
3504
 
3072
3505
                if (stat.st_size <= BUFSIZE) {
3074
3507
                } else {
3075
3508
                        Warning("parsing [%s:%d] : custom error message file <%s> larger than %d bytes. Truncating.\n",
3076
3509
                                file, linenum, args[2], BUFSIZE);
 
3510
                        err_code |= ERR_WARN;
3077
3511
                        errlen = BUFSIZE;
3078
3512
                }
3079
3513
 
3084
3518
                              file, linenum, args[2], args[1]);
3085
3519
                        close(fd);
3086
3520
                        free(err);
3087
 
                        return -1;
 
3521
                        err_code |= ERR_ALERT | ERR_FATAL;
 
3522
                        goto out;
3088
3523
                }
3089
3524
                close(fd);
3090
3525
 
3101
3536
                if (rc >= HTTP_ERR_SIZE) {
3102
3537
                        Warning("parsing [%s:%d] : status code %d not handled, error customization will be ignored.\n",
3103
3538
                                file, linenum, errnum);
 
3539
                        err_code |= ERR_WARN;
3104
3540
                        free(err);
3105
3541
                }
3106
3542
        }
3119
3555
                                        rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, sizeof(trash));
3120
3556
                                        if (rc < 0) {
3121
3557
                                                Alert("parsing [%s:%d] : %s\n", file, linenum, trash);
3122
 
                                                return -1;
 
3558
                                                err_code |= ERR_ALERT | ERR_FATAL;
 
3559
                                                goto out;
3123
3560
                                        }
3124
3561
                                        else if (rc > 0) {
3125
3562
                                                Warning("parsing [%s:%d] : %s\n", file, linenum, trash);
3126
 
                                                return 0;
 
3563
                                                err_code |= ERR_WARN;
 
3564
                                                goto out;
3127
3565
                                        }
3128
 
                                        return 0;
 
3566
                                        goto out;
3129
3567
                                }
3130
3568
                        }
3131
3569
                }
3132
3570
                
3133
3571
                Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection);
3134
 
                return -1;
 
3572
                err_code |= ERR_ALERT | ERR_FATAL;
 
3573
                goto out;
3135
3574
        }
3136
 
        return 0;
 
3575
 out:
 
3576
        return err_code;
3137
3577
}
3138
3578
 
3139
3579
 
3140
3580
/*
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
 
3588
 * indicators.
3143
3589
 */
3144
3590
int readcfgfile(const char *file)
3145
3591
{
3146
3592
        char thisline[LINESIZE];
3147
3593
        FILE *f;
3148
3594
        int linenum = 0;
3149
 
        int cfgerr = 0;
3150
3595
        int confsect = CFG_NONE;
3151
 
 
3152
 
        struct proxy *curproxy = NULL;
3153
 
        struct server *newsrv = NULL;
 
3596
        int err_code = 0;
3154
3597
 
3155
3598
        if ((f=fopen(file,"r")) == NULL)
3156
3599
                return -1;
3157
3600
 
3158
 
        init_default_instance();
3159
 
 
3160
3601
        while (fgets(thisline, sizeof(thisline), f) != NULL) {
3161
3602
                int arg, inv = 0 ;
3162
3603
                char *end;
3173
3614
                         */
3174
3615
                        Alert("parsing [%s:%d]: line too long, limit: %d.\n",
3175
3616
                              file, linenum, (int)sizeof(thisline)-1);
3176
 
                        goto err;
 
3617
                        err_code |= ERR_ALERT | ERR_FATAL;
3177
3618
                }
3178
3619
 
3179
3620
                /* skip leading spaces */
3217
3658
                                        }
3218
3659
                                        else {
3219
3660
                                                Alert("parsing [%s:%d] : invalid or incomplete '\\x' sequence in '%s'.\n", file, linenum, args[0]);
3220
 
                                                goto err;
 
3661
                                                err_code |= ERR_ALERT | ERR_FATAL;
3221
3662
                                        }
3222
3663
                                }
3223
3664
                                if (skip) {
3262
3703
 
3263
3704
                if (inv && strcmp(args[0], "option")) {
3264
3705
                        Alert("parsing [%s:%d]: negation currently supported only for options.\n", file, linenum);
3265
 
                        goto err;
 
3706
                        err_code |= ERR_ALERT | ERR_FATAL;
3266
3707
                }
3267
3708
 
3268
3709
                if (!strcmp(args[0], "listen") ||
3283
3724
 
3284
3725
                switch (confsect) {
3285
3726
                case CFG_LISTEN:
3286
 
                        if (cfg_parse_listen(file, linenum, args, inv) < 0)
3287
 
                                goto err;
 
3727
                        err_code |= cfg_parse_listen(file, linenum, args, inv);
3288
3728
                        break;
3289
3729
                case CFG_GLOBAL:
3290
 
                        if (cfg_parse_global(file, linenum, args, inv) < 0)
3291
 
                                goto err;
 
3730
                        err_code |= cfg_parse_global(file, linenum, args, inv);
3292
3731
                        break;
3293
3732
                default:
3294
3733
                        Alert("parsing [%s:%d] : unknown keyword '%s' out of section.\n", file, linenum, args[0]);
3295
 
                        goto err;
 
3734
                        err_code |= ERR_ALERT | ERR_FATAL;
3296
3735
                }
 
3736
 
 
3737
                if (err_code & ERR_ABORT)
 
3738
                        break;
3297
3739
        }
3298
3740
        free(cursection);
3299
3741
        cursection = NULL;
3300
3742
        fclose(f);
 
3743
        return err_code;
 
3744
}
 
3745
 
 
3746
/*
 
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
 
3753
 * indicators.
 
3754
 */
 
3755
int check_config_validity()
 
3756
{
 
3757
        int cfgerr = 0;
 
3758
        struct proxy *curproxy = NULL;
 
3759
        struct server *newsrv = NULL;
 
3760
        int err_code = 0;
3301
3761
 
3302
3762
        /*
3303
3763
         * Now, check for the integrity of all that we have collected.
3320
3780
        }
3321
3781
 
3322
3782
        if ((curproxy = proxy) == NULL) {
3323
 
                Alert("parsing %s : no <listen> line. Nothing to do !\n",
3324
 
                      file);
3325
 
                goto err;
 
3783
                Alert("config : no <listen> line. Nothing to do !\n");
 
3784
                err_code |= ERR_ALERT | ERR_FATAL;
 
3785
                goto out;
3326
3786
        }
3327
3787
 
3328
3788
        while (curproxy != NULL) {
3338
3798
 
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);
3345
3805
                                cfgerr++;
3346
3806
                        }
3347
3807
 
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);
3351
3811
                        break;
3352
3812
 
3353
3813
                case PR_MODE_TCP:
3354
 
                        cfgerr += proxy_cfg_ensure_no_http(curproxy, file);
 
3814
                        cfgerr += proxy_cfg_ensure_no_http(curproxy);
3355
3815
                        break;
3356
3816
 
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",
 
3820
                                      curproxy->id);
3361
3821
                                cfgerr++;
3362
3822
                        }
3363
3823
                        break;
3364
3824
                }
3365
3825
 
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);
3369
3829
                        cfgerr++;
3370
3830
                }
3371
3831
 
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);
3377
3837
                                        cfgerr++;
3378
3838
                                }
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);
3383
3843
                                        cfgerr++;
3384
3844
                                }
3385
3845
#endif
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;
3389
3850
                                }
3390
3851
                        }
3391
3852
                        else if (!(curproxy->options & (PR_O_TRANSP | PR_O_HTTP_PROXY)) &&
3401
3862
 
3402
3863
                if ((curproxy->options & PR_O_DISABLE404) && !(curproxy->options & PR_O_HTTP_CHK)) {
3403
3864
                        curproxy->options &= ~PR_O_DISABLE404;
3404
 
                        Warning("parsing %s : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
3405
 
                                file, "disable-on-404", proxy_type_str(curproxy), curproxy->id);
 
3865
                        Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
 
3866
                                "disable-on-404", proxy_type_str(curproxy), curproxy->id);
 
3867
                        err_code |= ERR_WARN;
3406
3868
                }
3407
3869
 
3408
3870
                /* if a default backend was specified, let's find it */
3417
3879
                        } else if (target == curproxy) {
3418
3880
                                Alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
3419
3881
                                        curproxy->id, curproxy->defbe.name);
 
3882
                                cfgerr++;
3420
3883
                        } else {
3421
3884
                                free(curproxy->defbe.name);
3422
3885
                                curproxy->defbe.be = target;
3488
3951
                    (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
3489
3952
                     ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
3490
3953
                      (!curproxy->timeout.connect || !curproxy->timeout.server)))) {
3491
 
                        Warning("parsing %s : missing timeouts for %s '%s'.\n"
 
3954
                        Warning("config : missing timeouts for %s '%s'.\n"
3492
3955
                                "   | While not properly invalid, you will certainly encounter various problems\n"
3493
3956
                                "   | with such a configuration. To fix this, please ensure that all following\n"
3494
3957
                                "   | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
3495
 
                                file, proxy_type_str(curproxy), curproxy->id);
 
3958
                                proxy_type_str(curproxy), curproxy->id);
 
3959
                        err_code |= ERR_WARN;
3496
3960
                }
3497
3961
 
3498
3962
                /* Historically, the tarpit and queue timeouts were inherited from contimeout.
3581
4045
                if (curproxy->options & PR_O_LOGASAP)
3582
4046
                        curproxy->to_log &= ~LW_BYTES;
3583
4047
 
 
4048
                if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
 
4049
                    (curproxy->cap & PR_CAP_FE) && curproxy->to_log && curproxy->logfac1 < 0) {
 
4050
                        Warning("config : log format ignored for %s '%s' since it has no log address.\n",
 
4051
                                proxy_type_str(curproxy), curproxy->id);
 
4052
                        err_code |= ERR_WARN;
 
4053
                }
 
4054
 
3584
4055
                /*
3585
4056
                 * ensure that we're not cross-dressing a TCP server into HTTP.
3586
4057
                 */
3587
4058
                newsrv = curproxy->srv;
3588
4059
                while (newsrv != NULL) {
3589
4060
                        if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
3590
 
                                Alert("parsing [%s:%d] : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
3591
 
                                      file, linenum, proxy_type_str(curproxy), curproxy->id);
3592
 
                                goto err;
 
4061
                                Alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
 
4062
                                      proxy_type_str(curproxy), curproxy->id);
 
4063
                                cfgerr++;
3593
4064
                        }
3594
4065
                        newsrv = newsrv->next;
3595
4066
                }
3611
4082
                                /* minconn was not specified, so we set it to maxconn */
3612
4083
                                newsrv->minconn = newsrv->maxconn;
3613
4084
                        } else if (newsrv->minconn != newsrv->maxconn && !curproxy->fullconn) {
3614
 
                                Alert("parsing [%s:%d] : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
3615
 
                                      file, linenum, proxy_type_str(curproxy), curproxy->id);
3616
 
                                goto err;
 
4085
                                Alert("config : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
 
4086
                                      proxy_type_str(curproxy), curproxy->id);
 
4087
                                cfgerr++;
3617
4088
                        }
3618
4089
 
3619
4090
                        if (newsrv->trackit) {
3634
4105
                                if (pname) {
3635
4106
                                        px = findproxy(pname, curproxy->mode, PR_CAP_BE);
3636
4107
                                        if (!px) {
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);
3640
 
                                                return -1;
 
4111
                                                cfgerr++;
 
4112
                                                goto next_srv;
3641
4113
                                        }
3642
4114
                                } else
3643
4115
                                        px = curproxy;
3644
4116
 
3645
4117
                                srv = findserver(px, sname);
3646
4118
                                if (!srv) {
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);
3650
 
                                        return -1;
 
4122
                                        cfgerr++;
 
4123
                                        goto next_srv;
3651
4124
                                }
3652
4125
 
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);
3658
 
                                        return -1;
 
4131
                                        cfgerr++;
 
4132
                                        goto next_srv;
3659
4133
                                }
3660
4134
 
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);
3667
 
                                        return -1;
 
4141
                                        cfgerr++;
 
4142
                                        goto next_srv;
3668
4143
                                }
3669
4144
 
3670
4145
                                newsrv->tracked = srv;
3673
4148
 
3674
4149
                                free(newsrv->trackit);
3675
4150
                        }
3676
 
 
 
4151
                next_srv:
3677
4152
                        newsrv = newsrv->next;
3678
4153
                }
3679
4154
 
3702
4177
                curproxy = curproxy->next;
3703
4178
        }
3704
4179
 
3705
 
        if (cfgerr > 0) {
3706
 
                Alert("Errors found in configuration file, aborting.\n");
3707
 
                goto err;
3708
 
        }
3709
 
 
3710
4180
        /*
3711
4181
         * Recount currently required checks.
3712
4182
         */
3723
4193
                                global.last_checks |= cfg_opts2[optnum].checks;
3724
4194
        }
3725
4195
 
3726
 
        free(cursection);
3727
 
        cursection = NULL;
3728
 
        return 0;
3729
 
 
3730
 
 err:
3731
 
        free(cursection);
3732
 
        cursection = NULL;
3733
 
        return -1;
 
4196
        if (cfgerr > 0)
 
4197
                err_code |= ERR_ALERT | ERR_FATAL;
 
4198
 out:
 
4199
        return err_code;
3734
4200
}
3735
4201
 
3736
4202
/*