109#include <sys/socket.h>
190#if USE_HTTP_VIOLATIONS
194#define free_http_header_access free_HeaderManglers
197#define free_http_header_replace free_HeaderManglers
219#define parse_PortCfg(l) parsePortCfg((l), token)
221#define free_PortCfg(h) *(h)=NULL
304 char* saveptr =
nullptr;
309 memset(&globbuf, 0,
sizeof(globbuf));
311 if (glob(path, globbuf.gl_pathc ? GLOB_APPEND : 0,
nullptr, &globbuf) != 0) {
313 fatalf(
"Unable to find configuration file: %s: %s", path,
xstrerr(xerrno));
316 for (i = 0; i < (
int)globbuf.gl_pathc; ++i) {
322 while (file !=
NULL) {
331ReplaceSubstr(
char*& str,
int& len,
unsigned substrIdx,
unsigned substrLen,
const char* newSubstr)
334 assert(newSubstr !=
nullptr);
336 unsigned newSubstrLen = strlen(newSubstr);
337 if (newSubstrLen > substrLen)
338 str = (
char*)realloc(str, len - substrLen + newSubstrLen + 1);
341 memmove(str + substrIdx + newSubstrLen, str + substrIdx + substrLen, len - substrIdx - substrLen + 1);
343 memcpy(str + substrIdx, newSubstr, newSubstrLen);
352 assert(macroName !=
nullptr);
353 assert(substStr !=
nullptr);
354 unsigned macroNameLen = strlen(macroName);
355 while (
const char* macroPos = strstr(line, macroName))
356 ReplaceSubstr(line, len, macroPos - line, macroNameLen, substStr);
371 unsigned i = strlen(str);
372 while ((i > 0) &&
xisspace(str[i - 1]))
381 assert(statement !=
nullptr);
383 const char* str =
skip_ws(line);
384 unsigned len = strlen(statement);
385 if (strncmp(str, statement, len) == 0) {
402 number = strtol(str, &end, 0);
404 return (end != str) && (*end ==
'\0');
411 if (strcmp(expr,
"true") == 0) {
413 }
else if (strcmp(expr,
"false") == 0) {
415 }
else if (
const char* equation = strchr(expr,
'=')) {
416 const char* rvalue =
skip_ws(equation + 1);
417 char* lvalue = (
char*)
xmalloc(equation - expr + 1);
418 xstrncpy(lvalue, expr, equation - expr + 1);
423 fatalf(
"String is not a integer number: '%s'\n", lvalue);
426 fatalf(
"String is not a integer number: '%s'\n", rvalue);
429 return number1 == number2;
431 fatalf(
"Unable to evaluate expression '%s'\n", expr);
441 char *token =
nullptr;
442 char *tmp_line =
nullptr;
443 int tmp_line_len = 0;
447 debugs(3,
Important(68),
"Processing Configuration File: " << file_name <<
" (depth " << depth <<
")");
449 fatalf(
"WARNING: can't include %s: includes are nested too deeply (>16)!\n", file_name);
453 if (file_name[0] ==
'!' || file_name[0] ==
'|') {
454 fp = popen(file_name + 1,
"r");
457 fp = fopen(file_name,
"r");
462 fatalf(
"Unable to open configuration file: %s: %s", file_name,
xstrerr(xerrno));
466 setmode(fileno(fp),
O_TEXT);
475 std::vector<bool> if_states;
491 static char new_file_name[1024];
493 static char new_lineno;
495 new_lineno = strtol(token, &file, 0) - 1;
500 while (*file &&
xisspace((
unsigned char) *file))
507 xstrncpy(new_file_name, file + 1,
sizeof(new_file_name));
509 if ((token = strchr(new_file_name,
'"')))
526 size_t append_len = strlen(append);
528 tmp_line = (
char*)
xrealloc(tmp_line, tmp_line_len + append_len + 1);
530 strcpy(tmp_line + tmp_line_len, append);
532 tmp_line_len += append_len;
534 if (tmp_line[tmp_line_len-1] ==
'\\') {
535 debugs(3, 5,
"parseConfigFile: tmp_line='" << tmp_line <<
"'");
536 tmp_line[--tmp_line_len] =
'\0';
547 if (!if_states.empty())
548 if_states.pop_back();
550 fatalf(
"'endif' without 'if'\n");
552 if (!if_states.empty())
553 if_states.back() = !if_states.back();
555 fatalf(
"'else' without 'if'\n");
556 }
else if (if_states.empty() || if_states.back()) {
558 if (tmp_line_len >= 9 && strncmp(tmp_line,
"include", 7) == 0 &&
xisspace(tmp_line[7])) {
578 if (!if_states.empty())
579 fatalf(
"if-statement without 'endif'\n");
582 int ret = pclose(fp);
585 fatalf(
"parseConfigFile: '%s' failed with exit code %d\n", file_name, ret);
625 "Current Squid Configuration",
640 catch (
const std::exception &ex) {
689 entry->
append(name, strlen(name));
692 const auto buf = os.
buf();
695 entry->
append(buf.rawContent(), buf.length());
712 static_assert(std::is_trivial<T>::value,
"SquidConfig member is trivial");
713 memset(&raw, 0,
sizeof(raw));
730 debugs(3,
DBG_CRITICAL,
"WARNING: This Squid binary can not handle files larger than 2GB. Limiting maximum_object_size to just below 2GB");
756 fatal(
"append_domain must begin with a '.'");
761#if !HAVE_SETRLIMIT || !defined(RLIMIT_NOFILE)
763 debugs(0,
DBG_IMPORTANT,
"WARNING: max_filedescriptors disabled. Operating System setrlimit(RLIMIT_NOFILE) is missing.");
767 debugs(0,
DBG_IMPORTANT,
"WARNING: max_filedescriptors limited to " << FD_SETSIZE <<
" by select() algorithm.");
800 debugs(0,
DBG_CRITICAL,
"WARNING: connect_retries cannot be larger than 10. Resetting to 10.");
809 bool logDaemonUsed =
false;
811 logDaemonUsed =
log->usesDaemon();
814 logDaemonUsed =
log->usesDaemon();
830#if USE_HTTP_VIOLATIONS
839 debugs(22,
DBG_IMPORTANT,
"WARNING: use of 'override-expire' in 'refresh_pattern' violates HTTP");
848 debugs(22,
DBG_IMPORTANT,
"WARNING: use of 'override-lastmod' in 'refresh_pattern' violates HTTP");
857 debugs(22,
DBG_IMPORTANT,
"WARNING: use of 'reload-into-ims' in 'refresh_pattern' violates HTTP");
866 debugs(22,
DBG_IMPORTANT,
"WARNING: use of 'ignore-reload' in 'refresh_pattern' violates HTTP");
875 debugs(22,
DBG_IMPORTANT,
"WARNING: use of 'ignore-no-store' in 'refresh_pattern' violates HTTP");
884 debugs(22,
DBG_IMPORTANT,
"WARNING: use of 'ignore-private' in 'refresh_pattern' violates HTTP");
890#if !USE_HTTP_VIOLATIONS
903 if (geteuid() == 0) {
908 if (
nullptr == pwd) {
918 fatalf(
"getpwnam failed to find userid for effective user '%s'",
928 if (pwd->pw_dir && *pwd->pw_dir) {
931 if (lastDir.
isEmpty() || lastDir.
cmp(pwd->pw_dir) != 0) {
932 lastDir = pwd->pw_dir;
933 int len = strlen(pwd->pw_dir) + 6;
934 char *env_str = (
char *)
xcalloc(len, 1);
935 snprintf(env_str, len,
"HOME=%s", pwd->pw_dir);
950 if (
nullptr == grp) {
951 fatalf(
"getgrnam failed to find groupid for effective group '%s'",
965 debugs(3, 2,
"initializing https:// proxy context");
969 fatal(
"ERROR: Could not initialize https:// proxy context");
971 debugs(3,
DBG_IMPORTANT,
"ERROR: proxying https:// currently still requires --with-openssl");
982 if (p->secure.sslDomain.isEmpty())
983 p->secure.sslDomain = p->host;
985 if (p->secure.encryptTransport) {
986 debugs(3, 2,
"initializing TLS context for cache_peer " << *p);
987 p->sslContext = p->secure.createClientContext(
true);
988 if (!p->sslContext) {
989 debugs(3,
DBG_CRITICAL,
"ERROR: Could not initialize TLS context for cache_peer " << *p);
997 if (!s->secure.encryptTransport)
999 debugs(3, 2,
"initializing " <<
AnyP::UriScheme(s->transport.protocol) <<
"_port " << s->s <<
" TLS contexts");
1000 s->secure.initServerContexts(*s);
1006 fatalf(
"Client request buffer of %u bytes cannot hold a request with %u bytes of headers." \
1007 " Change client_request_buffer_max or request_header_max_size limits.",
1017 " requires client_persistent_connections ON. Forced pipeline_prefetch 0.");
1032 if ((nego && nego->
active()) || (ntlm && ntlm->
active())) {
1039 authSchemes.expand();
1040 if (authSchemes.authConfigs.empty()) {
1041 debugs(3,
DBG_CRITICAL,
"auth_schemes: at least one scheme name is required; got: " << authSchemes.rawSchemes);
1058 if (!strcmp(name,
"url_rewrite_concurrency")) {
1061 debugs(3,
DBG_CRITICAL,
"WARNING: url_rewrite_concurrency upgrade overriding url_rewrite_children settings.");
1065 if (!strcmp(name,
"log_access")) {
1070 if (!strcmp(name,
"log_icap")) {
1075 if (!strcmp(name,
"ignore_ims_on_miss")) {
1083 if (!strncmp(name,
"sslproxy_", 9)) {
1086 if (!strcmp(name,
"sslproxy_cafile"))
1088 else if (!strcmp(name,
"sslproxy_capath"))
1090 else if (!strcmp(name,
"sslproxy_cipher"))
1092 else if (!strcmp(name,
"sslproxy_client_certificate"))
1094 else if (!strcmp(name,
"sslproxy_client_key"))
1096 else if (!strcmp(name,
"sslproxy_flags"))
1098 else if (!strcmp(name,
"sslproxy_options"))
1100 else if (!strcmp(name,
"sslproxy_version"))
1110 tmp.
append(token, strlen(token));
1115template <
class MinimalUnit>
1119 const auto minUnit = MinimalUnit(1);
1120 if(minUnit == std::chrono::nanoseconds(1))
1122 else if (minUnit == std::chrono::microseconds(1))
1124 else if (minUnit == std::chrono::milliseconds(1))
1127 assert(minUnit >= std::chrono::seconds(1));
1137template <
class MinimalUnit>
1142 throw TexcHere(
"missing time unit");
1145 ns = std::chrono::nanoseconds(1);
1147 ns = std::chrono::microseconds(1);
1149 ns = std::chrono::milliseconds(1);
1151 ns = std::chrono::seconds(1);
1153 ns = std::chrono::minutes(1);
1155 ns = std::chrono::hours(1);
1157 ns = std::chrono::hours(24);
1159 ns = std::chrono::hours(24 * 7);
1161 ns = std::chrono::hours(24 * 14);
1163 ns = std::chrono::hours(24 * 30);
1165 ns = std::chrono::hours(
static_cast<std::chrono::hours::rep
>(
HoursPerYear));
1167 ns = std::chrono::hours(
static_cast<std::chrono::hours::rep
>(
HoursPerYear * 10));
1171 if (
ns < MinimalUnit(1)) {
1172 throw TexcHere(
ToSBuf(
"time unit '", unitName,
"' is too small to be used in this context, the minimal unit is ",
1173 TimeUnitToString<MinimalUnit>()));
1179static std::chrono::nanoseconds
1183 throw TexcHere(
"time must have a positive value");
1187 throw TexcHere(
ToSBuf(
"time values cannot exceed ", maxYears,
" years"));
1190 return std::chrono::duration_cast<std::chrono::nanoseconds>(unit * value);
1193template <
class TimeUnit>
1197 const auto result = std::chrono::duration_cast<TimeUnit>(
ns);
1198 if (!result.count()) {
1200 "' is too small to be used in this context, the minimal value is 1 ",
1201 TimeUnitToString<TimeUnit>()));
1208template <
class TimeUnit>
1214 throw TexcHere(
"cannot read a time value");
1216 const auto parsedValue =
xatof(valueToken);
1218 if (parsedValue == 0)
1219 return TimeUnit::zero();
1221 std::chrono::nanoseconds parsedUnitDuration;
1225 if (!parseTimeUnit<TimeUnit>(token, parsedUnitDuration))
1230 const auto nanoseconds =
ToNanoSeconds(parsedValue, parsedUnitDuration);
1233 if (TimeUnit(1) <= std::chrono::microseconds(1)) {
1234 if (0 < nanoseconds.count() && nanoseconds.count() < 3) {
1236 "Squid time measurement precision is likely to be far worse than " <<
1237 "the nanosecond-level precision implied by the configured value: " << parsedValue <<
' ' << token);
1241 return FromNanoseconds<TimeUnit>(nanoseconds, parsedValue);
1262 if (strcmp(token,
"none") == 0 || strcmp(token,
"-1") == 0) {
1276 d <<
" " << units );
1282 *bptr =
static_cast<int64_t
>(m * d / u);
1284 if (
static_cast<double>(*bptr) * 2 != (m * d / u) * 2) {
1286 d <<
" " << token <<
": integer overflow (int64_t).");
1309 if (strcmp(token,
"none") == 0 || strcmp(token,
"-1") == 0) {
1310 *bptr =
static_cast<size_t>(-1);
1323 d <<
" " << units );
1329 *bptr =
static_cast<size_t>(m * d / u);
1331 if (
static_cast<double>(*bptr) * 2 != (m * d / u) * 2) {
1333 d <<
" " << token <<
": integer overflow (size_t).");
1356 if (strcmp(token,
"none") == 0 || token[0] ==
'-' ) {
1370 d <<
" " << units );
1376 *bptr =
static_cast<ssize_t
>(m * d / u);
1378 if (
static_cast<double>(*bptr) * 2 != (m * d / u) * 2) {
1380 d <<
" " << token <<
": integer overflow (ssize_t).");
1400 char const * number_begin = value;
1401 char const * number_end = value;
1403 while ((*number_end >=
'0' && *number_end <=
'9')) {
1408 number.assign(number_begin, number_end - number_begin);
1417 *bptr =
static_cast<size_t>(m * d / u);
1418 if (
static_cast<double>(*bptr) * 2 != (m * d / u) * 2)
1446 list->push_back(
SBuf(token));
1453 for (
const auto &i : words) {
1454 entry->
append(i.rawContent(), i.length());
1464 if (!list.empty()) {
1465 entry->
append(name, strlen(name));
1481 while (ae !=
nullptr) {
1482 debugs(3, 3,
"dump_acl: " << name <<
" " << ae->
name);
1489 tail.splice(tail.end(), ae->
dump());
1551 if (!strcmp(token,
"any_addr"))
1553 else if ( (!strcmp(token,
"no_addr")) || (!strcmp(token,
"full_mask")) )
1555 else if ( (*addr = token) )
1560 debugs(3,
DBG_CRITICAL,
"FATAL: invalid IP address or domain name '" << token <<
"'");
1577 if (!l->addr.isAnyAddr())
1597 tail = &(*tail)->
next;
1642 const unsigned int chTos = tos & 0xFC;
1656 tail = &(*tail)->
next;
1668#if SO_MARK && USE_LIBCAP
1689 const auto pkt_dirs = {
"mark_client_packet",
"clientside_mark",
"tcp_outgoing_mark"};
1690 if (mc.hasMask() && std::find(pkt_dirs.begin(), pkt_dirs.end(),
cfg_directive) != pkt_dirs.end())
1700 tail = &(*tail)->
next;
1739 tail = &(*tail)->
next;
1758#define free_delay_pool_class(X)
1759#define free_delay_pool_access(X)
1760#define free_delay_pool_rates(X)
1761#define dump_delay_pool_class(X, Y, Z)
1762#define dump_delay_pool_access(X, Y, Z)
1763#define dump_delay_pool_rates(X, Y, Z)
1809#define free_client_delay_pool_access(X)
1810#define free_client_delay_pool_rates(X)
1811#define dump_client_delay_pool_access(X, Y, Z)
1812#define dump_client_delay_pool_rates(X, Y, Z)
1845#if USE_HTTP_VIOLATIONS
1870 std::string directive =
"http_header_access ";
1922 return s ==
nullptr;
1944 if (schemeCfg ==
nullptr) {
1948 if (theScheme ==
nullptr) {
1949 debugs(3,
DBG_CRITICAL,
"ERROR: Failure while parsing Config File: Unknown authentication scheme '" << type_str <<
"'.");
1954 config->push_back(theScheme->createConfig());
1956 if (schemeCfg ==
nullptr) {
1957 debugs(3,
DBG_CRITICAL,
"Parsing Config File: Corruption configuring authentication scheme '" << type_str <<
"'.");
1963 schemeCfg->
parse(schemeCfg, config->size(), param_str);
1981 for (
auto *scheme : cfg)
1982 scheme->dump(entry, name, scheme);
2011 return Auth::TheConfig.schemeLists.at(action.kind).rawSchemes;
2024 name.
Printf(
"(%s rules)", desc);
2028 name.
Printf(
"(%s rule)", desc);
2034 (*access)->add(rule,
action);
2047 const char * result;
2060 result =
"multicast";
2080 for (
const auto &peer: *peers) {
2081 const auto p = peer.get();
2092 snprintf(xname, 128,
"cache_peer_access %s", p->name);
2096 for (t = p->typelist; t; t = t->
next) {
2112 if (len < 1)
return false;
2114 for (; len >0 && *str; ++str, --len) {
2115 if (! isdigit(*str))
2125static unsigned short
2128 struct servent *
port =
nullptr;
2131 if (token ==
nullptr) {
2137 port = getservbyname(token, proto);
2138 if (
port !=
nullptr) {
2139 return ntohs((
unsigned short)
port->s_port);
2142 return xatos(token);
2149inline unsigned short
2159inline unsigned short
2185 p->options.no_digest =
true;
2186 p->options.no_netdb_exchange =
true;
2191 if (!p->http_port) {
2200 if (!strcmp(token,
"proxy-only")) {
2201 p->options.proxy_only =
true;
2202 }
else if (!strcmp(token,
"no-query")) {
2203 p->options.no_query =
true;
2204 }
else if (!strcmp(token,
"background-ping")) {
2205 p->options.background_ping =
true;
2206 }
else if (!strcmp(token,
"no-digest")) {
2207 p->options.no_digest =
true;
2208 }
else if (!strcmp(token,
"no-tproxy")) {
2209 p->options.no_tproxy =
true;
2210 }
else if (!strcmp(token,
"multicast-responder")) {
2211 p->options.mcast_responder =
true;
2212#if PEER_MULTICAST_SIBLINGS
2213 }
else if (!strcmp(token,
"multicast-siblings")) {
2214 p->options.mcast_siblings =
true;
2216 }
else if (!strncmp(token,
"weight=", 7)) {
2217 p->weight =
xatoi(token + 7);
2218 }
else if (!strncmp(token,
"basetime=", 9)) {
2219 p->basetime =
xatoi(token + 9);
2220 }
else if (!strcmp(token,
"closest-only")) {
2221 p->options.closest_only =
true;
2222 }
else if (!strncmp(token,
"ttl=", 4)) {
2223 p->mcast.ttl =
xatoi(token + 4);
2225 if (p->mcast.ttl < 0)
2228 if (p->mcast.ttl > 128)
2230 }
else if (!strcmp(token,
"default")) {
2231 p->options.default_parent =
true;
2232 }
else if (!strcmp(token,
"round-robin")) {
2233 p->options.roundrobin =
true;
2234 }
else if (!strcmp(token,
"weighted-round-robin")) {
2235 p->options.weighted_roundrobin =
true;
2237 }
else if (!strcmp(token,
"htcp")) {
2238 p->options.htcp =
true;
2239 }
else if (!strncmp(token,
"htcp=", 5) || !strncmp(token,
"htcp-", 5)) {
2241 p->options.htcp =
true;
2243 char *mode, *nextmode;
2244 for (mode = nextmode = tmp; mode; mode = nextmode) {
2245 nextmode = strchr(mode,
',');
2250 if (!strcmp(mode,
"no-clr")) {
2251 if (p->options.htcp_only_clr)
2252 fatalf(
"parse_peer: can't set htcp-no-clr and htcp-only-clr simultaneously");
2253 p->options.htcp_no_clr =
true;
2254 }
else if (!strcmp(mode,
"no-purge-clr")) {
2255 p->options.htcp_no_purge_clr =
true;
2256 }
else if (!strcmp(mode,
"only-clr")) {
2257 if (p->options.htcp_no_clr)
2258 fatalf(
"parse_peer: can't set htcp no-clr and only-clr simultaneously");
2259 p->options.htcp_only_clr =
true;
2260 }
else if (!strcmp(mode,
"forward-clr")) {
2261 p->options.htcp_forward_clr =
true;
2262 }
else if (!strcmp(mode,
"oldsquid")) {
2263 p->options.htcp_oldsquid =
true;
2265 fatalf(
"invalid HTCP mode '%s'", mode);
2270 }
else if (!strcmp(token,
"no-netdb-exchange")) {
2271 p->options.no_netdb_exchange =
true;
2273 }
else if (!strcmp(token,
"carp")) {
2277 p->options.carp =
true;
2278 }
else if (!strncmp(token,
"carp-key=", 9)) {
2279 if (p->options.carp !=
true)
2281 p->options.carp_key.set =
true;
2282 char *nextkey=token+strlen(
"carp-key="), *key=nextkey;
2283 for (; key; key = nextkey) {
2284 nextkey=strchr(key,
',');
2285 if (nextkey) ++nextkey;
2286 if (0==strncmp(key,
"scheme",6)) {
2287 p->options.carp_key.scheme =
true;
2288 }
else if (0==strncmp(key,
"host",4)) {
2289 p->options.carp_key.host =
true;
2290 }
else if (0==strncmp(key,
"port",4)) {
2291 p->options.carp_key.port =
true;
2292 }
else if (0==strncmp(key,
"path",4)) {
2293 p->options.carp_key.path =
true;
2294 }
else if (0==strncmp(key,
"params",6)) {
2295 p->options.carp_key.params =
true;
2297 fatalf(
"invalid carp-key '%s'",key);
2300 }
else if (!strcmp(token,
"userhash")) {
2305 p->options.userhash =
true;
2309 }
else if (!strcmp(token,
"sourcehash")) {
2313 p->options.sourcehash =
true;
2315 }
else if (!strcmp(token,
"no-delay")) {
2317 p->options.no_delay =
true;
2319 debugs(0,
DBG_CRITICAL,
"WARNING: cache_peer option 'no-delay' requires --enable-delay-pools");
2321 }
else if (!strncmp(token,
"login=", 6)) {
2322 p->login =
xstrdup(token + 6);
2324 }
else if (!strcmp(token,
"auth-no-keytab")) {
2325 p->options.auth_no_keytab = 1;
2326 }
else if (!strncmp(token,
"connect-timeout=", 16)) {
2327 p->connect_timeout_raw =
xatoi(token + 16);
2328 }
else if (!strncmp(token,
"connect-fail-limit=", 19)) {
2329 p->connect_fail_limit =
xatoi(token + 19);
2330#if USE_CACHE_DIGESTS
2331 }
else if (!strncmp(token,
"digest-url=", 11)) {
2332 p->digest_url =
xstrdup(token + 11);
2335 }
else if (!strcmp(token,
"allow-miss")) {
2336 p->options.allow_miss =
true;
2337 }
else if (!strncmp(token,
"max-conn=", 9)) {
2338 p->max_conn =
xatoi(token + 9);
2339 }
else if (!strncmp(token,
"standby=", 8)) {
2340 p->standby.limit =
xatoi(token + 8);
2341 }
else if (!strcmp(token,
"originserver")) {
2342 p->options.originserver =
true;
2343 }
else if (!strncmp(token,
"name=", 5)) {
2344 p->rename(token + 5);
2345 }
else if (!strncmp(token,
"forceddomain=", 13)) {
2348 p->domain =
xstrdup(token + 13);
2350 }
else if (strncmp(token,
"ssl", 3) == 0) {
2352 debugs(0,
DBG_CRITICAL,
"WARNING: cache_peer option '" << token <<
"' requires --with-openssl");
2354 p->secure.parse(token+3);
2356 }
else if (strncmp(token,
"tls-", 4) == 0) {
2357 p->secure.parse(token+4);
2358 }
else if (strncmp(token,
"tls", 3) == 0) {
2359 p->secure.parse(token+3);
2360 }
else if (strcmp(token,
"front-end-https") == 0) {
2361 p->front_end_https = 1;
2362 }
else if (strcmp(token,
"front-end-https=on") == 0) {
2363 p->front_end_https = 1;
2364 }
else if (strcmp(token,
"front-end-https=auto") == 0) {
2365 p->front_end_https = 2;
2366 }
else if (strcmp(token,
"connection-auth=off") == 0) {
2367 p->connection_auth = 0;
2368 }
else if (strcmp(token,
"connection-auth") == 0) {
2369 p->connection_auth = 1;
2370 }
else if (strcmp(token,
"connection-auth=on") == 0) {
2371 p->connection_auth = 1;
2372 }
else if (strcmp(token,
"connection-auth=auto") == 0) {
2373 p->connection_auth = 2;
2374 }
else if (token[0] ==
'#') {
2385 if (p->max_conn > 0 && p->max_conn < p->standby.limit)
2387 " is lower than its standby=", p->standby.limit),
Here());
2392 if (p->connect_fail_limit < 1)
2393 p->connect_fail_limit = 10;
2395#if USE_CACHE_DIGESTS
2396 if (!p->options.no_digest)
2400 if (p->secure.encryptTransport)
2401 p->secure.parseOptions();
2408 p->index = (*peers)->size();
2424 if (strcmp(list->
passwd,
"none") && strcmp(list->
passwd,
"disable"))
2440 char *passwd =
nullptr;
2450 for (P =
head; *P; P = &(*P)->
next) {
2459 for (
const auto &w : (*P)->actions) {
2460 for (
const auto &u : p->
actions) {
2482 while (var !=
nullptr) {
2485 for (
const auto &aclName: var->
acl_list)
2511 std::string directive =
"peer_access ";
2512 directive += p.
name;
2527 char *domain =
nullptr;
2534 for (L = &p.typelist; *L; L = &((*L)->next));
2594 if (!strcmp(token,
"on")) {
2596 }
else if (!strcmp(token,
"enable")) {
2599 }
else if (!strcmp(token,
"off")) {
2601 }
else if (!strcmp(token,
"disable")) {
2610#define free_onoff free_int
2636 if (!strcmp(token,
"on")) {
2638 }
else if (!strcmp(token,
"enable")) {
2641 }
else if (!strcmp(token,
"warn")) {
2643 }
else if (!strcmp(token,
"off")) {
2645 }
else if (!strcmp(token,
"disable")) {
2654#define free_tristate free_int
2665 if (!strcmp(token,
"on")) {
2670 }
else if (!strcmp(token,
"off")) {
2671 debugs(0,
DBG_PARSE_NOTE(2),
"WARNING: 'pipeline_prefetch off' is deprecated. Please update to use '0'.");
2679#define free_pipelinePrefetch free_int
2680#define dump_pipelinePrefetch dump_int
2685 while (
head !=
nullptr) {
2688 head->printHead(os);
2690 if (
head->max_stale >= 0)
2693 if (
head->flags.refresh_ims)
2696 if (
head->flags.store_stale)
2699#if USE_HTTP_VIOLATIONS
2701 if (
head->flags.override_expire)
2704 if (
head->flags.override_lastmod)
2707 if (
head->flags.reload_into_ims)
2710 if (
head->flags.ignore_reload)
2713 if (
head->flags.ignore_no_store)
2716 if (
head->flags.ignore_private)
2733 int refresh_ims = 0;
2734 int store_stale = 0;
2737#if USE_HTTP_VIOLATIONS
2739 int override_expire = 0;
2740 int override_lastmod = 0;
2741 int reload_into_ims = 0;
2742 int ignore_reload = 0;
2743 int ignore_no_store = 0;
2744 int ignore_private = 0;
2756 debugs(3,
DBG_IMPORTANT,
"WARNING: refresh_pattern minimum age negative. Cropped back to zero.");
2759 if (i > 60*24*365) {
2760 debugs(3,
DBG_IMPORTANT,
"WARNING: refresh_pattern minimum age too high. Cropped back to 1 year.");
2764 min = (time_t) (i * 60);
2772 debugs(3,
DBG_IMPORTANT,
"WARNING: refresh_pattern maximum age negative. Cropped back to zero.");
2775 if (i > 60*24*365) {
2776 debugs(3,
DBG_IMPORTANT,
"WARNING: refresh_pattern maximum age too high. Cropped back to 1 year.");
2780 max = (time_t) (i * 60);
2784 if (!strcmp(token,
"refresh-ims")) {
2786 }
else if (!strcmp(token,
"store-stale")) {
2788 }
else if (!strncmp(token,
"max-stale=", 10)) {
2789 max_stale =
xatoi(token + 10);
2791#if USE_HTTP_VIOLATIONS
2793 }
else if (!strcmp(token,
"override-expire"))
2794 override_expire = 1;
2795 else if (!strcmp(token,
"override-lastmod"))
2796 override_lastmod = 1;
2797 else if (!strcmp(token,
"ignore-no-store"))
2798 ignore_no_store = 1;
2799 else if (!strcmp(token,
"ignore-private"))
2801 else if (!strcmp(token,
"reload-into-ims")) {
2802 reload_into_ims = 1;
2805 }
else if (!strcmp(token,
"ignore-reload")) {
2811 }
else if (!strcmp(token,
"ignore-no-cache") ||
2812 !strcmp(token,
"ignore-must-revalidate") ||
2813 !strcmp(token,
"ignore-auth")
2815 debugs(22,
DBG_PARSE_NOTE(2),
"UPGRADE: refresh_pattern option '" << token <<
"' is obsolete. Remove it.");
2820 pct = pct < 0.0 ? 0.0 : pct;
2835#if USE_HTTP_VIOLATIONS
2837 if (override_expire)
2840 if (override_lastmod)
2843 if (reload_into_ims)
2849 if (ignore_no_store)
2870#if USE_HTTP_VIOLATIONS
2927 *var =
xstrdup((
char *) token);
2930#define dump_eol dump_string
2931#define free_eol free_string
2947#define dump_TokenOrQuotedString dump_string
2948#define free_TokenOrQuotedString free_string
2954 os << name <<
' ' << var <<
" seconds\n";
2961 const auto seconds = parseTimeLine<std::chrono::seconds>();
2962 if (maxTime < seconds.count())
2963 throw TexcHere(
ToSBuf(
"directive supports time values up to ", maxTime,
" but is given ", seconds.count(),
" seconds"));
2964 *var =
static_cast<time_t
>(seconds.count());
2978 os << name <<
' ' << var <<
" milliseconds\n";
2980 os << name <<
' ' << (var/1000) <<
" seconds\n";
2986 *var = parseTimeLine<std::chrono::milliseconds>().count();
2999 storeAppendPrintf(entry,
"%s %jd nanoseconds\n", name,
static_cast<intmax_t
>(var.count()));
3005 *var = parseTimeLine<std::chrono::nanoseconds>();
3011 *var = std::chrono::nanoseconds::zero();
3080#define free_b_size_t free_size_t
3081#define free_b_ssize_t free_ssize_t
3082#define free_kb_size_t free_size_t
3083#define free_mb_size_t free_size_t
3084#define free_gb_size_t free_size_t
3085#define free_kb_int64_t free_b_int64_t
3127 while (list !=
nullptr) {
3150 return a ==
nullptr;
3153#define free_wordlist wordlistDestroy
3155#define free_uri_whitespace free_int
3166 if (!strcmp(token,
"strip"))
3168 else if (!strcmp(token,
"deny"))
3170 else if (!strcmp(token,
"allow"))
3172 else if (!strcmp(token,
"encode"))
3174 else if (!strcmp(token,
"chop"))
3177 debugs(0,
DBG_PARSE_NOTE(2),
"ERROR: Invalid option '" << token <<
"': 'uri_whitespace' accepts 'strip', 'deny', 'allow', 'encode', and 'chop'.");
3213 *settings =
nullptr;
3234 args = settings->
args;
3276 if (strcmp(token,
"always") == 0) {
3279 }
else if (strcmp(token,
"disk") == 0) {
3282 }
else if (strncmp(token,
"net", 3) == 0) {
3285 }
else if (strcmp(token,
"never") == 0) {
3289 debugs(0,
DBG_PARSE_NOTE(2),
"ERROR: Invalid option '" << token <<
"': 'memory_cache_mode' accepts 'always', 'disk', 'network', and 'never'.");
3309#include "cf_parser.cci"
3314 if (!strcmp(s,
"parent"))
3317 if (!strcmp(s,
"neighbor"))
3320 if (!strcmp(s,
"neighbour"))
3323 if (!strcmp(s,
"sibling"))
3326 if (!strcmp(s,
"multicast"))
3395 char *host =
nullptr;
3396 unsigned short port = 0;
3398 char *junk =
nullptr;
3402 s->connection_auth_disabled =
false;
3406 if (*token ==
'[') {
3409 t = strchr(host,
']');
3411 debugs(3,
DBG_CRITICAL,
"FATAL: " << portType <<
"_port: missing ']' on IPv6 address: " << token);
3418 debugs(3,
DBG_CRITICAL,
"FATAL: " << portType <<
"_port: missing Port in: " << token);
3428 }
else if ((t = strchr(token,
':'))) {
3435 }
else if (strtol(token, &junk, 10) && !*junk) {
3437 debugs(3, 3, portType <<
"_port: found Listen on Port: " <<
port);
3444 if (
port == 0 && host !=
nullptr) {
3445 debugs(3,
DBG_CRITICAL,
"FATAL: " << portType <<
"_port: Port cannot be 0: " << token);
3450 if (
nullptr == host) {
3455 debugs(3, 3, portType <<
"_port: found Listen on wildcard address: *:" << s->s.port());
3456 }
else if ( (s->s = host) ) {
3460 debugs(3, 3, portType <<
"_port: Listen on Host/IP: " << host <<
" --> " << s->s);
3461 }
else if ( s->s.GetHostByName(host) ) {
3463 s->defaultsite =
xstrdup(host);
3467 debugs(3, 3, portType <<
"_port: found Listen as Host " << s->defaultsite <<
" on IP: " << s->s);
3469 debugs(3,
DBG_CRITICAL,
"FATAL: " << portType <<
"_port: failed to resolve Host/IP: " << host);
3482 if (value.
cmp(
"HTTP") == 0 || value.
cmp(
"HTTP/1.1") == 0)
3485 if (value.
cmp(
"HTTPS") == 0 || value.
cmp(
"HTTPS/1.1") == 0)
3488 if (value.
cmp(
"FTP") == 0)
3500 if (strcmp(token,
"accel") == 0) {
3501 if (s->flags.isIntercepted()) {
3506 s->flags.accelSurrogate =
true;
3508 }
else if (strcmp(token,
"transparent") == 0 || strcmp(token,
"intercept") == 0) {
3509 if (s->flags.accelSurrogate || s->flags.tproxyIntercept) {
3514 s->flags.natIntercept =
true;
3518 debugs(3,
DBG_IMPORTANT,
"Disabling Authentication on port " << s->s <<
" (interception enabled)");
3519 }
else if (strcmp(token,
"tproxy") == 0) {
3520 if (s->flags.natIntercept || s->flags.accelSurrogate) {
3525 s->flags.tproxyIntercept =
true;
3528 debugs(3,
DBG_IMPORTANT,
"Disabling Authentication on port " << s->s <<
" (TPROXY enabled)");
3530 if (s->flags.proxySurrogate) {
3531 debugs(3,
DBG_IMPORTANT,
"Disabling TPROXY Spoofing on port " << s->s <<
" (require-proxy-header enabled)");
3540 }
else if (strcmp(token,
"require-proxy-header") == 0) {
3541 s->flags.proxySurrogate =
true;
3542 if (s->flags.tproxyIntercept) {
3545 debugs(3,
DBG_IMPORTANT,
"Disabling TPROXY Spoofing on port " << s->s <<
" (require-proxy-header enabled)");
3548 }
else if (strncmp(token,
"defaultsite=", 12) == 0) {
3549 if (!s->flags.accelSurrogate) {
3555 s->defaultsite =
xstrdup(token + 12);
3556 }
else if (strcmp(token,
"vhost") == 0) {
3557 if (!s->flags.accelSurrogate) {
3560 s->flags.accelSurrogate =
true;
3562 }
else if (strcmp(token,
"no-vhost") == 0) {
3563 if (!s->flags.accelSurrogate) {
3567 }
else if (strcmp(token,
"vport") == 0) {
3568 if (!s->flags.accelSurrogate) {
3574 }
else if (strncmp(token,
"vport=", 6) == 0) {
3575 if (!s->flags.accelSurrogate) {
3580 s->vport =
xatos(token + 6);
3581 }
else if (strncmp(token,
"protocol=", 9) == 0) {
3582 if (!s->flags.accelSurrogate) {
3588 }
else if (strcmp(token,
"allow-direct") == 0) {
3589 if (!s->flags.accelSurrogate) {
3594 s->allow_direct =
true;
3595 }
else if (strcmp(token,
"act-as-origin") == 0) {
3596 if (!s->flags.accelSurrogate) {
3599 s->actAsOrigin =
true;
3600 }
else if (strcmp(token,
"ignore-cc") == 0) {
3601#if !USE_HTTP_VIOLATIONS
3602 if (!s->flags.accelSurrogate) {
3608 s->ignore_cc =
true;
3609 }
else if (strncmp(token,
"name=", 5) == 0) {
3612 }
else if (strcmp(token,
"no-connection-auth") == 0) {
3613 s->connection_auth_disabled =
true;
3614 }
else if (strcmp(token,
"connection-auth=off") == 0) {
3615 s->connection_auth_disabled =
true;
3616 }
else if (strcmp(token,
"connection-auth") == 0) {
3617 s->connection_auth_disabled =
false;
3618 }
else if (strcmp(token,
"connection-auth=on") == 0) {
3619 s->connection_auth_disabled =
false;
3620 }
else if (strncmp(token,
"disable-pmtu-discovery=", 23) == 0) {
3621 if (!strcmp(token + 23,
"off"))
3623 else if (!strcmp(token + 23,
"transparent"))
3625 else if (!strcmp(token + 23,
"always"))
3631 }
else if (strcmp(token,
"ipv4") == 0) {
3632 if ( !s->s.setIPv4() ) {
3637 }
else if (strcmp(token,
"tcpkeepalive") == 0) {
3638 s->tcp_keepalive.enabled =
true;
3639 }
else if (strncmp(token,
"tcpkeepalive=", 13) == 0) {
3640 char *t = token + 13;
3641 s->tcp_keepalive.enabled =
true;
3642 s->tcp_keepalive.idle =
xatoui(t,
',');
3646 s->tcp_keepalive.interval =
xatoui(t,
',');
3651 s->tcp_keepalive.timeout =
xatoui(t);
3654 }
else if (strcmp(token,
"sslBump") == 0) {
3657 s->flags.tunnelSslBumping =
true;
3658 }
else if (strcmp(token,
"ssl-bump") == 0) {
3659 s->flags.tunnelSslBumping =
true;
3660 }
else if (strncmp(token,
"cert=", 5) == 0) {
3661 s->secure.parse(token);
3662 }
else if (strncmp(token,
"key=", 4) == 0) {
3663 s->secure.parse(token);
3664 }
else if (strncmp(token,
"version=", 8) == 0) {
3667 s->secure.parse(token);
3668 }
else if (strncmp(token,
"options=", 8) == 0) {
3669 s->secure.parse(token);
3670 }
else if (strncmp(token,
"cipher=", 7) == 0) {
3671 s->secure.parse(token);
3672 }
else if (strncmp(token,
"clientca=", 9) == 0) {
3673 s->secure.parse(token);
3674 }
else if (strncmp(token,
"cafile=", 7) == 0) {
3677 s->secure.parse(token);
3678 }
else if (strncmp(token,
"capath=", 7) == 0) {
3679 s->secure.parse(token);
3680 }
else if (strncmp(token,
"crlfile=", 8) == 0) {
3681 s->secure.parse(token);
3682 }
else if (strncmp(token,
"dhparams=", 9) == 0) {
3685 s->secure.parse(token);
3686 }
else if (strncmp(token,
"sslflags=", 9) == 0) {
3688 s->secure.parse(token+3);
3689 }
else if (strncmp(token,
"sslcontext=", 11) == 0) {
3691 s->secure.parse(token+3);
3692 }
else if (strncmp(token,
"generate-host-certificates", 26) == 0) {
3693 s->secure.parse(token);
3695 }
else if (strncmp(token,
"dynamic_cert_mem_cache_size=", 28) == 0) {
3696 s->secure.parse(token);
3697 }
else if (strncmp(token,
"tls-", 4) == 0) {
3698 s->secure.parse(token+4);
3699 }
else if (strcmp(token,
"ftp-track-dirs") == 0) {
3700 s->ftp_track_dirs =
true;
3701 }
else if (strcmp(token,
"worker-queues") == 0) {
3702#if !defined(SO_REUSEADDR)
3703#error missing system #include that #defines SO_* constants
3705#if !defined(SO_REUSEPORT)
3706 throw TexcHere(
ToSBuf(
cfg_directive,
' ', token,
" option requires building Squid where SO_REUSEPORT is supported by the TCP stack"));
3708 s->workerQueues =
true;
3722 assert(s->next ==
nullptr);
3731 if (strcmp(optionName,
"http_port") == 0 ||
3732 strcmp(optionName,
"ascii_port") == 0)
3734 else if (strcmp(optionName,
"https_port") == 0)
3735 protoName =
"HTTPS";
3736 else if (strcmp(optionName,
"ftp_port") == 0)
3759 s->secure.syncCaFiles();
3762 s->secure.encryptTransport =
true;
3765 const bool hijacked = s->flags.isIntercepted();
3766 if (s->flags.tunnelSslBumping && !hijacked) {
3767 debugs(3,
DBG_CRITICAL,
"FATAL: ssl-bump on https_port requires tproxy/intercept which is missing.");
3771 if (hijacked && !s->flags.tunnelSslBumping) {
3772 debugs(3,
DBG_CRITICAL,
"FATAL: tproxy/intercept on https_port requires ssl-bump which is missing.");
3777 if (s->flags.proxySurrogate) {
3778 debugs(3,
DBG_CRITICAL,
"FATAL: https_port: require-proxy-header option is not supported on HTTPS ports.");
3782 }
else if (protoName.
cmp(
"FTP") == 0) {
3784 if (s->flags.tunnelSslBumping) {
3789 if (s->flags.proxySurrogate) {
3791 debugs(3,
DBG_CRITICAL,
"FATAL: require-proxy-header option is not supported on ftp_port.");
3797 if (s->secure.encryptTransport) {
3798 if (s->secure.certs.empty()) {
3803 s->secure.parseOptions();
3808 s->next = s->ipV4clone();
3811 while (*
head !=
nullptr)
3812 head = &((*head)->next);
3827 if (s->flags.natIntercept)
3830 else if (s->flags.tproxyIntercept)
3833 else if (s->flags.proxySurrogate)
3836 else if (s->flags.accelSurrogate) {
3844 else if (s->vport > 0)
3854 if (s->allow_direct)
3867#if USE_HTTP_VIOLATIONS
3868 if (!s->flags.accelSurrogate && s->ignore_cc)
3872 if (s->connection_auth_disabled)
3883 pmtu =
"transparent";
3888 if (s->s.isAnyAddr() && !s->s.isIPv6())
3891 if (s->tcp_keepalive.enabled) {
3892 if (s->tcp_keepalive.idle || s->tcp_keepalive.interval || s->tcp_keepalive.timeout) {
3893 storeAppendPrintf(e,
" tcpkeepalive=%d,%d,%d", s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout);
3900 if (s->flags.tunnelSslBumping)
3905 s->secure.dumpCfg(os,
"tls-");
3941 if (stat(path, &
sb) < 0) {
3988 cl->filename =
xstrdup(filename);
3990 if (strcmp(filename,
"none") == 0) {
3994 logs = &(*logs)->
next;
4000 if (token && !strchr(token,
'=')) {
4003 cl->setLogformat(token);
4007 cl->setLogformat(
"squid");
4019 logs = &(*logs)->
next;
4027 return customlog_definitions ==
nullptr;
4038 os <<
' ' <<
log->filename;
4039 log->dumpOptions(os);
4052 while (*definitions) {
4054 *definitions =
log->next;
4059#if HAVE_CPU_AFFINITY
4062parseNamedIntList(
const char *data,
const String &name, std::vector<int> &list)
4064 if (data && (strncmp(data, name.
rawBuf(), name.
size()) == 0)) {
4065 data += name.
size();
4072 list.push_back(value);
4073 if (*data ==
'\0' || *data !=
',')
4078 return data && *data ==
'\0';
4085#if !HAVE_CPU_AFFINITY
4086 (void)cpuAffinityMap;
4088 "support, do not set 'cpu_affinity_map'");
4092 if (!*cpuAffinityMap)
4097 std::vector<int> processes, cores;
4098 if (!parseNamedIntList(pToken,
"process_numbers", processes)) {
4100 "in 'cpu_affinity_map'");
4102 }
else if (!parseNamedIntList(cToken,
"cores", cores)) {
4104 "'cpu_affinity_map'");
4106 }
else if (!(*cpuAffinityMap)->add(processes, cores)) {
4108 "process_numbers and cores lists differ in length or " <<
4109 "contain numbers <= 0");
4118 if (cpuAffinityMap) {
4120 for (
size_t i = 0; i < cpuAffinityMap->
processes().
size(); ++i) {
4125 for (
size_t i = 0; i < cpuAffinityMap->
cores().
size(); ++i) {
4127 cpuAffinityMap->
cores()[i]);
4136 delete *cpuAffinityMap;
4137 *cpuAffinityMap =
nullptr;
4185 "Use 'adaptation_service_set' instead");
4193 "Use 'adaptation_access' instead");
4230 if (strcmp(token,
"in") != 0) {
4265 if (
char *s = strchr(al,
'{')) {
4288 if (strlen(param) > 64) {
4289 debugs(3,
DBG_CRITICAL,
"FATAL: sslproxy_cert_adapt: setCommonName{" <<param <<
"} : using common name longer than 64 bytes is not supported");
4296 debugs(3,
DBG_CRITICAL,
"FATAL: sslproxy_cert_adapt: unknown cert adaptation algorithm: " << al);
4304 cert_adapt = &(*cert_adapt)->
next;
4306 *cert_adapt = ca.release();
4311 for (
const auto *ca = cert_adapt; ca; ca = ca->
next) {
4323 *cert_adapt =
nullptr;
4342 debugs(3,
DBG_CRITICAL,
"FATAL: sslproxy_cert_sign: unknown cert signing algorithm: " << al);
4350 cert_sign = &(*cert_sign)->
next;
4352 *cert_sign = cs.release();
4357 for (
const auto *cs = cert_sign; cs; cs = cs->
next) {
4369 *cert_sign =
nullptr;
4389 static char buf[1024];
4391 strcpy(buf,
"ssl_bump deny all");
4393 "\"ssl_bump deny all\" to \"ssl_bump none all\". New ssl_bump configurations "
4394 "must not use implicit rules. Update your ssl_bump rules.");
4396 strcpy(buf,
"ssl_bump allow all");
4398 "\"ssl_bump allow all\" to \"ssl_bump client-first all\" which is usually "
4399 "inferior to the newer server-first bumping mode. New ssl_bump"
4400 " configurations must not use implicit rules. Update your ssl_bump rules.");
4408 typedef const char *BumpCfgStyle;
4409 BumpCfgStyle bcsNone =
nullptr;
4410 BumpCfgStyle bcsNew =
"new client/server-first/none";
4411 BumpCfgStyle bcsOld =
"deprecated allow/deny";
4412 static BumpCfgStyle bumpCfgStyleLast = bcsNone;
4413 BumpCfgStyle bumpCfgStyleNow = bcsNone;
4421 if (*ssl_bump ==
nullptr) {
4422 bumpCfgStyleLast = bcsNone;
4430 bumpCfgStyleNow = bcsNew;
4433 bumpCfgStyleNow = bcsNew;
4436 bumpCfgStyleNow = bcsNew;
4439 bumpCfgStyleNow = bcsNew;
4442 bumpCfgStyleNow = bcsNew;
4445 bumpCfgStyleNow = bcsNew;
4448 bumpCfgStyleNow = bcsNew;
4451 bumpCfgStyleNow = bcsNew;
4452 }
else if (strcmp(bm,
"allow") == 0) {
4454 "\"ssl_bump allow <acl>\" to \"ssl_bump client-first <acl>\" which "
4455 "is usually inferior to the newer server-first "
4456 "bumping mode. Update your ssl_bump rules.");
4458 bumpCfgStyleNow = bcsOld;
4460 }
else if (strcmp(bm,
"deny") == 0) {
4462 "\"ssl_bump deny <acl>\" to \"ssl_bump none <acl>\". Update "
4463 "your ssl_bump rules.");
4465 bumpCfgStyleNow = bcsOld;
4473 if (bumpCfgStyleLast != bcsNone && bumpCfgStyleNow != bumpCfgStyleLast) {
4474 debugs(3,
DBG_CRITICAL,
"FATAL: do not mix " << bumpCfgStyleNow <<
" actions with " <<
4475 bumpCfgStyleLast <<
" actions. Update your ssl_bump rules.");
4480 bumpCfgStyleLast = bumpCfgStyleNow;
4490 return Ssl::BumpModeStr.at(action.kind);
4506 for (HeaderWithAclList::iterator hwa = headers->begin(); hwa != headers->end(); ++hwa) {
4507 storeAppendPrintf(entry,
"%s %s %s", name, hwa->fieldName.c_str(), hwa->fieldValue.c_str());
4545 (*headers)->push_back(hwa);
4553 for (HeaderWithAclList::iterator hwa = (*header)->begin(); hwa != (*header)->end(); ++hwa) {
4557 if (hwa->valueFormat) {
4558 delete hwa->valueFormat;
4559 hwa->valueFormat =
nullptr;
4574 notes.
dump(entry, name);
4584 const auto id =
xatoui(value, eov);
4596 char *key =
nullptr;
4597 char *value =
nullptr;
4599 if (strcmp(key,
"id") == 0) {
4603 }
else if (strcmp(key,
"ids") == 0) {
4606 const auto dash = strchr(value,
'-');
4613 }
else if (strcmp(key,
"level") == 0) {
4616 const auto level =
xatoi(value);
4620 }
else if (strcmp(key,
"limit") == 0) {
4627 key = value =
nullptr;
4634 throw TextException(
"cache_log_message is missing a required id=... or ids=... option",
Here());
4637 throw TextException(
"cache_log_message is missing a required level=... or limit=... option",
Here());
4640 if (!*debugMessages)
4643 for (
auto id = minId;
id <= maxId; ++id) {
4645 (*debugMessages)->messages.at(
id) = msg;
4655 for (
const auto &msg: debugMessages->
messages) {
4656 if (!msg.configured())
4658 out << name <<
" id=" << msg.id;
4660 out <<
" level=" << msg.level;
4662 out <<
" limit=" << msg.limit;
4665 const auto buf = out.
buf();
4666 entry->
append(buf.rawContent(), buf.length());
4673 delete *debugMessages;
4674 *debugMessages =
nullptr;
4681 bool ftpEpsvIsDeprecatedRule =
false;
4689 if (!strcmp(t,
"off")) {
4691 ftpEpsvIsDeprecatedRule =
true;
4693 }
else if (!strcmp(t,
"on")) {
4695 ftpEpsvIsDeprecatedRule =
true;
4705 debugs(3,
DBG_CRITICAL,
"FATAL: do not mix \"ftp_epsv on|off\" cfg lines with \"ftp_epsv allow|deny ...\" cfg lines. Update your ftp_epsv rules.");
4710 if (ftpEpsvIsDeprecatedRule) {
4713 *ftp_epsv =
nullptr;
4743static std::chrono::seconds
4747 if (!timeValueToken)
4748 throw TexcHere(
"cannot read a time value");
4750 using Seconds = std::chrono::seconds;
4752 const auto parsedTimeValue =
xatof(timeValueToken);
4754 if (parsedTimeValue == 0)
4755 return std::chrono::seconds::zero();
4757 std::chrono::nanoseconds parsedUnitDuration;
4760 if (parseTimeUnit<Seconds>(unitToken, parsedUnitDuration))
4763 const auto defaultParsed = parseTimeUnit<Seconds>(
T_SECOND_STR, parsedUnitDuration);
4766 ": WARNING: missing time unit, using deprecated default '" <<
T_SECOND_STR <<
"'");
4769 const auto nanoseconds =
ToNanoSeconds(parsedTimeValue, parsedUnitDuration);
4771 return FromNanoseconds<Seconds>(nanoseconds, parsedTimeValue);
4783 if (strcasecmp(key,
"on_timeout") == 0) {
4784 if (strcasecmp(value,
"bypass") == 0)
4786 else if (strcasecmp(value,
"fail") == 0)
4788 else if (strcasecmp(value,
"retry") == 0)
4790 else if (strcasecmp(value,
"use_configured_response") == 0) {
4797 }
else if (strcasecmp(key,
"response") == 0) {
4807 debugs(3,
DBG_CRITICAL,
"FATAL: Expected 'response=' option after 'on_timeout=use_configured_response' option");
4812 debugs(3,
DBG_CRITICAL,
"FATAL: 'response=' option is valid only when used with the 'on_timeout=use_configured_response' option");
4820 const char *onTimedOutActions[] = {
"bypass",
"fail",
"retry",
"use_configured_response"};
4880 if (strcmp(tm,
"tunnel") == 0)
4882 else if (strcmp(tm,
"respond") == 0)
4897 static const std::vector<const char *> onErrorTunnelMode = {
4904 return onErrorTunnelMode.at(
action.kind);
4920 auto &protoGuards = *protoGuardsPtr;
4932 const SBuf name(rawName);
4935 line.push_back(name);
4936 line.push_back(proto);
4938 line.insert(line.end(), acld.begin(), acld.end());
4947 auto &protoGuards = *protoGuardsPtr;
4949 protoGuards =
nullptr;
const CachePeers & CurrentCachePeers()
#define Here()
source code location of the caller
SBuf TheKidName
current Squid process name (e.g., "squid-coord")
unsigned int xatoui(const char *token, char eov)
double GetPercentage(bool limit)
bool GetHostWithPort(char *token, Ip::Address *ipa)
uint64_t xatoull(const char *token, int base, char eov)
double xatof(const char *token)
unsigned short xatos(const char *token)
bool StringToInt(const char *s, int &result, const char **p, int base)
int64_t GetInteger64(void)
unsigned short GetShort(void)
int xatoi(const char *token)
AnyP::PortCfgPointer HttpPortList
list of Squid http(s)_port configured
SBuf ToUpper(SBuf buf)
Returns a lower-cased copy of its parameter.
#define SQUIDSBUFPRINT(s)
class SquidConfig2 Config2
char * strwordtok(char *buf, char **t)
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
void aclParseAccessLine(const char *directive, ConfigParser &, acl_access **treep)
size_t aclParseAclList(ConfigParser &, Acl::Tree **treep, const char *label)
void log(char *format,...)
squidaio_request_t * head
static DebugMessageId ParseDebugMessageId(const char *value, const char eov)
static std::chrono::nanoseconds ToNanoSeconds(const double value, const std::chrono::nanoseconds &unit)
static void SetConfigFilename(char const *file_name, bool is_pipe)
void parse_time_t(time_t *var)
static void dump_sslproxy_ssl_bump(StoreEntry *entry, const char *name, acl_access *ssl_bump)
static void free_authparam(Auth::ConfigVector *cfg)
static void dump_cachemgrpasswd(StoreEntry *entry, const char *name, Mgr::ActionPasswordList *list)
static void parse_address(Ip::Address *addr)
static void free_icap_service_failure_limit(Adaptation::Icap::Config *)
static const char *const T_SECOND_STR
static void ReplaceSubstr(char *&str, int &len, unsigned substrIdx, unsigned substrLen, const char *newSubstr)
static void parse_b_size_t(size_t *var)
static int parseOneConfigFile(const char *file_name, unsigned int depth)
static void parse_icap_service_failure_limit(Adaptation::Icap::Config *)
static void free_b_int64_t(int64_t *var)
static void free_int64_t(int64_t *var)
static void free_refreshpattern(RefreshPattern **head)
static void parse_authparam(Auth::ConfigVector *config)
static void dump_SBufList(StoreEntry *entry, const SBufList &words)
static void free_time_nanoseconds(std::chrono::nanoseconds *var)
void free_YesNoNone(YesNoNone *)
static void free_HeaderManglers(HeaderManglers **pm)
static void dump_note(StoreEntry *, const char *, Notes &)
int parseConfigFile(const char *file_name)
static void free_delay_pool_count(DelayConfig *cfg)
void configFreeMemory(void)
static void free_memcachemode(SquidConfig *)
static void free_time_msec(time_msec_t *var)
static void parse_b_ssize_t(ssize_t *var)
static void dump_cache_log_message(StoreEntry *entry, const char *name, const DebugMessages *messages)
static void free_time_t(time_t *var)
static void dump_configuration_includes_quoted_values(StoreEntry *const entry, const char *const name, bool recognizeQuotedValues)
static void parse_client_delay_pool_count(ClientDelayConfig *cfg)
static void parse_adaptation_service_set_type()
static void parse_ftp_epsv(acl_access **ftp_epsv)
static void parse_string(char **)
static const char *const T_MONTH_STR
static void parse_port_option(AnyP::PortCfgPointer &s, char *token)
static void ParseAclWithAction(acl_access **access, const Acl::Answer &action, const char *desc, ACL *acl=nullptr)
static void dump_removalpolicy(StoreEntry *entry, const char *name, RemovalPolicySettings *settings)
static const char *const B_MBYTES_STR
static void parse_acl_access(acl_access **head)
static void free_http_upgrade_request_protocols(HttpUpgradeProtocolAccess **protoGuards)
static void free_AuthSchemes(acl_access **authSchemes)
static void free_ecap_service_type(Adaptation::Ecap::Config *)
static void dump_AuthSchemes(StoreEntry *entry, const char *name, acl_access *authSchemes)
static void free_client_delay_pool_count(ClientDelayConfig *cfg)
static void parse_adaptation_access_type()
static void dump_PortCfg(StoreEntry *, const char *, const AnyP::PortCfgPointer &)
static void dump_ecap_service_type(StoreEntry *, const char *, const Adaptation::Ecap::Config &)
static const char *const T_WEEK_STR
static void dump_delay_pool_count(StoreEntry *entry, const char *name, DelayConfig &cfg)
static void dump_b_ssize_t(StoreEntry *entry, const char *name, ssize_t var)
static int parse_line(char *)
static void defaults_postscriptum(void)
static void parse_configuration_includes_quoted_values(bool *recognizeQuotedValues)
static void free_SBufList(SBufList *list)
static void parse_adaptation_service_chain_type()
static void SubstituteMacro(char *&line, int &len, const char *macroName, const char *substStr)
static void dump_refreshpattern(StoreEntry *entry, const char *name, RefreshPattern *head)
static void parse_icap_service_type(Adaptation::Icap::Config *)
static void parse_time_msec(time_msec_t *var)
static void free_removalpolicy(RemovalPolicySettings **settings)
void parse_onoff(int *var)
static void parse_obsolete(const char *)
static void dump_b_size_t(StoreEntry *entry, const char *name, size_t var)
static void dump_client_delay_pool_count(StoreEntry *entry, const char *name, ClientDelayConfig &cfg)
static void ProcessMacros(char *&line, int &len)
static AnyP::ProtocolVersion parsePortProtocol(const SBuf &value)
static void dump_time_t(StoreEntry *entry, const char *name, time_t var)
static void free_size_t(size_t *var)