#endif
#include "auth/Config.h"
#include "auth/Scheme.h"
-#include "CacheManager.h"
#include "ConfigParser.h"
+#include "CpuAffinityMap.h"
#include "eui/Config.h"
#if USE_SQUID_ESI
#include "esi/Parser.h"
#include "ip/tools.h"
#include "log/Config.h"
#include "MemBuf.h"
+#include "mgr/Registration.h"
#include "Parsing.h"
#include "ProtoPort.h"
#include "rfc1738.h"
#include <glob.h>
#endif
+#if HAVE_LIMITS_H
+#include <limits>
+#endif
+
#if USE_ADAPTATION
static void parse_adaptation_service_set_type();
static void parse_adaptation_service_chain_type();
static void default_all(void);
static void defaults_if_none(void);
static int parse_line(char *);
+static void parse_obsolete(const char *);
static void parseBytesLine(size_t * bptr, const char *units);
+#if !USE_DNSSERVERS
+static void parseBytesLineSigned(ssize_t * bptr, const char *units);
+#endif
static size_t parseBytesUnits(const char *unit);
static void free_all(void);
void requirePathnameExists(const char *name, const char *path);
static void parse_b_size_t(size_t * var);
static void parse_b_int64_t(int64_t * var);
+static bool parseNamedIntList(const char *data, const String &name, Vector<int> &list);
+
+static void parse_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap);
+static void dump_CpuAffinityMap(StoreEntry *const entry, const char *const name, const CpuAffinityMap *const cpuAffinityMap);
+static void free_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap);
+
static int parseOneConfigFile(const char *file_name, unsigned int depth);
/*
parseConfigFile(const char *file_name)
{
int err_count = 0;
- CacheManager *manager=CacheManager::GetInstance();
debugs(5, 4, HERE);
}
if (opt_send_signal == -1) {
- manager->registerAction("config",
- "Current Squid Configuration",
- dump_config,
- 1, 1);
+ Mgr::RegisterAction("config",
+ "Current Squid Configuration",
+ dump_config,
+ 1, 1);
}
return err_count;
else
Config.appendDomainLen = 0;
- if (Config.retry.maxtries > 10)
- fatal("maximum_single_addr_tries cannot be larger than 10");
-
- if (Config.retry.maxtries < 1) {
- debugs(3, 0, "WARNING: resetting 'maximum_single_addr_tries to 1");
- Config.retry.maxtries = 1;
+ if (Config.connect_retries > 10) {
+ debugs(0,DBG_CRITICAL, "WARNING: connect_retries cannot be larger than 10. Resetting to 10.");
+ Config.connect_retries = 10;
}
requirePathnameExists("MIME Config Table", Config.mimeTablePathname);
#endif
}
+/** Parse a line containing an obsolete directive.
+ * To upgrade it where possible instead of just "Bungled config" for
+ * directives which cannot be marked as simply aliases of the some name.
+ * For example if the parameter order and content has changed.
+ * Or if the directive has been completely removed.
+ */
+void
+parse_obsolete(const char *name)
+{
+ // Directives which have been radically changed rather than removed
+ if (!strcmp(name, "url_rewrite_concurrency")) {
+ int cval;
+ parse_int(&cval);
+ debugs(3, DBG_CRITICAL, "WARNING: url_rewrite_concurrency upgrade overriding url_rewrite_children settings.");
+ Config.redirectChildren.concurrency = cval;
+ }
+}
+
/* Parse a time specification from the config file. Store the
* result in 'tptr', after converting it to 'units' */
static void
self_destruct();
}
+#if !USE_DNSSERVERS
+static void
+parseBytesLineSigned(ssize_t * bptr, const char *units)
+{
+ char *token;
+ double d;
+ int m;
+ int u;
+
+ if ((u = parseBytesUnits(units)) == 0) {
+ self_destruct();
+ return;
+ }
+
+ if ((token = strtok(NULL, w_space)) == NULL) {
+ self_destruct();
+ return;
+ }
+
+ if (strcmp(token, "none") == 0 || token[0] == '-' /* -N */) {
+ *bptr = -1;
+ return;
+ }
+
+ d = xatof(token);
+
+ m = u; /* default to 'units' if none specified */
+
+ if (0.0 == d)
+ (void) 0;
+ else if ((token = strtok(NULL, w_space)) == NULL)
+ debugs(3, 0, "WARNING: No units on '" <<
+ config_input_line << "', assuming " <<
+ d << " " << units );
+ else if ((m = parseBytesUnits(token)) == 0) {
+ self_destruct();
+ return;
+ }
+
+ *bptr = static_cast<size_t>(m * d / u);
+
+ if (static_cast<double>(*bptr) * 2 != m * d / u * 2)
+ self_destruct();
+}
+#endif
+
static size_t
parseBytesUnits(const char *unit)
{
aclDestroyAcls(ae);
}
-static void
+void
dump_acl_list(StoreEntry * entry, ACLList * head)
{
ACLList *l;
{
acl_tos *l;
acl_tos **tail = head; /* sane name below */
- int tos;
- char junk;
+ unsigned int tos; /* Initially uint for strtoui. Casted to tos_t before return */
char *token = strtok(NULL, w_space);
if (!token) {
return;
}
- if (sscanf(token, "0x%x%c", &tos, &junk) != 1) {
- self_destruct();
- return;
- }
-
- if (tos < 0 || tos > 255) {
+ if (!xstrtoui(token, NULL, &tos, 0, std::numeric_limits<tos_t>::max())) {
self_destruct();
return;
}
l = cbdataAlloc(acl_tos);
- l->tos = tos;
+ l->tos = (tos_t)tos;
aclParseAclList(LegacyParser, &l->aclList);
}
}
+#if defined(SO_MARK)
+
+CBDATA_TYPE(acl_nfmark);
+
+static void
+dump_acl_nfmark(StoreEntry * entry, const char *name, acl_nfmark * head)
+{
+ acl_nfmark *l;
+
+ for (l = head; l; l = l->next) {
+ if (l->nfmark > 0)
+ storeAppendPrintf(entry, "%s 0x%02X", name, l->nfmark);
+ else
+ storeAppendPrintf(entry, "%s none", name);
+
+ dump_acl_list(entry, l->aclList);
+
+ storeAppendPrintf(entry, "\n");
+ }
+}
+
+static void
+freed_acl_nfmark(void *data)
+{
+ acl_nfmark *l = static_cast<acl_nfmark *>(data);
+ aclDestroyAclList(&l->aclList);
+}
+
+static void
+parse_acl_nfmark(acl_nfmark ** head)
+{
+ acl_nfmark *l;
+ acl_nfmark **tail = head; /* sane name below */
+ nfmark_t mark;
+ char *token = strtok(NULL, w_space);
+
+ if (!token) {
+ self_destruct();
+ return;
+ }
+
+ if (!xstrtoui(token, NULL, &mark, 0, std::numeric_limits<nfmark_t>::max())) {
+ self_destruct();
+ return;
+ }
+
+ CBDATA_INIT_TYPE_FREECB(acl_nfmark, freed_acl_nfmark);
+
+ l = cbdataAlloc(acl_nfmark);
+
+ l->nfmark = mark;
+
+ aclParseAclList(LegacyParser, &l->aclList);
+
+ while (*tail)
+ tail = &(*tail)->next;
+
+ *tail = l;
+}
+
+static void
+free_acl_nfmark(acl_nfmark ** head)
+{
+ while (*head) {
+ acl_nfmark *l = *head;
+ *head = l->next;
+ l->next = NULL;
+ cbdataFree(l);
+ }
+}
+#endif /* SO_MARK */
+
CBDATA_TYPE(acl_size_t);
static void
#endif
+#if DELAY_POOLS
+#include "ClientDelayConfig.h"
+/* do nothing - free_client_delay_pool_count is the magic free function.
+ * this is why client_delay_pool_count isn't just marked TYPE: ushort
+ */
+
+#define free_client_delay_pool_access(X)
+#define free_client_delay_pool_rates(X)
+#define dump_client_delay_pool_access(X, Y, Z)
+#define dump_client_delay_pool_rates(X, Y, Z)
+
+static void
+free_client_delay_pool_count(ClientDelayConfig * cfg)
+{
+ cfg->freePoolCount();
+}
+
+static void
+dump_client_delay_pool_count(StoreEntry * entry, const char *name, ClientDelayConfig &cfg)
+{
+ cfg.dumpPoolCount (entry, name);
+}
+
+static void
+parse_client_delay_pool_count(ClientDelayConfig * cfg)
+{
+ cfg->parsePoolCount();
+}
+
+static void
+parse_client_delay_pool_rates(ClientDelayConfig * cfg)
+{
+ cfg->parsePoolRates();
+}
+
+static void
+parse_client_delay_pool_access(ClientDelayConfig * cfg)
+{
+ cfg->parsePoolAccess(LegacyParser);
+}
+#endif
+
#if USE_HTTP_VIOLATIONS
static void
dump_http_header_access(StoreEntry * entry, const char *name, header_mangler header[])
static void
parse_cachedir(SquidConfig::_cacheSwap * swap)
{
+ // The workers option must preceed cache_dir for the IamWorkerProcess check
+ // below to work. TODO: Redo IamWorkerProcess to work w/o Config and remove
+ if (KidIdentifier > 1 && Config.workers == 1) {
+ debugs(3, DBG_CRITICAL,
+ "FATAL: cache_dir found before the workers option. Reorder.");
+ self_destruct();
+ }
+
+ // Among all processes, only workers may need and can handle cache_dir.
+ if (!IamWorkerProcess())
+ return;
+
char *type_str;
char *path_str;
RefCount<SwapDir> sd;
} else if (!strcasecmp(token, "weighted-round-robin")) {
p->options.weighted_roundrobin = 1;
#if USE_HTCP
-
} else if (!strcasecmp(token, "htcp")) {
p->options.htcp = 1;
- } else if (!strcasecmp(token, "htcp-oldsquid")) {
- p->options.htcp = 1;
- p->options.htcp_oldsquid = 1;
- } else if (!strcasecmp(token, "htcp-no-clr")) {
- if (p->options.htcp_only_clr)
- fatalf("parse_peer: can't set htcp-no-clr and htcp-only-clr simultaneously");
- p->options.htcp = 1;
- p->options.htcp_no_clr = 1;
- } else if (!strcasecmp(token, "htcp-no-purge-clr")) {
- p->options.htcp = 1;
- p->options.htcp_no_purge_clr = 1;
- } else if (!strcasecmp(token, "htcp-only-clr")) {
- if (p->options.htcp_no_clr)
- fatalf("parse_peer: can't set htcp-no-clr and htcp-only-clr simultaneously");
- p->options.htcp = 1;
- p->options.htcp_only_clr = 1;
- } else if (!strcasecmp(token, "htcp-forward-clr")) {
+ } else if (!strncasecmp(token, "htcp=", 5) || !strncasecmp(token, "htcp-", 5)) {
+ /* Note: The htcp- form is deprecated, replaced by htcp= */
p->options.htcp = 1;
- p->options.htcp_forward_clr = 1;
+ char *tmp = xstrdup(token+5);
+ char *mode, *nextmode;
+ for (mode = nextmode = tmp; mode; mode = nextmode) {
+ nextmode = strchr(mode, ',');
+ if (nextmode)
+ *nextmode++ = '\0';
+ if (!strcasecmp(mode, "no-clr")) {
+ if (p->options.htcp_only_clr)
+ fatalf("parse_peer: can't set htcp-no-clr and htcp-only-clr simultaneously");
+ p->options.htcp_no_clr = 1;
+ } else if (!strcasecmp(mode, "no-purge-clr")) {
+ p->options.htcp_no_purge_clr = 1;
+ } else if (!strcasecmp(mode, "only-clr")) {
+ if (p->options.htcp_no_clr)
+ fatalf("parse_peer: can't set htcp no-clr and only-clr simultaneously");
+ p->options.htcp_only_clr = 1;
+ } else if (!strcasecmp(mode, "forward-clr")) {
+ p->options.htcp_forward_clr = 1;
+ } else if (!strcasecmp(mode, "oldsquid")) {
+ p->options.htcp_oldsquid = 1;
+ } else {
+ fatalf("invalid HTCP mode '%s'", mode);
+ }
+ }
+ safe_free(tmp);
#endif
-
} else if (!strcasecmp(token, "no-netdb-exchange")) {
p->options.no_netdb_exchange = 1;
p->icp.version = ICP_VERSION_CURRENT;
- p->test_fd = -1;
+ p->testing_now = false;
#if USE_CACHE_DIGESTS
i = GetInteger(); /* token: min */
+ /* catch negative and insanely huge values close to 32-bit wrap */
+ if (i < 0) {
+ debugs(3, DBG_IMPORTANT, "WARNING: refresh_pattern minimum age negative. Cropped back to zero.");
+ i = 0;
+ }
+ if (i > 60*24*365) {
+ debugs(3, DBG_IMPORTANT, "WARNING: refresh_pattern minimum age too high. Cropped back to 1 year.");
+ i = 60*24*365;
+ }
+
min = (time_t) (i * 60); /* convert minutes to seconds */
i = GetInteger(); /* token: pct */
i = GetInteger(); /* token: max */
+ /* catch negative and insanely huge values close to 32-bit wrap */
+ if (i < 0) {
+ debugs(3, DBG_IMPORTANT, "WARNING: refresh_pattern maximum age negative. Cropped back to zero.");
+ i = 0;
+ }
+ if (i > 60*24*365) {
+ debugs(3, DBG_IMPORTANT, "WARNING: refresh_pattern maximum age too high. Cropped back to 1 year.");
+ i = 60*24*365;
+ }
+
max = (time_t) (i * 60); /* convert minutes to seconds */
/* Options */
storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_BYTES_STR);
}
+#if !USE_DNSSERVERS
+static void
+dump_b_ssize_t(StoreEntry * entry, const char *name, ssize_t var)
+{
+ storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_BYTES_STR);
+}
+#endif
+
#if UNUSED_CODE
static void
dump_kb_size_t(StoreEntry * entry, const char *name, size_t var)
parseBytesLine(var, B_BYTES_STR);
}
+#if !USE_DNSSERVERS
+static void
+parse_b_ssize_t(ssize_t * var)
+{
+ parseBytesLineSigned(var, B_BYTES_STR);
+}
+#endif
+
#if UNUSED_CODE
static void
parse_kb_size_t(size_t * var)
*var = 0;
}
+#if !USE_DNSSERVERS
+static void
+free_ssize_t(ssize_t * var)
+{
+ *var = 0;
+}
+#endif
+
static void
free_b_int64_t(int64_t * var)
{
}
#define free_b_size_t free_size_t
+#define free_b_ssize_t free_ssize_t
#define free_kb_size_t free_size_t
#define free_mb_size_t free_size_t
#define free_gb_size_t free_size_t
t = strchr(t, ',');
}
#if USE_SSL
- } else if (strcmp(token, "sslBump") == 0) {
+ } else if (strcasecmp(token, "sslBump") == 0) {
+ debugs(3, DBG_CRITICAL, "WARNING: '" << token << "' is deprecated " <<
+ "in http_port. Use 'ssl-bump' instead.");
+ s->sslBump = 1; // accelerated when bumped, otherwise not
+ } else if (strcmp(token, "ssl-bump") == 0) {
s->sslBump = 1; // accelerated when bumped, otherwise not
} else if (strncmp(token, "cert=", 5) == 0) {
safe_free(s->cert);
}
}
+/// parses list of integers form name=N1,N2,N3,...
+static bool
+parseNamedIntList(const char *data, const String &name, Vector<int> &list)
+{
+ if (data && (strncmp(data, name.rawBuf(), name.size()) == 0)) {
+ data += name.size();
+ if (*data == '=') {
+ while (true) {
+ ++data;
+ int value = 0;
+ if (!StringToInt(data, value, &data, 10))
+ break;
+ list.push_back(value);
+ if (*data == '\0' || *data != ',')
+ break;
+ }
+ }
+ }
+ return data && *data == '\0';
+}
+
+static void
+parse_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap)
+{
+#if !HAVE_CPU_AFFINITY
+ debugs(3, DBG_CRITICAL, "FATAL: Squid built with no CPU affinity " <<
+ "support, do not set 'cpu_affinity_map'");
+ self_destruct();
+#endif /* HAVE_CPU_AFFINITY */
+
+ if (!*cpuAffinityMap)
+ *cpuAffinityMap = new CpuAffinityMap;
+
+ const char *const pToken = strtok(NULL, w_space);
+ const char *const cToken = strtok(NULL, w_space);
+ Vector<int> processes, cores;
+ if (!parseNamedIntList(pToken, "process_numbers", processes)) {
+ debugs(3, DBG_CRITICAL, "FATAL: bad 'process_numbers' parameter " <<
+ "in 'cpu_affinity_map'");
+ self_destruct();
+ } else if (!parseNamedIntList(cToken, "cores", cores)) {
+ debugs(3, DBG_CRITICAL, "FATAL: bad 'cores' parameter in " <<
+ "'cpu_affinity_map'");
+ self_destruct();
+ } else if (!(*cpuAffinityMap)->add(processes, cores)) {
+ debugs(3, DBG_CRITICAL, "FATAL: bad 'cpu_affinity_map'; " <<
+ "process_numbers and cores lists differ in length or " <<
+ "contain numbers <= 0");
+ self_destruct();
+ }
+}
+
+static void
+dump_CpuAffinityMap(StoreEntry *const entry, const char *const name, const CpuAffinityMap *const cpuAffinityMap)
+{
+ if (cpuAffinityMap) {
+ storeAppendPrintf(entry, "%s process_numbers=", name);
+ for (size_t i = 0; i < cpuAffinityMap->processes().size(); ++i) {
+ storeAppendPrintf(entry, "%s%i", (i ? "," : ""),
+ cpuAffinityMap->processes()[i]);
+ }
+ storeAppendPrintf(entry, " cores=");
+ for (size_t i = 0; i < cpuAffinityMap->processes().size(); ++i) {
+ storeAppendPrintf(entry, "%s%i", (i ? "," : ""),
+ cpuAffinityMap->cores()[i]);
+ }
+ storeAppendPrintf(entry, "\n");
+ }
+}
+
+static void
+free_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap)
+{
+ delete *cpuAffinityMap;
+ *cpuAffinityMap = NULL;
+}
+
#if USE_ADAPTATION
static void