~clint-fewbar/ubuntu/precise/squid3/ignore-sighup-early

« back to all changes in this revision

Viewing changes to src/cache_cf.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2010-05-04 11:15:49 UTC
  • mfrom: (1.3.1 upstream)
  • mto: (20.3.1 squeeze) (21.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20100504111549-1apjh2g5sndki4te
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
1
/*
3
 
 * $Id: cache_cf.cc,v 1.528.2.8 2008/03/04 12:10:00 amosjeffries Exp $
 
2
 * $Id$
4
3
 *
5
4
 * DEBUG: section 3     Configuration File Parsing
6
5
 * AUTHOR: Harvest Derived
21
20
 *  it under the terms of the GNU General Public License as published by
22
21
 *  the Free Software Foundation; either version 2 of the License, or
23
22
 *  (at your option) any later version.
24
 
 *  
 
23
 *
25
24
 *  This program is distributed in the hope that it will be useful,
26
25
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
27
26
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
27
 *  GNU General Public License for more details.
29
 
 *  
 
28
 *
30
29
 *  You should have received a copy of the GNU General Public License
31
30
 *  along with this program; if not, write to the Free Software
32
31
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
34
33
 */
35
34
 
36
35
#include "squid.h"
37
 
#include "authenticate.h"
38
 
#include "AuthConfig.h"
39
 
#include "AuthScheme.h"
 
36
#include "ProtoPort.h"
 
37
#include "HttpRequestMethod.h"
 
38
#include "auth/Config.h"
 
39
#include "auth/Scheme.h"
40
40
#include "CacheManager.h"
41
41
#include "Store.h"
42
42
#include "SwapDir.h"
43
43
#include "ConfigParser.h"
44
 
#include "ACL.h"
 
44
#include "acl/Acl.h"
 
45
#include "acl/MethodData.h"
 
46
#include "acl/Gadgets.h"
45
47
#include "StoreFileSystem.h"
46
48
#include "Parsing.h"
 
49
#include "rfc1738.h"
47
50
#include "MemBuf.h"
48
51
#include "wordlist.h"
 
52
#include "ident/Config.h"
 
53
#include "ip/IpIntercept.h"
 
54
 
49
55
#if HAVE_GLOB_H
50
56
#include <glob.h>
51
57
#endif
54
60
#include "snmp.h"
55
61
#endif
56
62
#if USE_SQUID_ESI
57
 
#include "ESIParser.h"
 
63
#include "esi/Parser.h"
 
64
#endif
 
65
 
 
66
#if USE_ADAPTATION
 
67
#include "adaptation/Config.h"
 
68
 
 
69
static void parse_adaptation_service_set_type();
 
70
static void parse_adaptation_service_chain_type();
 
71
static void parse_adaptation_access_type();
 
72
 
58
73
#endif
59
74
 
60
75
#if ICAP_CLIENT
61
 
#include "ICAP/ICAPConfig.h"
62
 
 
63
 
static void parse_icap_service_type(ICAPConfig *);
64
 
static void dump_icap_service_type(StoreEntry *, const char *, const ICAPConfig &);
65
 
static void free_icap_service_type(ICAPConfig *);
66
 
static void parse_icap_class_type(ICAPConfig *);
67
 
static void dump_icap_class_type(StoreEntry *, const char *, const ICAPConfig &);
68
 
static void free_icap_class_type(ICAPConfig *);
69
 
static void parse_icap_access_type(ICAPConfig *);
70
 
static void dump_icap_access_type(StoreEntry *, const char *, const ICAPConfig &);
71
 
static void free_icap_access_type(ICAPConfig *);
72
 
 
 
76
#include "adaptation/icap/Config.h"
 
77
 
 
78
static void parse_icap_service_type(Adaptation::Icap::Config *);
 
79
static void dump_icap_service_type(StoreEntry *, const char *, const Adaptation::Icap::Config &);
 
80
static void free_icap_service_type(Adaptation::Icap::Config *);
 
81
static void parse_icap_class_type();
 
82
static void parse_icap_access_type();
 
83
 
 
84
#endif
 
85
 
 
86
#if USE_ECAP
 
87
#include "adaptation/ecap/Config.h"
 
88
static void parse_ecap_service_type(Adaptation::Ecap::Config *);
 
89
static void dump_ecap_service_type(StoreEntry *, const char *, const Adaptation::Ecap::Config &);
 
90
static void free_ecap_service_type(Adaptation::Ecap::Config *);
73
91
#endif
74
92
 
75
93
CBDATA_TYPE(peer);
93
111
 
94
112
static void parse_logformat(logformat ** logformat_definitions);
95
113
static void parse_access_log(customlog ** customlog_definitions);
96
 
#if UNUSED_CODE
97
114
static int check_null_access_log(customlog *customlog_definitions);
98
 
#endif
99
115
 
100
116
static void dump_logformat(StoreEntry * entry, const char *name, logformat * definitions);
101
117
static void dump_access_log(StoreEntry * entry, const char *name, customlog * definitions);
130
146
static void free_denyinfo(acl_deny_info_list ** var);
131
147
 
132
148
#if USE_WCCPv2
133
 
static void parse_sockaddr_in_list(sockaddr_in_list **);
134
 
static void dump_sockaddr_in_list(StoreEntry *, const char *, const sockaddr_in_list *);
135
 
static void free_sockaddr_in_list(sockaddr_in_list **);
 
149
static void parse_IpAddress_list(IpAddress_list **);
 
150
static void dump_IpAddress_list(StoreEntry *, const char *, const IpAddress_list *);
 
151
static void free_IpAddress_list(IpAddress_list **);
136
152
#if CURRENTLY_UNUSED
137
 
static int check_null_sockaddr_in_list(const sockaddr_in_list *);
 
153
static int check_null_IpAddress_list(const IpAddress_list *);
138
154
#endif /* CURRENTLY_UNUSED */
139
155
#endif /* USE_WCCPv2 */
140
156
 
219
235
    int i;
220
236
    memset(&globbuf, 0, sizeof(globbuf));
221
237
    for (path = strwordtok(files, &saveptr); path; path = strwordtok(NULL, &saveptr)) {
222
 
        if (glob(path, globbuf.gl_pathc ? GLOB_APPEND : 0, NULL, &globbuf) != 0) {
223
 
            fatalf("Unable to find configuration file: %s: %s",
224
 
                path, xstrerror());
225
 
        }
226
 
     }
 
238
        if (glob(path, globbuf.gl_pathc ? GLOB_APPEND : 0, NULL, &globbuf) != 0) {
 
239
            fatalf("Unable to find configuration file: %s: %s",
 
240
                   path, xstrerror());
 
241
        }
 
242
    }
227
243
    for (i = 0; i < (int)globbuf.gl_pathc; i++) {
228
 
        error_count += parseOneConfigFile(globbuf.gl_pathv[i], depth);
 
244
        error_count += parseOneConfigFile(globbuf.gl_pathv[i], depth);
229
245
    }
230
246
    globfree(&globbuf);
231
247
#else
232
248
    char* file = strwordtok(files, &saveptr);
233
249
    while (file != NULL) {
234
 
        error_count += parseOneConfigFile(file, depth);
235
 
        file = strwordtok(NULL, &saveptr);
 
250
        error_count += parseOneConfigFile(file, depth);
 
251
        file = strwordtok(NULL, &saveptr);
236
252
    }
237
253
#endif /* HAVE_GLOB */
238
254
    return error_count;
339
355
 
340
356
        debugs(3, 5, "Processing: '" << tmp_line << "'");
341
357
 
342
 
        /* Handle includes here */
 
358
        /* Handle includes here */
343
359
        if (tmp_line_len >= 9 && strncmp(tmp_line, "include", 7) == 0 && xisspace(tmp_line[7])) {
344
360
            err_count += parseManyConfigFiles(tmp_line + 8, depth + 1);
345
 
        } else if (!parse_line(tmp_line)) {
 
361
        } else if (!parse_line(tmp_line)) {
346
362
            debugs(3, 0, HERE << cfg_filename << ":" << config_lineno << " unrecognized: '" << tmp_line << "'");
347
 
            err_count++;
348
 
        }
 
363
            err_count++;
 
364
        }
349
365
 
350
366
        safe_free(tmp_line);
351
367
        tmp_line_len = 0;
368
384
}
369
385
 
370
386
int
371
 
parseConfigFile(const char *file_name, CacheManager & manager)
 
387
parseConfigFile(const char *file_name)
372
388
{
373
389
    int err_count = 0;
 
390
    CacheManager *manager=CacheManager::GetInstance();
374
391
 
375
392
    configFreeMemory();
376
393
 
 
394
    ACLMethodData::ThePurgeCount = 0;
377
395
    default_all();
378
396
 
379
397
    err_count = parseOneConfigFile(file_name, 0);
390
408
    if (!Config.chroot_dir) {
391
409
        leave_suid();
392
410
        setUmask(Config.umask);
393
 
        _db_init(Config.Log.log, Config.debugOptions);
 
411
        _db_init(Debug::cache_log, Debug::debugOptions);
394
412
        enter_suid();
395
413
    }
396
414
 
397
415
    if (opt_send_signal == -1) {
398
 
        manager.registerAction("config",
399
 
                               "Current Squid Configuration",
400
 
                               dump_config,
401
 
                               1, 1);
 
416
        manager->registerAction("config",
 
417
                                "Current Squid Configuration",
 
418
                                dump_config,
 
419
                                1, 1);
402
420
    }
403
421
 
404
422
    return err_count;
413
431
    memConfigure();
414
432
    /* Sanity checks */
415
433
 
416
 
    if (Config.cacheSwap.swapDirs == NULL)
417
 
        fatal("No cache_dir's specified in config file");
 
434
    if (Config.cacheSwap.swapDirs == NULL) {
 
435
        /* Memory-only cache probably in effect. */
 
436
        /* turn off the cache rebuild delays... */
 
437
        StoreController::store_dirs_rebuilding = 0;
 
438
    }
 
439
 
 
440
    if (Debug::rotateNumber < 0) {
 
441
        Debug::rotateNumber = Config.Log.rotateNumber;
 
442
    }
418
443
 
419
444
#if SIZEOF_OFF_T <= 4
420
445
    if (Config.Store.maxObjectSize > 0x7FFF0000) {
421
 
        debugs(3, 0, "WARNING: This Squid binary can not handle files larger than 2GB. Limiting maximum_object_size to just below 2GB");
422
 
        Config.Store.maxObjectSize = 0x7FFF0000;
 
446
        debugs(3, 0, "WARNING: This Squid binary can not handle files larger than 2GB. Limiting maximum_object_size to just below 2GB");
 
447
        Config.Store.maxObjectSize = 0x7FFF0000;
423
448
    }
424
449
#endif
425
450
    if (0 == Store::Root().maxSize())
439
464
    if (Config.onoff.httpd_suppress_version_string)
440
465
        visible_appname_string = (char *)appname_string;
441
466
    else
442
 
        visible_appname_string = (char *)full_appname_string;
 
467
        visible_appname_string = (char const *)APP_FULLNAME;
443
468
 
444
469
#if USE_DNSSERVERS
445
470
 
484
509
    else
485
510
        Config.appendDomainLen = 0;
486
511
 
487
 
    safe_free(debug_options)
488
 
    debug_options = xstrdup(Config.debugOptions);
489
 
 
490
512
    if (Config.retry.maxtries > 10)
491
513
        fatal("maximum_single_addr_tries cannot be larger than 10");
492
514
 
510
532
 
511
533
    requirePathnameExists("Icon Directory", Config.icons.directory);
512
534
 
513
 
    requirePathnameExists("Error Directory", Config.errorDirectory);
 
535
    if (Config.errorDirectory)
 
536
        requirePathnameExists("Error Directory", Config.errorDirectory);
514
537
 
515
538
#if HTTP_VIOLATIONS
516
539
 
517
540
    {
518
541
        const refresh_t *R;
519
542
 
520
 
        for (R = Config.Refresh; R; R = R->next)
521
 
        {
 
543
        for (R = Config.Refresh; R; R = R->next) {
522
544
            if (!R->flags.override_expire)
523
545
                continue;
524
546
 
527
549
            break;
528
550
        }
529
551
 
530
 
        for (R = Config.Refresh; R; R = R->next)
531
 
        {
 
552
        for (R = Config.Refresh; R; R = R->next) {
532
553
            if (!R->flags.override_lastmod)
533
554
                continue;
534
555
 
537
558
            break;
538
559
        }
539
560
 
540
 
        for (R = Config.Refresh; R; R = R->next)
541
 
        {
 
561
        for (R = Config.Refresh; R; R = R->next) {
542
562
            if (!R->flags.reload_into_ims)
543
563
                continue;
544
564
 
547
567
            break;
548
568
        }
549
569
 
550
 
        for (R = Config.Refresh; R; R = R->next)
551
 
        {
 
570
        for (R = Config.Refresh; R; R = R->next) {
552
571
            if (!R->flags.ignore_reload)
553
572
                continue;
554
573
 
557
576
            break;
558
577
        }
559
578
 
560
 
        for (R = Config.Refresh; R; R = R->next)
561
 
        {
 
579
        for (R = Config.Refresh; R; R = R->next) {
562
580
            if (!R->flags.ignore_no_cache)
563
581
                continue;
564
582
 
567
585
            break;
568
586
        }
569
587
 
570
 
        for (R = Config.Refresh; R; R = R->next)
571
 
        {
 
588
        for (R = Config.Refresh; R; R = R->next) {
572
589
            if (!R->flags.ignore_no_store)
573
590
                continue;
574
591
 
577
594
            break;
578
595
        }
579
596
 
580
 
        for (R = Config.Refresh; R; R = R->next)
581
 
        {
 
597
        for (R = Config.Refresh; R; R = R->next) {
 
598
            if (!R->flags.ignore_must_revalidate)
 
599
                continue;
 
600
            debugs(22, 1, "WARNING: use of 'ignore-must-revalidate' in 'refresh_pattern' violates HTTP");
 
601
            break;
 
602
        }
 
603
 
 
604
        for (R = Config.Refresh; R; R = R->next) {
582
605
            if (!R->flags.ignore_private)
583
606
                continue;
584
607
 
587
610
            break;
588
611
        }
589
612
 
590
 
        for (R = Config.Refresh; R; R = R->next)
591
 
        {
 
613
        for (R = Config.Refresh; R; R = R->next) {
592
614
            if (!R->flags.ignore_auth)
593
615
                continue;
594
616
 
608
630
 
609
631
#endif
610
632
 
611
 
    if (aclPurgeMethodInUse(Config.accessList.http))
612
 
        Config2.onoff.enable_purge = 1;
 
633
    // we enable runtime PURGE checks if there is at least one PURGE method ACL
 
634
    // TODO: replace with a dedicated "purge" ACL option?
 
635
    Config2.onoff.enable_purge = (ACLMethodData::ThePurgeCount > 0);
613
636
 
614
637
    Config2.onoff.mangle_request_headers = httpReqHdrManglersConfigured();
615
638
 
688
711
 
689
712
    {
690
713
 
 
714
        http_port_list *s;
 
715
 
 
716
        for (s = Config.Sockaddr.http; s != NULL; s = (http_port_list *) s->next) {
 
717
            if (!s->cert && !s->key)
 
718
                continue;
 
719
 
 
720
            debugs(3, 1, "Initializing http_port " << s->http.s << " SSL context");
 
721
 
 
722
            s->sslContext = sslCreateServerContext(s->cert, s->key, s->version, s->cipher, s->options, s->sslflags, s->clientca, s->cafile, s->capath, s->crlfile, s->dhfile, s->sslcontext);
 
723
        }
 
724
    }
 
725
 
 
726
    {
 
727
 
691
728
        https_port_list *s;
692
729
 
693
730
        for (s = Config.Sockaddr.https; s != NULL; s = (https_port_list *) s->http.next) {
694
 
            debugs(3, 1, "Initializing https_port " <<
695
 
                   inet_ntoa(s->http.s.sin_addr) << ":" <<
696
 
                   ntohs(s->http.s.sin_port) << " SSL context");
 
731
            debugs(3, 1, "Initializing https_port " << s->http.s << " SSL context");
697
732
 
698
733
            s->sslContext = sslCreateServerContext(s->cert, s->key, s->version, s->cipher, s->options, s->sslflags, s->clientca, s->cafile, s->capath, s->crlfile, s->dhfile, s->sslcontext);
699
734
        }
725
760
    if (0 == d)
726
761
        (void) 0;
727
762
    else if ((token = strtok(NULL, w_space)) == NULL)
728
 
        debugs(3, 0, "WARNING: No units on '" << 
729
 
                     config_input_line << "', assuming " << 
730
 
                     d << " " << units  );
 
763
        debugs(3, 0, "WARNING: No units on '" <<
 
764
               config_input_line << "', assuming " <<
 
765
               d << " " << units  );
731
766
    else if ((m = parseTimeUnits(token)) == 0)
732
767
        self_destruct();
733
768
 
799
834
    if (0.0 == d)
800
835
        (void) 0;
801
836
    else if ((token = strtok(NULL, w_space)) == NULL)
802
 
        debugs(3, 0, "WARNING: No units on '" << 
803
 
                     config_input_line << "', assuming " <<
804
 
                     d << " " <<  units  );
 
837
        debugs(3, 0, "WARNING: No units on '" <<
 
838
               config_input_line << "', assuming " <<
 
839
               d << " " <<  units  );
805
840
    else if ((m = parseBytesUnits(token)) == 0) {
806
841
        self_destruct();
807
842
        return;
844
879
    if (0.0 == d)
845
880
        (void) 0;
846
881
    else if ((token = strtok(NULL, w_space)) == NULL)
847
 
        debugs(3, 0, "WARNING: No units on '" << 
848
 
                     config_input_line << "', assuming " <<
849
 
                     d << " " <<  units  );
 
882
        debugs(3, 0, "WARNING: No units on '" <<
 
883
               config_input_line << "', assuming " <<
 
884
               d << " " <<  units  );
850
885
    else if ((m = parseBytesUnits(token)) == 0) {
851
886
        self_destruct();
852
887
        return;
959
994
}
960
995
 
961
996
static void
962
 
 
963
 
dump_address(StoreEntry * entry, const char *name, struct IN_ADDR addr)
 
997
dump_address(StoreEntry * entry, const char *name, IpAddress &addr)
964
998
{
965
 
    storeAppendPrintf(entry, "%s %s\n", name, inet_ntoa(addr));
 
999
    char buf[MAX_IPSTRLEN];
 
1000
    storeAppendPrintf(entry, "%s %s\n", name, addr.NtoA(buf,MAX_IPSTRLEN) );
966
1001
}
967
1002
 
968
1003
static void
969
 
 
970
 
parse_address(struct IN_ADDR *addr)
 
1004
parse_address(IpAddress *addr)
971
1005
{
972
 
 
973
 
    const struct hostent *hp;
974
1006
    char *token = strtok(NULL, w_space);
975
1007
 
976
1008
    if (!token) {
978
1010
        return;
979
1011
    }
980
1012
 
981
 
    if (safe_inet_addr(token, addr) == 1)
982
 
        (void) 0;
983
 
    else if ((hp = gethostbyname(token)))       /* dont use ipcache */
984
 
        *addr = inaddrFromHostent(hp);
985
 
    else
986
 
        self_destruct();
 
1013
    if (!strcmp(token,"any_addr")) {
 
1014
        addr->SetAnyAddr();
 
1015
        (void) 0;
 
1016
    } else if ( (!strcmp(token,"no_addr")) || (!strcmp(token,"full_mask")) ) {
 
1017
        addr->SetNoAddr();
 
1018
        (void) 0;
 
1019
    } else
 
1020
        *addr = token;
987
1021
}
988
1022
 
989
1023
static void
990
 
 
991
 
free_address(struct IN_ADDR *addr)
 
1024
free_address(IpAddress *addr)
992
1025
{
993
 
 
994
 
    memset(addr, '\0', sizeof(struct IN_ADDR));
 
1026
    addr->SetEmpty();
995
1027
}
996
1028
 
997
1029
CBDATA_TYPE(acl_address);
999
1031
static void
1000
1032
dump_acl_address(StoreEntry * entry, const char *name, acl_address * head)
1001
1033
{
 
1034
    char buf[MAX_IPSTRLEN];
1002
1035
    acl_address *l;
1003
1036
 
1004
1037
    for (l = head; l; l = l->next) {
1005
 
        if (l->addr.s_addr != INADDR_ANY)
1006
 
            storeAppendPrintf(entry, "%s %s", name, inet_ntoa(l->addr));
 
1038
        if (!l->addr.IsAnyAddr())
 
1039
            storeAppendPrintf(entry, "%s %s", name, l->addr.NtoA(buf,MAX_IPSTRLEN));
1007
1040
        else
1008
1041
            storeAppendPrintf(entry, "%s autoselect", name);
1009
1042
 
1366
1399
#endif
1367
1400
 
1368
1401
static void
1369
 
dump_cachedir(StoreEntry * entry, const char *name, _SquidConfig::_cacheSwap swap)
 
1402
dump_cachedir(StoreEntry * entry, const char *name, SquidConfig::_cacheSwap swap)
1370
1403
{
1371
1404
    SwapDir *s;
1372
1405
    int i;
1374
1407
 
1375
1408
    for (i = 0; i < swap.n_configured; i++) {
1376
1409
        s = dynamic_cast<SwapDir *>(swap.swapDirs[i].getRaw());
1377
 
        if(!s) continue;
 
1410
        if (!s) continue;
1378
1411
        storeAppendPrintf(entry, "%s %s %s", name, s->type(), s->path);
1379
1412
        s->dump(*entry);
1380
1413
        storeAppendPrintf(entry, "\n");
1382
1415
}
1383
1416
 
1384
1417
static int
1385
 
check_null_cachedir(_SquidConfig::_cacheSwap swap)
1386
 
{
1387
 
    return swap.swapDirs == NULL;
1388
 
}
1389
 
 
1390
 
static int
1391
1418
check_null_string(char *s)
1392
1419
{
1393
1420
    return s == NULL;
1459
1486
}
1460
1487
 
1461
1488
static void
1462
 
parse_cachedir(_SquidConfig::_cacheSwap * swap)
 
1489
parse_cachedir(SquidConfig::_cacheSwap * swap)
1463
1490
{
1464
1491
    char *type_str;
1465
1492
    char *path_str;
1485
1512
 
1486
1513
        if ((strcasecmp(path_str, dynamic_cast<SwapDir *>(swap->swapDirs[i].getRaw())->path)) == 0) {
1487
1514
            /* this is specific to on-fs Stores. The right
1488
 
             * way to handle this is probably to have a mapping 
 
1515
             * way to handle this is probably to have a mapping
1489
1516
             * from paths to stores, and have on-fs stores
1490
1517
             * register with that, and lookip in that in their
1491
1518
             * own setup logic. RBC 20041225. TODO.
1508
1535
    }
1509
1536
 
1510
1537
    /* new cache_dir */
1511
 
    if(swap->n_configured > 63) {
 
1538
    if (swap->n_configured > 63) {
1512
1539
        /* 7 bits, signed */
1513
1540
        debugs(3, DBG_CRITICAL, "WARNING: There is a fixed maximum of 63 cache_dir entries Squid can handle.");
1514
1541
        debugs(3, DBG_CRITICAL, "WARNING: '" << path_str << "' is one to many.");
1566
1593
    LOCAL_ARRAY(char, xname, 128);
1567
1594
 
1568
1595
    while (p != NULL) {
1569
 
        storeAppendPrintf(entry, "%s %s %s %d %d",
 
1596
        storeAppendPrintf(entry, "%s %s %s %d %d name=%s",
1570
1597
                          name,
1571
1598
                          p->host,
1572
1599
                          neighborTypeStr(p),
1573
1600
                          p->http_port,
1574
 
                          p->icp.port);
 
1601
                          p->icp.port,
 
1602
                          p->name);
1575
1603
        dump_peer_options(entry, p);
1576
1604
 
1577
1605
        for (d = p->peer_domain; d; d = d->next) {
1624
1652
    /** Parses a port number or service name from the squid.conf */
1625
1653
    char *token = strtok(NULL, w_space);
1626
1654
    if (token == NULL) {
1627
 
       self_destruct();
1628
 
       return 0; /* NEVER REACHED */
 
1655
        self_destruct();
 
1656
        return 0; /* NEVER REACHED */
1629
1657
    }
1630
1658
    /** Returns either the service port number from /etc/services */
1631
 
    if( !isUnsignedNumeric(token, strlen(token)) )
 
1659
    if ( !isUnsignedNumeric(token, strlen(token)) )
1632
1660
        port = getservbyname(token, proto);
1633
1661
    if (port != NULL) {
1634
1662
        return ntohs((u_short)port->s_port);
1693
1721
        self_destruct();
1694
1722
 
1695
1723
    p->icp.port = GetUdpService();
 
1724
    p->connection_auth = 2;    /* auto */
1696
1725
 
1697
1726
    while ((token = strtok(NULL, w_space))) {
1698
1727
        if (!strcasecmp(token, "proxy-only")) {
1703
1732
            p->options.background_ping = 1;
1704
1733
        } else if (!strcasecmp(token, "no-digest")) {
1705
1734
            p->options.no_digest = 1;
 
1735
        } else if (!strcasecmp(token, "no-tproxy")) {
 
1736
            p->options.no_tproxy = 1;
1706
1737
        } else if (!strcasecmp(token, "multicast-responder")) {
1707
1738
            p->options.mcast_responder = 1;
 
1739
#if PEER_MULTICAST_SIBLINGS
 
1740
        } else if (!strcasecmp(token, "multicast-siblings")) {
 
1741
            p->options.mcast_siblings = 1;
 
1742
#endif
1708
1743
        } else if (!strncasecmp(token, "weight=", 7)) {
1709
1744
            p->weight = xatoi(token + 7);
1710
1745
        } else if (!strncasecmp(token, "basetime=", 9)) {
1732
1767
        } else if (!strcasecmp(token, "htcp-oldsquid")) {
1733
1768
            p->options.htcp = 1;
1734
1769
            p->options.htcp_oldsquid = 1;
 
1770
        } else if (!strcasecmp(token, "htcp-no-clr")) {
 
1771
            if (p->options.htcp_only_clr)
 
1772
                fatalf("parse_peer: can't set htcp-no-clr and htcp-only-clr simultaneously");
 
1773
            p->options.htcp = 1;
 
1774
            p->options.htcp_no_clr = 1;
 
1775
        } else if (!strcasecmp(token, "htcp-no-purge-clr")) {
 
1776
            p->options.htcp = 1;
 
1777
            p->options.htcp_no_purge_clr = 1;
 
1778
        } else if (!strcasecmp(token, "htcp-only-clr")) {
 
1779
            if (p->options.htcp_no_clr)
 
1780
                fatalf("parse_peer: can't set htcp-no-clr and htcp-only-clr simultaneously");
 
1781
            p->options.htcp = 1;
 
1782
            p->options.htcp_only_clr = 1;
 
1783
        } else if (!strcasecmp(token, "htcp-forward-clr")) {
 
1784
            p->options.htcp = 1;
 
1785
            p->options.htcp_forward_clr = 1;
1735
1786
#endif
1736
1787
 
1737
1788
        } else if (!strcasecmp(token, "no-netdb-exchange")) {
1738
1789
            p->options.no_netdb_exchange = 1;
1739
 
#if USE_CARP
1740
1790
 
1741
1791
        } else if (!strcasecmp(token, "carp")) {
1742
1792
            if (p->type != PEER_PARENT)
1744
1794
 
1745
1795
            p->options.carp = 1;
1746
1796
 
1747
 
#endif
1748
1797
        } else if (!strcasecmp(token, "userhash")) {
1749
1798
            if (p->type != PEER_PARENT)
1750
1799
                fatalf("parse_peer: non-parent userhash peer %s/%d\n", p->host, p->http_port);
1768
1817
            rfc1738_unescape(p->login);
1769
1818
        } else if (!strncasecmp(token, "connect-timeout=", 16)) {
1770
1819
            p->connect_timeout = xatoi(token + 16);
 
1820
        } else if (!strncasecmp(token, "connect-fail-limit=", 19)) {
 
1821
            p->connect_fail_limit = xatoi(token + 19);
1771
1822
#if USE_CACHE_DIGESTS
1772
 
 
1773
1823
        } else if (!strncasecmp(token, "digest-url=", 11)) {
1774
1824
            p->digest_url = xstrdup(token + 11);
1775
1825
#endif
1832
1882
            p->front_end_https = 1;
1833
1883
        } else if (strcmp(token, "front-end-https=auto") == 0) {
1834
1884
            p->front_end_https = 2;
 
1885
        } else if (strcmp(token, "connection-auth=off") == 0) {
 
1886
            p->connection_auth = 0;
 
1887
        } else if (strcmp(token, "connection-auth") == 0) {
 
1888
            p->connection_auth = 1;
 
1889
        } else if (strcmp(token, "connection-auth=on") == 0) {
 
1890
            p->connection_auth = 1;
 
1891
        } else if (strcmp(token, "connection-auth=auto") == 0) {
 
1892
            p->connection_auth = 2;
1835
1893
        } else {
1836
1894
            debugs(3, 0, "parse_peer: token='" << token << "'");
1837
1895
            self_destruct();
1844
1902
    if (p->weight < 1)
1845
1903
        p->weight = 1;
1846
1904
 
 
1905
    if (p->connect_fail_limit < 1)
 
1906
        p->connect_fail_limit = 10;
 
1907
 
1847
1908
    p->icp.version = ICP_VERSION_CURRENT;
1848
1909
 
1849
1910
    p->test_fd = -1;
1859
1920
    }
1860
1921
 
1861
1922
#endif
 
1923
 
 
1924
    p->index =  ++Config.npeers;
 
1925
 
1862
1926
    while (*head != NULL)
1863
1927
        head = &(*head)->next;
1864
1928
 
1865
1929
    *head = p;
1866
1930
 
1867
 
    Config.npeers++;
1868
1931
    peerClearRRStart();
1869
1932
}
1870
1933
 
2049
2112
 
2050
2113
        l->domain = xstrdup(domain);
2051
2114
 
2052
 
        for (L = &(p->peer_domain); *L; L = &((*L)->next))
2053
 
 
2054
 
            ;
 
2115
        for (L = &(p->peer_domain); *L; L = &((*L)->next));
2055
2116
        *L = l;
2056
2117
    }
2057
2118
}
2083
2144
        l->type = parseNeighborType(type);
2084
2145
        l->domain = xstrdup(domain);
2085
2146
 
2086
 
        for (L = &(p->typelist); *L; L = &((*L)->next))
2087
 
 
2088
 
            ;
 
2147
        for (L = &(p->typelist); *L; L = &((*L)->next));
2089
2148
        *L = l;
2090
2149
    }
2091
2150
}
2200
2259
        if (head->flags.ignore_no_store)
2201
2260
            storeAppendPrintf(entry, " ignore-no-store");
2202
2261
 
 
2262
        if (head->flags.ignore_must_revalidate)
 
2263
            storeAppendPrintf(entry, " ignore-must-revalidate");
 
2264
 
2203
2265
        if (head->flags.ignore_private)
2204
2266
            storeAppendPrintf(entry, " ignore-private");
2205
2267
 
2231
2293
    int ignore_reload = 0;
2232
2294
    int ignore_no_cache = 0;
2233
2295
    int ignore_no_store = 0;
 
2296
    int ignore_must_revalidate = 0;
2234
2297
    int ignore_private = 0;
2235
2298
    int ignore_auth = 0;
2236
2299
#endif
2287
2350
            ignore_no_cache = 1;
2288
2351
        else if (!strcmp(token, "ignore-no-store"))
2289
2352
            ignore_no_store = 1;
 
2353
        else if (!strcmp(token, "ignore-must-revalidate"))
 
2354
            ignore_must_revalidate = 1;
2290
2355
        else if (!strcmp(token, "ignore-private"))
2291
2356
            ignore_private = 1;
2292
2357
        else if (!strcmp(token, "ignore-auth"))
2302
2367
#endif
2303
2368
 
2304
2369
        } else
2305
 
             debugs(22, 0, "redreshAddToList: Unknown option '" << pattern << "': " << token);
 
2370
            debugs(22, 0, "redreshAddToList: Unknown option '" << pattern << "': " << token);
2306
2371
    }
2307
2372
 
2308
2373
    if ((errcode = regcomp(&comp, pattern, flags)) != 0) {
2348
2413
    if (ignore_no_store)
2349
2414
        t->flags.ignore_no_store = 1;
2350
2415
 
 
2416
    if (ignore_must_revalidate)
 
2417
        t->flags.ignore_must_revalidate = 1;
 
2418
 
2351
2419
    if (ignore_private)
2352
2420
        t->flags.ignore_private = 1;
2353
2421
 
2615
2683
        wordlistAdd(list, token);
2616
2684
}
2617
2685
 
 
2686
#if 0 /* now unused */
2618
2687
static int
2619
2688
check_null_wordlist(wordlist * w)
2620
2689
{
2621
2690
    return w == NULL;
2622
2691
}
 
2692
#endif
2623
2693
 
2624
2694
static int
2625
2695
check_null_acl_access(acl_access * a)
2742
2812
 
2743
2813
#if USE_WCCPv2
2744
2814
void
2745
 
parse_sockaddr_in_list_token(sockaddr_in_list ** head, char *token)
 
2815
parse_IpAddress_list_token(IpAddress_list ** head, char *token)
2746
2816
{
2747
2817
    char *t;
2748
2818
    char *host;
2749
2819
    char *tmp;
2750
2820
 
2751
 
    const struct hostent *hp;
 
2821
    IpAddress ipa;
2752
2822
    unsigned short port;
2753
 
    sockaddr_in_list *s;
 
2823
    IpAddress_list *s;
2754
2824
 
2755
2825
    host = NULL;
2756
2826
    port = 0;
2757
2827
 
2758
 
    if ((t = strchr(token, ':'))) {
2759
 
        /* host:port */
2760
 
        host = token;
2761
 
        *t = '\0';
 
2828
#if USE_IPV6
 
2829
    if (*token == '[') {
 
2830
        /* [host]:port */
 
2831
        host = token + 1;
 
2832
        t = strchr(host, ']');
 
2833
        if (!t)
 
2834
            self_destruct();
 
2835
        *t++ = '\0';
 
2836
        if (*t != ':')
 
2837
            self_destruct();
2762
2838
        port = xatos(t + 1);
2763
 
 
2764
 
        if (0 == port)
2765
 
            self_destruct();
2766
 
    } else if ((port = strtol(token, &tmp, 10)), !*tmp) {
2767
 
        /* port */
2768
 
    } else {
2769
 
        host = token;
2770
 
        port = 0;
2771
 
    }
2772
 
 
2773
 
    s = static_cast<sockaddr_in_list *>(xcalloc(1, sizeof(*s)));
2774
 
    s->s.sin_port = htons(port);
 
2839
    } else
 
2840
#endif
 
2841
        if ((t = strchr(token, ':'))) {
 
2842
            /* host:port */
 
2843
            host = token;
 
2844
            *t = '\0';
 
2845
            port = xatos(t + 1);
 
2846
 
 
2847
            if (0 == port)
 
2848
                self_destruct();
 
2849
        } else if ((port = strtol(token, &tmp, 10)), !*tmp) {
 
2850
            /* port */
 
2851
        } else {
 
2852
            host = token;
 
2853
            port = 0;
 
2854
        }
2775
2855
 
2776
2856
    if (NULL == host)
2777
 
        s->s.sin_addr = any_addr;
2778
 
    else if (1 == safe_inet_addr(host, &s->s.sin_addr))
 
2857
        ipa.SetAnyAddr();
 
2858
    else if ( ipa.GetHostByName(host) ) /* dont use ipcache. Accept either FQDN or IPA. */
2779
2859
        (void) 0;
2780
 
    else if ((hp = gethostbyname(host)))        /* dont use ipcache */
2781
 
        s->s.sin_addr = inaddrFromHostent(hp);
2782
2860
    else
2783
2861
        self_destruct();
2784
2862
 
 
2863
    /* port MUST be set after the IPA lookup/conversion is perofrmed. */
 
2864
    ipa.SetPort(port);
 
2865
 
2785
2866
    while (*head)
2786
2867
        head = &(*head)->next;
2787
2868
 
 
2869
    s = static_cast<IpAddress_list *>(xcalloc(1, sizeof(*s)));
 
2870
    s->s = ipa;
 
2871
 
2788
2872
    *head = s;
2789
2873
}
2790
2874
 
2791
2875
static void
2792
 
parse_sockaddr_in_list(sockaddr_in_list ** head)
 
2876
parse_IpAddress_list(IpAddress_list ** head)
2793
2877
{
2794
2878
    char *token;
2795
2879
 
2796
2880
    while ((token = strtok(NULL, w_space))) {
2797
 
        parse_sockaddr_in_list_token(head, token);
 
2881
        parse_IpAddress_list_token(head, token);
2798
2882
    }
2799
2883
}
2800
2884
 
2801
2885
static void
2802
 
dump_sockaddr_in_list(StoreEntry * e, const char *n, const sockaddr_in_list * s)
 
2886
dump_IpAddress_list(StoreEntry * e, const char *n, const IpAddress_list * s)
2803
2887
{
 
2888
    char ntoabuf[MAX_IPSTRLEN];
 
2889
 
2804
2890
    while (s) {
2805
 
        storeAppendPrintf(e, "%s %s:%d\n",
 
2891
        storeAppendPrintf(e, "%s %s\n",
2806
2892
                          n,
2807
 
                          inet_ntoa(s->s.sin_addr),
2808
 
                          ntohs(s->s.sin_port));
 
2893
                          s->s.NtoA(ntoabuf,MAX_IPSTRLEN));
2809
2894
        s = s->next;
2810
2895
    }
2811
2896
}
2812
2897
 
2813
2898
static void
2814
 
free_sockaddr_in_list(sockaddr_in_list ** head)
 
2899
free_IpAddress_list(IpAddress_list ** head)
2815
2900
{
2816
 
    sockaddr_in_list *s;
2817
 
 
2818
 
    while ((s = *head) != NULL) {
2819
 
        *head = s->next;
2820
 
        xfree(s);
2821
 
    }
 
2901
    if (*head) delete *head;
 
2902
    *head = NULL;
2822
2903
}
2823
2904
 
2824
2905
#if CURRENTLY_UNUSED
2826
2907
 * be used by icp_port and htcp_port
2827
2908
 */
2828
2909
static int
2829
 
check_null_sockaddr_in_list(const sockaddr_in_list * s)
 
2910
check_null_IpAddress_list(const IpAddress_list * s)
2830
2911
{
2831
2912
    return NULL == s;
2832
2913
}
2834
2915
#endif /* CURRENTLY_UNUSED */
2835
2916
#endif /* USE_WCCPv2 */
2836
2917
 
 
2918
CBDATA_CLASS_INIT(http_port_list);
 
2919
 
2837
2920
static void
2838
2921
parse_http_port_specification(http_port_list * s, char *token)
2839
2922
{
2840
2923
    char *host = NULL;
2841
 
 
2842
 
    const struct hostent *hp;
2843
2924
    unsigned short port = 0;
2844
 
    char *t;
 
2925
    char *t = NULL;
 
2926
    char *junk = NULL;
2845
2927
 
2846
2928
    s->disable_pmtu_discovery = DISABLE_PMTU_OFF;
2847
2929
    s->name = xstrdup(token);
 
2930
    s->connection_auth_disabled = false;
2848
2931
 
2849
 
    if ((t = strchr(token, ':'))) {
2850
 
        /* host:port */
2851
 
        host = token;
2852
 
        *t = '\0';
 
2932
#if USE_IPV6
 
2933
    if (*token == '[') {
 
2934
        /* [ipv6]:port */
 
2935
        host = token + 1;
 
2936
        t = strchr(host, ']');
 
2937
        if (!t) {
 
2938
            debugs(3, 0, "http(s)_port: missing ']' on IPv6 address: " << token);
 
2939
            self_destruct();
 
2940
        }
 
2941
        *t++ = '\0';
 
2942
        if (*t != ':') {
 
2943
            debugs(3, 0, "http(s)_port: missing Port in: " << token);
 
2944
            self_destruct();
 
2945
        }
2853
2946
        port = xatos(t + 1);
2854
 
    } else {
2855
 
        /* port */
2856
 
        port = xatos(token);
 
2947
    } else
 
2948
#endif
 
2949
        if ((t = strchr(token, ':'))) {
 
2950
            /* host:port */
 
2951
            /* ipv4:port */
 
2952
            host = token;
 
2953
            *t = '\0';
 
2954
            port = xatos(t + 1);
 
2955
 
 
2956
        } else if ((port = strtol(token, &junk, 10)), !*junk) {
 
2957
            /* port */
 
2958
            debugs(3, 3, "http(s)_port: found Listen on Port: " << port);
 
2959
        } else {
 
2960
            debugs(3, 0, "http(s)_port: missing Port: " << token);
 
2961
            self_destruct();
 
2962
        }
 
2963
 
 
2964
    if (port == 0) {
 
2965
        debugs(3, 0, "http(s)_port: Port cannot be 0: " << token);
 
2966
        self_destruct();
2857
2967
    }
2858
2968
 
2859
 
    if (port == 0)
2860
 
        self_destruct();
2861
 
 
2862
 
    s->s.sin_port = htons(port);
2863
 
 
2864
 
    if (NULL == host)
2865
 
        s->s.sin_addr = any_addr;
2866
 
    else if (1 == safe_inet_addr(host, &s->s.sin_addr))
2867
 
        (void) 0;
2868
 
    else if ((hp = gethostbyname(host))) {
 
2969
    if (NULL == host) {
 
2970
        s->s.SetAnyAddr();
 
2971
        s->s.SetPort(port);
 
2972
        debugs(3, 3, "http(s)_port: found Listen on wildcard address: " << s->s);
 
2973
    } else if ( s->s = host ) { /* check/parse numeric IPA */
 
2974
        s->s.SetPort(port);
 
2975
        debugs(3, 3, "http(s)_port: Listen on Host/IP: " << host << " --> " << s->s);
 
2976
    } else if ( s->s.GetHostByName(host) ) { /* check/parse for FQDN */
2869
2977
        /* dont use ipcache */
2870
 
        s->s.sin_addr = inaddrFromHostent(hp);
2871
2978
        s->defaultsite = xstrdup(host);
2872
 
    } else
 
2979
        s->s.SetPort(port);
 
2980
        debugs(3, 3, "http(s)_port: found Listen as Host " << s->defaultsite << " on IP: " << s->s);
 
2981
    } else {
 
2982
        debugs(3, 0, "http(s)_port: failed to resolve Host/IP: " << host);
2873
2983
        self_destruct();
 
2984
    }
2874
2985
}
2875
2986
 
2876
2987
static void
2897
3008
        s->accel = 1;
2898
3009
    } else if (strcmp(token, "accel") == 0) {
2899
3010
        s->accel = 1;
 
3011
    } else if (strcmp(token, "allow-direct") == 0) {
 
3012
        s->allow_direct = 1;
 
3013
    } else if (strcmp(token, "ignore-cc") == 0) {
 
3014
        s->ignore_cc = 1;
 
3015
#if !HTTP_VIOLATIONS
 
3016
        if (!s->accel) {
 
3017
            debugs(3, DBG_CRITICAL, "FATAL: ignore-cc is only valid in accelerator mode");
 
3018
            self_destruct();
 
3019
        }
 
3020
#endif
 
3021
    } else if (strcmp(token, "no-connection-auth") == 0) {
 
3022
        s->connection_auth_disabled = true;
 
3023
    } else if (strcmp(token, "connection-auth=off") == 0) {
 
3024
        s->connection_auth_disabled = true;
 
3025
    } else if (strcmp(token, "connection-auth") == 0) {
 
3026
        s->connection_auth_disabled = false;
 
3027
    } else if (strcmp(token, "connection-auth=on") == 0) {
 
3028
        s->connection_auth_disabled = false;
2900
3029
    } else if (strncmp(token, "disable-pmtu-discovery=", 23) == 0) {
2901
3030
        if (!strcasecmp(token + 23, "off"))
2902
3031
            s->disable_pmtu_discovery = DISABLE_PMTU_OFF;
2907
3036
        else
2908
3037
            self_destruct();
2909
3038
 
2910
 
    } else if (strcmp(token, "transparent") == 0) {
2911
 
        s->transparent = 1;
 
3039
    } else if (strcmp(token, "transparent") == 0 || strcmp(token, "intercept") == 0) {
 
3040
        s->intercepted = 1;
 
3041
        IpInterceptor.StartInterception();
2912
3042
        /* Log information regarding the port modes under interception. */
2913
 
        debugs(3, 1, "Starting Authentication on port " << inet_ntoa(s->s.sin_addr) << ":" << s->s.sin_port);
2914
 
        debugs(3, 1, "Disabling Authentication on port " << inet_ntoa(s->s.sin_addr) << ":" << s->s.sin_port << " (interception enabled)");
 
3043
        debugs(3, DBG_IMPORTANT, "Starting Authentication on port " << s->s);
 
3044
        debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (interception enabled)");
2915
3045
 
2916
 
#if LINUX_TPROXY
 
3046
#if USE_IPV6
 
3047
        /* INET6: until transparent REDIRECT works on IPv6 SOCKET, force wildcard to IPv4 */
 
3048
        debugs(3, DBG_IMPORTANT, "Disabling IPv6 on port " << s->s << " (interception enabled)");
 
3049
        if ( !s->s.SetIPv4() ) {
 
3050
            debugs(3, DBG_CRITICAL, "http(s)_port: IPv6 addresses cannot be transparent (protocol does not provide NAT)" << s->s );
 
3051
            self_destruct();
 
3052
        }
 
3053
#endif
2917
3054
    } else if (strcmp(token, "tproxy") == 0) {
2918
 
        s->tproxy = 1;
2919
 
        need_linux_tproxy = 1;
 
3055
        if (s->intercepted || s->accel) {
 
3056
            debugs(3,DBG_CRITICAL, "http(s)_port: TPROXY option requires its own interception port. It cannot be shared.");
 
3057
            self_destruct();
 
3058
        }
 
3059
        s->spoof_client_ip = 1;
 
3060
        IpInterceptor.StartTransparency();
2920
3061
        /* Log information regarding the port modes under transparency. */
2921
 
        debugs(3, 1, "Starting IP Spoofing on port " << inet_ntoa(s->s.sin_addr) << ":" << s->s.sin_port);
2922
 
        debugs(3, 1, "Disabling Authentication on port " << inet_ntoa(s->s.sin_addr) << ":" << s->s.sin_port << " (IP spoofing enabled)");
2923
 
#endif
2924
 
 
 
3062
        debugs(3, DBG_IMPORTANT, "Starting IP Spoofing on port " << s->s);
 
3063
        debugs(3, DBG_IMPORTANT, "Disabling Authentication on port " << s->s << " (IP spoofing enabled)");
 
3064
 
 
3065
        if (!IpInterceptor.ProbeForTproxy(s->s)) {
 
3066
            debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: TPROXY support in the system does not work.");
 
3067
            self_destruct();
 
3068
        }
 
3069
 
 
3070
    } else if (strcmp(token, "ipv4") == 0) {
 
3071
#if USE_IPV6
 
3072
        if ( !s->s.SetIPv4() ) {
 
3073
            debugs(3, 0, "http(s)_port: IPv6 addresses cannot be used a IPv4-Only." << s->s );
 
3074
            self_destruct();
 
3075
        }
 
3076
#endif
 
3077
    } else if (strcmp(token, "tcpkeepalive") == 0) {
 
3078
        s->tcp_keepalive.enabled = 1;
 
3079
    } else if (strncmp(token, "tcpkeepalive=", 13) == 0) {
 
3080
        char *t = token + 13;
 
3081
        s->tcp_keepalive.enabled = 1;
 
3082
        s->tcp_keepalive.idle = atoi(t);
 
3083
        t = strchr(t, ',');
 
3084
        if (t) {
 
3085
            t++;
 
3086
            s->tcp_keepalive.interval = atoi(t);
 
3087
            t = strchr(t, ',');
 
3088
        }
 
3089
        if (t) {
 
3090
            t++;
 
3091
            s->tcp_keepalive.timeout = atoi(t);
 
3092
            t = strchr(t, ',');
 
3093
        }
 
3094
#if USE_SSL
 
3095
    } else if (strncmp(token, "cert=", 5) == 0) {
 
3096
        safe_free(s->cert);
 
3097
        s->cert = xstrdup(token + 5);
 
3098
    } else if (strncmp(token, "key=", 4) == 0) {
 
3099
        safe_free(s->key);
 
3100
        s->key = xstrdup(token + 4);
 
3101
    } else if (strncmp(token, "version=", 8) == 0) {
 
3102
        s->version = xatoi(token + 8);
 
3103
 
 
3104
        if (s->version < 1 || s->version > 4)
 
3105
            self_destruct();
 
3106
    } else if (strncmp(token, "options=", 8) == 0) {
 
3107
        safe_free(s->options);
 
3108
        s->options = xstrdup(token + 8);
 
3109
    } else if (strncmp(token, "cipher=", 7) == 0) {
 
3110
        safe_free(s->cipher);
 
3111
        s->cipher = xstrdup(token + 7);
 
3112
    } else if (strncmp(token, "clientca=", 9) == 0) {
 
3113
        safe_free(s->clientca);
 
3114
        s->clientca = xstrdup(token + 9);
 
3115
    } else if (strncmp(token, "cafile=", 7) == 0) {
 
3116
        safe_free(s->cafile);
 
3117
        s->cafile = xstrdup(token + 7);
 
3118
    } else if (strncmp(token, "capath=", 7) == 0) {
 
3119
        safe_free(s->capath);
 
3120
        s->capath = xstrdup(token + 7);
 
3121
    } else if (strncmp(token, "crlfile=", 8) == 0) {
 
3122
        safe_free(s->crlfile);
 
3123
        s->crlfile = xstrdup(token + 8);
 
3124
    } else if (strncmp(token, "dhparams=", 9) == 0) {
 
3125
        safe_free(s->dhfile);
 
3126
        s->dhfile = xstrdup(token + 9);
 
3127
    } else if (strncmp(token, "sslflags=", 9) == 0) {
 
3128
        safe_free(s->sslflags);
 
3129
        s->sslflags = xstrdup(token + 9);
 
3130
    } else if (strncmp(token, "sslcontext=", 11) == 0) {
 
3131
        safe_free(s->sslcontext);
 
3132
        s->sslcontext = xstrdup(token + 11);
 
3133
    } else if (strcmp(token, "sslBump") == 0) {
 
3134
        s->sslBump = 1; // accelerated when bumped, otherwise not
 
3135
#endif
2925
3136
    } else {
2926
3137
        self_destruct();
2927
3138
    }
2928
 
}
2929
 
 
2930
 
static void
2931
 
free_generic_http_port_data(http_port_list * s)
2932
 
{
2933
 
    safe_free(s->name);
2934
 
    safe_free(s->defaultsite);
2935
 
    safe_free(s->protocol);
2936
 
}
2937
 
 
2938
 
static void
2939
 
cbdataFree_http_port(void *data)
2940
 
{
2941
 
    free_generic_http_port_data((http_port_list *)data);
 
3139
 
 
3140
    if ( s->spoof_client_ip && (s->intercepted || s->accel) ) {
 
3141
        debugs(3,DBG_CRITICAL, "http(s)_port: TPROXY option requires its own interception port. It cannot be shared.");
 
3142
        self_destruct();
 
3143
    }
2942
3144
}
2943
3145
 
2944
3146
static http_port_list *
2945
3147
create_http_port(char *portspec)
2946
3148
{
2947
 
    CBDATA_TYPE(http_port_list);
2948
 
    CBDATA_INIT_TYPE_FREECB(http_port_list, cbdataFree_http_port);
2949
 
 
2950
 
    http_port_list *s = cbdataAlloc(http_port_list);
2951
 
    s->protocol = xstrdup("http");
 
3149
    http_port_list *s = new http_port_list("http");
2952
3150
    parse_http_port_specification(s, portspec);
2953
3151
    return s;
2954
3152
}
2987
3185
static void
2988
3186
dump_generic_http_port(StoreEntry * e, const char *n, const http_port_list * s)
2989
3187
{
2990
 
    storeAppendPrintf(e, "%s %s:%d",
 
3188
    char buf[MAX_IPSTRLEN];
 
3189
 
 
3190
    storeAppendPrintf(e, "%s %s",
2991
3191
                      n,
2992
 
                      inet_ntoa(s->s.sin_addr),
2993
 
                      ntohs(s->s.sin_port));
 
3192
                      s->s.ToURL(buf,MAX_IPSTRLEN));
2994
3193
 
2995
3194
    if (s->defaultsite)
2996
3195
        storeAppendPrintf(e, " defaultsite=%s", s->defaultsite);
2997
3196
 
2998
 
    if (s->transparent)
2999
 
        storeAppendPrintf(e, " transparent");
 
3197
    if (s->intercepted)
 
3198
        storeAppendPrintf(e, " intercept");
3000
3199
 
3001
3200
    if (s->vhost)
3002
3201
        storeAppendPrintf(e, " vhost");
3004
3203
    if (s->vport)
3005
3204
        storeAppendPrintf(e, " vport");
3006
3205
 
 
3206
    if (s->connection_auth_disabled)
 
3207
        storeAppendPrintf(e, " connection-auth=off");
 
3208
    else
 
3209
        storeAppendPrintf(e, " connection-auth=on");
 
3210
 
3007
3211
    if (s->disable_pmtu_discovery != DISABLE_PMTU_OFF) {
3008
3212
        const char *pmtu;
3009
3213
 
3014
3218
 
3015
3219
        storeAppendPrintf(e, " disable-pmtu-discovery=%s", pmtu);
3016
3220
    }
 
3221
 
 
3222
    if (s->tcp_keepalive.enabled) {
 
3223
        if (s->tcp_keepalive.idle || s->tcp_keepalive.interval || s->tcp_keepalive.timeout) {
 
3224
            storeAppendPrintf(e, " tcpkeepalive=%d,%d,%d", s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout);
 
3225
        } else {
 
3226
            storeAppendPrintf(e, " tcpkeepalive");
 
3227
        }
 
3228
    }
 
3229
 
 
3230
#if USE_SSL
 
3231
    if (s->cert)
 
3232
        storeAppendPrintf(e, " cert=%s", s->cert);
 
3233
 
 
3234
    if (s->key)
 
3235
        storeAppendPrintf(e, " key=%s", s->key);
 
3236
 
 
3237
    if (s->version)
 
3238
        storeAppendPrintf(e, " version=%d", s->version);
 
3239
 
 
3240
    if (s->options)
 
3241
        storeAppendPrintf(e, " options=%s", s->options);
 
3242
 
 
3243
    if (s->cipher)
 
3244
        storeAppendPrintf(e, " cipher=%s", s->cipher);
 
3245
 
 
3246
    if (s->cafile)
 
3247
        storeAppendPrintf(e, " cafile=%s", s->cafile);
 
3248
 
 
3249
    if (s->capath)
 
3250
        storeAppendPrintf(e, " capath=%s", s->capath);
 
3251
 
 
3252
    if (s->crlfile)
 
3253
        storeAppendPrintf(e, " crlfile=%s", s->crlfile);
 
3254
 
 
3255
    if (s->dhfile)
 
3256
        storeAppendPrintf(e, " dhparams=%s", s->dhfile);
 
3257
 
 
3258
    if (s->sslflags)
 
3259
        storeAppendPrintf(e, " sslflags=%s", s->sslflags);
 
3260
 
 
3261
    if (s->sslcontext)
 
3262
        storeAppendPrintf(e, " sslcontext=%s", s->sslcontext);
 
3263
 
 
3264
    if (s->sslBump)
 
3265
        storeAppendPrintf(e, " sslBump");
 
3266
#endif
3017
3267
}
3018
3268
 
3019
3269
static void
3033
3283
 
3034
3284
    while ((s = *head) != NULL) {
3035
3285
        *head = s->next;
3036
 
        cbdataFree(s);
 
3286
        delete s;
3037
3287
    }
3038
3288
}
3039
3289
 
3040
3290
#if USE_SSL
3041
 
static void
3042
 
cbdataFree_https_port(void *data)
3043
 
{
3044
 
    https_port_list *s = (https_port_list *)data;
3045
 
    free_generic_http_port_data(&s->http);
3046
 
    safe_free(s->cert);
3047
 
    safe_free(s->key);
3048
 
    safe_free(s->options);
3049
 
    safe_free(s->cipher);
3050
 
    safe_free(s->cafile);
3051
 
    safe_free(s->capath);
3052
 
    safe_free(s->dhfile);
3053
 
    safe_free(s->sslflags);
3054
 
}
3055
3291
 
 
3292
// TODO: merge better with parse_http_port_list
3056
3293
static void
3057
3294
parse_https_port_list(https_port_list ** head)
3058
3295
{
3059
 
    CBDATA_TYPE(https_port_list);
3060
3296
    char *token;
3061
3297
    https_port_list *s;
3062
 
    CBDATA_INIT_TYPE_FREECB(https_port_list, cbdataFree_https_port);
 
3298
 
3063
3299
    token = strtok(NULL, w_space);
3064
3300
 
3065
3301
    if (!token)
3066
3302
        self_destruct();
3067
3303
 
3068
 
    s = cbdataAlloc(https_port_list);
3069
 
 
3070
 
    s->http.protocol = xstrdup("https");
3071
 
 
 
3304
    s = new https_port_list;
3072
3305
    parse_http_port_specification(&s->http, token);
3073
3306
 
3074
3307
    /* parse options ... */
3075
3308
    while ((token = strtok(NULL, w_space))) {
3076
 
        if (strncmp(token, "cert=", 5) == 0) {
3077
 
            safe_free(s->cert);
3078
 
            s->cert = xstrdup(token + 5);
3079
 
        } else if (strncmp(token, "key=", 4) == 0) {
3080
 
            safe_free(s->key);
3081
 
            s->key = xstrdup(token + 4);
3082
 
        } else if (strncmp(token, "version=", 8) == 0) {
3083
 
            s->version = xatoi(token + 8);
3084
 
 
3085
 
            if (s->version < 1 || s->version > 4)
3086
 
                self_destruct();
3087
 
        } else if (strncmp(token, "options=", 8) == 0) {
3088
 
            safe_free(s->options);
3089
 
            s->options = xstrdup(token + 8);
3090
 
        } else if (strncmp(token, "cipher=", 7) == 0) {
3091
 
            safe_free(s->cipher);
3092
 
            s->cipher = xstrdup(token + 7);
3093
 
        } else if (strncmp(token, "clientca=", 9) == 0) {
3094
 
            safe_free(s->clientca);
3095
 
            s->clientca = xstrdup(token + 9);
3096
 
        } else if (strncmp(token, "cafile=", 7) == 0) {
3097
 
            safe_free(s->cafile);
3098
 
            s->cafile = xstrdup(token + 7);
3099
 
        } else if (strncmp(token, "capath=", 7) == 0) {
3100
 
            safe_free(s->capath);
3101
 
            s->capath = xstrdup(token + 7);
3102
 
        } else if (strncmp(token, "crlfile=", 8) == 0) {
3103
 
            safe_free(s->crlfile);
3104
 
            s->crlfile = xstrdup(token + 8);
3105
 
        } else if (strncmp(token, "dhparams=", 9) == 0) {
3106
 
            safe_free(s->dhfile);
3107
 
            s->dhfile = xstrdup(token + 9);
3108
 
        } else if (strncmp(token, "sslflags=", 9) == 0) {
3109
 
            safe_free(s->sslflags);
3110
 
            s->sslflags = xstrdup(token + 9);
3111
 
        } else if (strncmp(token, "sslcontext=", 11) == 0) {
3112
 
            safe_free(s->sslcontext);
3113
 
            s->sslcontext = xstrdup(token + 11);
3114
 
        } else {
3115
 
            parse_http_port_option(&s->http, token);
3116
 
        }
 
3309
        parse_http_port_option(s, token);
3117
3310
    }
3118
3311
 
3119
3312
    while (*head) {
3127
3320
static void
3128
3321
dump_https_port_list(StoreEntry * e, const char *n, const https_port_list * s)
3129
3322
{
3130
 
    while (s) {
3131
 
        dump_generic_http_port(e, n, &s->http);
3132
 
 
3133
 
        if (s->cert)
3134
 
            storeAppendPrintf(e, " cert=%s", s->cert);
3135
 
 
3136
 
        if (s->key)
3137
 
            storeAppendPrintf(e, " key=%s", s->key);
3138
 
 
3139
 
        if (s->version)
3140
 
            storeAppendPrintf(e, " version=%d", s->version);
3141
 
 
3142
 
        if (s->options)
3143
 
            storeAppendPrintf(e, " options=%s", s->options);
3144
 
 
3145
 
        if (s->cipher)
3146
 
            storeAppendPrintf(e, " cipher=%s", s->cipher);
3147
 
 
3148
 
        if (s->cafile)
3149
 
            storeAppendPrintf(e, " cafile=%s", s->cafile);
3150
 
 
3151
 
        if (s->capath)
3152
 
            storeAppendPrintf(e, " capath=%s", s->capath);
3153
 
 
3154
 
        if (s->crlfile)
3155
 
            storeAppendPrintf(e, " crlfile=%s", s->crlfile);
3156
 
 
3157
 
        if (s->dhfile)
3158
 
            storeAppendPrintf(e, " dhparams=%s", s->dhfile);
3159
 
 
3160
 
        if (s->sslflags)
3161
 
            storeAppendPrintf(e, " sslflags=%s", s->sslflags);
3162
 
 
3163
 
        if (s->sslcontext)
3164
 
            storeAppendPrintf(e, " sslcontext=%s", s->sslcontext);
3165
 
 
3166
 
        storeAppendPrintf(e, "\n");
3167
 
 
3168
 
        s = (https_port_list *) s->http.next;
3169
 
    }
 
3323
    dump_http_port_list(e, n, s);
3170
3324
}
3171
3325
 
3172
3326
static void
3173
3327
free_https_port_list(https_port_list ** head)
3174
3328
{
3175
 
    https_port_list *s;
3176
 
 
3177
 
    while ((s = *head) != NULL) {
3178
 
        *head = (https_port_list *) s->http.next;
3179
 
        cbdataFree(s);
3180
 
    }
 
3329
    free_http_port_list((http_port_list**)head);
3181
3330
}
3182
3331
 
3183
3332
#if 0
3303
3452
        cl->type = CLF_SQUID;
3304
3453
    } else if (strcmp(logdef_name, "common") == 0) {
3305
3454
        cl->type = CLF_COMMON;
 
3455
#if ICAP_CLIENT
 
3456
    } else if (strcmp(logdef_name, "icap_squid") == 0) {
 
3457
        cl->type = CLF_ICAP_SQUID;
 
3458
#endif
3306
3459
    } else {
3307
3460
        debugs(3, 0, "Log format '" << logdef_name << "' is not defined");
3308
3461
        self_destruct();
3318
3471
    *logs = cl;
3319
3472
}
3320
3473
 
3321
 
#if UNUSED_CODE
3322
3474
static int
3323
3475
check_null_access_log(customlog *customlog_definitions)
3324
3476
{
3325
3477
    return customlog_definitions == NULL;
3326
3478
}
3327
 
#endif
3328
3479
 
3329
3480
static void
3330
3481
dump_logformat(StoreEntry * entry, const char *name, logformat * definitions)
3357
3508
        case CLF_COMMON:
3358
3509
            storeAppendPrintf(entry, "%s squid", log->filename);
3359
3510
            break;
3360
 
 
 
3511
#if ICAP_CLIENT
 
3512
        case CLF_ICAP_SQUID:
 
3513
            storeAppendPrintf(entry, "%s icap_squid", log->filename);
 
3514
            break;
 
3515
#endif
3361
3516
        case CLF_AUTO:
3362
3517
 
3363
3518
            if (log->aclList)
3409
3564
    }
3410
3565
}
3411
3566
 
 
3567
#if USE_ADAPTATION
 
3568
 
 
3569
static void
 
3570
parse_adaptation_service_set_type()
 
3571
{
 
3572
    Adaptation::Config::ParseServiceSet();
 
3573
}
 
3574
 
 
3575
static void
 
3576
parse_adaptation_service_chain_type()
 
3577
{
 
3578
    Adaptation::Config::ParseServiceChain();
 
3579
}
 
3580
 
 
3581
static void
 
3582
parse_adaptation_access_type()
 
3583
{
 
3584
    Adaptation::Config::ParseAccess(LegacyParser);
 
3585
}
 
3586
 
 
3587
#endif /* USE_ADAPTATION */
 
3588
 
 
3589
 
3412
3590
#if ICAP_CLIENT
3413
3591
 
3414
3592
static void
3415
 
parse_icap_service_type(ICAPConfig * cfg)
3416
 
{
3417
 
    cfg->parseICAPService();
3418
 
}
3419
 
 
3420
 
static void
3421
 
free_icap_service_type(ICAPConfig * cfg)
3422
 
{
3423
 
    cfg->freeICAPService();
3424
 
}
3425
 
 
3426
 
static void
3427
 
dump_icap_service_type(StoreEntry * entry, const char *name, const ICAPConfig &cfg)
3428
 
{
3429
 
    cfg.dumpICAPService(entry, name);
3430
 
}
3431
 
 
3432
 
static void
3433
 
parse_icap_class_type(ICAPConfig * cfg)
3434
 
{
3435
 
    cfg->parseICAPClass();
3436
 
}
3437
 
 
3438
 
static void
3439
 
free_icap_class_type(ICAPConfig * cfg)
3440
 
{
3441
 
    cfg->freeICAPClass();
3442
 
}
3443
 
 
3444
 
static void
3445
 
dump_icap_class_type(StoreEntry * entry, const char *name, const ICAPConfig &cfg)
3446
 
{
3447
 
    cfg.dumpICAPClass(entry, name);
3448
 
}
3449
 
 
3450
 
static void
3451
 
parse_icap_access_type(ICAPConfig * cfg)
3452
 
{
3453
 
    cfg->parseICAPAccess(LegacyParser);
3454
 
}
3455
 
 
3456
 
static void
3457
 
free_icap_access_type(ICAPConfig * cfg)
3458
 
{
3459
 
    cfg->freeICAPAccess();
3460
 
}
3461
 
 
3462
 
static void
3463
 
dump_icap_access_type(StoreEntry * entry, const char *name, const ICAPConfig &cfg)
3464
 
{
3465
 
    cfg.dumpICAPAccess(entry, name);
 
3593
parse_icap_service_type(Adaptation::Icap::Config * cfg)
 
3594
{
 
3595
    cfg->parseService();
 
3596
}
 
3597
 
 
3598
static void
 
3599
free_icap_service_type(Adaptation::Icap::Config * cfg)
 
3600
{
 
3601
    cfg->freeService();
 
3602
}
 
3603
 
 
3604
static void
 
3605
dump_icap_service_type(StoreEntry * entry, const char *name, const Adaptation::Icap::Config &cfg)
 
3606
{
 
3607
    cfg.dumpService(entry, name);
 
3608
}
 
3609
 
 
3610
static void
 
3611
parse_icap_class_type()
 
3612
{
 
3613
    debugs(93, 0, "WARNING: 'icap_class' is depricated. " <<
 
3614
           "Use 'adaptation_service_set' instead");
 
3615
    Adaptation::Config::ParseServiceSet();
 
3616
}
 
3617
 
 
3618
static void
 
3619
parse_icap_access_type()
 
3620
{
 
3621
    debugs(93, 0, "WARNING: 'icap_access' is depricated. " <<
 
3622
           "Use 'adaptation_access' instead");
 
3623
    Adaptation::Config::ParseAccess(LegacyParser);
3466
3624
}
3467
3625
 
3468
3626
#endif
 
3627
 
 
3628
 
 
3629
#if USE_ECAP
 
3630
 
 
3631
static void
 
3632
parse_ecap_service_type(Adaptation::Ecap::Config * cfg)
 
3633
{
 
3634
    cfg->parseService();
 
3635
}
 
3636
 
 
3637
static void
 
3638
free_ecap_service_type(Adaptation::Ecap::Config * cfg)
 
3639
{
 
3640
    cfg->freeService();
 
3641
}
 
3642
 
 
3643
static void
 
3644
dump_ecap_service_type(StoreEntry * entry, const char *name, const Adaptation::Ecap::Config &cfg)
 
3645
{
 
3646
    cfg.dumpService(entry, name);
 
3647
}
 
3648
 
 
3649
#endif /* USE_ECAP */