37#if HAVE_SYS_CAPABILITY_H
38#include <sys/capability.h>
44#include <sys/procctl.h>
63The Squid Cache (version %s) died.\n\
65You've encountered a fatal error in the Squid Cache version %s.\n\
66If a core file was created (possibly in the swap directory),\n\
67please execute 'gdb squid core' or 'dbx squid core', then type 'where',\n\
68and report the trace back to squid-bugs@lists.squid-cache.org.\n\
119 static char command[256];
128 const mode_t prev_umask=umask(S_IXUSR|S_IXGRP|S_IWGRP|S_IWOTH|S_IXOTH);
131 char filename[] =
"/tmp/squid-XXXXXX";
132 int tfd = mkstemp(filename);
133 if (tfd < 0 || (fp = fdopen(tfd,
"w")) ==
nullptr) {
142 (fp = fopen(filename,
"w")) ==
NULL) {
155 fprintf(fp,
"Subject: %s\n",
dead_msg());
159 if (system(command)) {}
169#if HAVE_MSTATS && HAVE_GNUMALLOC_H
171 struct mstats ms = mstats();
172 fprintf(
DebugStream(),
"\ttotal space in arena: %6d KB\n",
173 (
int) (ms.bytes_total >> 10));
174 fprintf(
DebugStream(),
"\tTotal free: %6d KB %d%%\n",
175 (
int) (ms.bytes_free >> 10),
183 memset(r,
'\0',
sizeof(
struct rusage));
184#if HAVE_GETRUSAGE && defined(RUSAGE_SELF)
190 getrusage(RUSAGE_SELF, r);
196#elif defined(PSAPI_VERSION)
198 if (WIN32_OS_version >= _WIN_OS_WINNT) {
202 PROCESS_MEMORY_COUNTERS pmc;
203 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
205 FALSE, GetCurrentProcessId());
209 FILETIME ftCreate, ftExit, ftKernel, ftUser;
210 if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
211 int64_t *ptUser = (int64_t *)&ftUser;
212 int64_t tUser64 = *ptUser / 10;
213 int64_t *ptKernel = (int64_t *)&ftKernel;
214 int64_t tKernel64 = *ptKernel / 10;
215 r->
ru_utime.tv_sec =(long)(tUser64 / 1000000);
216 r->
ru_stime.tv_sec =(long)(tKernel64 / 1000000);
217 r->
ru_utime.tv_usec =(long)(tUser64 % 1000000);
218 r->
ru_stime.tv_usec =(long)(tKernel64 % 1000000);
220 CloseHandle( hProcess );
224 if (GetProcessMemoryInfo( hProcess, &pmc,
sizeof(pmc))) {
225 r->
ru_maxrss=(DWORD)(pmc.WorkingSetSize / getpagesize());
228 CloseHandle( hProcess );
232 CloseHandle( hProcess );
241 return (
double) r->
ru_stime.tv_sec +
243 (
double) r->
ru_stime.tv_usec / 1000000.0 +
248#ifndef HAVE_GETPAGESIZE
249#define HAVE_GETPAGESIZE 0
256#if _SQUID_OSF_ || _SQUID_AIX_ || defined(BSD4_4)
258#elif defined(HAVE_GETPAGESIZE) && HAVE_GETPAGESIZE != 0
260 return (r->
ru_maxrss * getpagesize()) >> 10;
261#elif defined(PAGESIZE)
283 const auto handleError = [](
const char *
const syscall,
const int savedErrno) {
286#if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
287 if (prctl(PR_SET_DUMPABLE, 1) != 0)
288 handleError(
"prctl(PR_SET_DUMPABLE)", errno);
289#elif HAVE_PROCCTL && defined(PROC_TRACE_CTL)
292 int traceable = PROC_TRACE_CTL_ENABLE;
293 if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &traceable) != 0)
294 handleError(
"procctl(PROC_TRACE_CTL_ENABLE)", errno);
296 if (setpflags(__PROC_PROTECT, 0) != 0)
297 handleError(
"setpflags(__PROC_PROTECT)", errno);
299 debugs(50, 2,
"WARNING: Assuming this process is traceable");
327 fprintf(
DebugStream(),
"CPU Usage: %.3f seconds = %.3f user + %.3f sys\n",
331 fprintf(
DebugStream(),
"Maximum Resident Size: %d KB\n",
333 fprintf(
DebugStream(),
"Page faults with physical i/o: %d\n",
342 else if (sig == SIGBUS)
350 extern void U_STACK_TRACE(
void);
357#if _SQUID_SOLARIS_ && HAVE_LIBOPCOM_STACK
359 extern void opcom_stack_trace(
void);
367#if HAVE_BACKTRACE_SYMBOLS_FD
369 static void *callarray[8192];
371 n = backtrace(callarray, 8192);
372 backtrace_symbols_fd(callarray, n, fileno(
DebugStream()));
378#if SA_RESETHAND == 0 && !_SQUID_WINDOWS_
379 signal(SIGSEGV, SIG_DFL);
381 signal(SIGBUS, SIG_DFL);
383 signal(sig, SIG_DFL);
418 kill(kid.getPid(), sig);
428 static int state = 0;
463 static int present = 0;
464 struct addrinfo *AI =
nullptr;
486 if (getnameinfo(AI->ai_addr, AI->ai_addrlen, host,
SQUIDHOSTNAMELEN,
nullptr, 0, NI_NAMEREQD ) == 0) {
489 debugs(50, 4,
"getMyHostname: resolved " << sa <<
" to '" << host <<
"'");
495 if (strchr(host,
'.'))
500 debugs(50, 2,
"WARNING: failed to resolve " << sa <<
" to a fully qualified hostname");
509 struct addrinfo hints;
510 memset(&hints, 0,
sizeof(addrinfo));
511 hints.ai_flags = AI_CANONNAME;
513 if (getaddrinfo(host,
nullptr,
nullptr, &AI) == 0) {
516 debugs(50, 6,
"getMyHostname: '" << host <<
"' has DNS resolution.");
533 debugs(50,
DBG_CRITICAL,
"WARNING: Could not determine this machines public hostname. " <<
534 "Please configure one or set 'visible_hostname'.");
536 return (
"localhost");
554 debugs(21, 3,
"leave_suid: PID " << getpid() <<
" called");
592 const auto xerrno = errno;
598 const auto xerrno = errno;
604 const auto xerrno = errno;
618 debugs(21, 3,
"enter_suid: PID " << getpid() <<
" taking root privileges");
620 if (setresuid((uid_t)-1, 0, (uid_t)-1) < 0) {
621 const auto xerrno = errno;
622 debugs (21, 3,
"enter_suid: setresuid failed: " <<
xstrerr(xerrno));
627 const auto xerrno = errno;
644 debugs(21, 3,
"no_suid: PID " << getpid() <<
" giving up root privileges forever");
651 if (setuid(uid) < 0) {
738 roles.
append(
" coordinator");
749#define RLIMIT_NOFILE RLIMIT_OFILE
757#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE)
762#if defined(getrlimit)
768 auto checkLimits =
true;
770 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
777 rl.rlim_cur = FD_SETSIZE;
782 if (rl.rlim_cur > rl.rlim_max)
783 rl.rlim_max = rl.rlim_cur;
784 if (setrlimit(RLIMIT_NOFILE, &rl)) {
787 getrlimit(RLIMIT_NOFILE, &rl);
788 rl.rlim_cur = rl.rlim_max;
789 if (setrlimit(RLIMIT_NOFILE, &rl)) {
799 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
809 const auto defaultCapForMaximumNumberOfFiles = rlim_t(100*1024);
814 if (checkLimits && rl.rlim_cur > defaultCapForMaximumNumberOfFiles) {
815 debugs(50,
DBG_IMPORTANT,
"WARNING: OS-provided soft limit (" << rl.rlim_cur <<
" RLIMIT_NOFILE) " <<
816 "is too big to use for calculating the maximum number of descriptors Squid may use; " <<
817 "setting that maximum to " << defaultCapForMaximumNumberOfFiles);
820 debugs(50, 3,
"Squid_MaxFD was " <<
Squid_MaxFD <<
"; now " << rl.rlim_cur <<
" <= " << rl.rlim_max);
835#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !_SQUID_CYGWIN_
841#if defined(getrlimit)
847 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
852 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
860#if HAVE_SETRLIMIT && defined(RLIMIT_DATA) && !_SQUID_CYGWIN_
861 if (getrlimit(RLIMIT_DATA, &rl) < 0) {
864 }
else if (rl.rlim_max > rl.rlim_cur) {
865 rl.rlim_cur = rl.rlim_max;
867 if (setrlimit(RLIMIT_DATA, &rl) < 0) {
878#if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) && !_SQUID_CYGWIN_
879 if (getrlimit(RLIMIT_VMEM, &rl) < 0) {
882 }
else if (rl.rlim_max > rl.rlim_cur) {
883 rl.rlim_cur = rl.rlim_max;
885 if (setrlimit(RLIMIT_VMEM, &rl) < 0) {
900 sa.sa_handler = func;
902 sigemptyset(&sa.sa_mask);
904 if (sigaction(sig, &sa,
nullptr) < 0) {
932 WIN32_ExceptionHandlerInit();
936 WIN32_ExceptionHandlerInit();
962 assert(label && obj && pm);
966 debugs(section, level,
"" << label <<
"" << mb.
buf <<
"");
993 setmode(fileno(fp),
O_TEXT);
996 while (fgets(buf, 1024, fp)) {
1007 debugs(1, 5,
"etc_hosts: line is '" << buf <<
"'");
1016 debugs(1, 5,
"etc_hosts: address is '" << addr <<
"'");
1022 while ((nt = strpbrk(lt,
w_space))) {
1023 char *host =
nullptr;
1026 debugs(1, 5,
"etc_hosts: multiple spaces, skipping");
1032 debugs(1, 5,
"etc_hosts: got hostname '" << lt <<
"'");
1037 strncpy(buf2, lt,
sizeof(buf2)-1);
1039 buf2[
sizeof(buf2)-1] =
'\0';
1050 hosts.emplace_back(
SBuf(host));
1068 while (p !=
nullptr && p->flags.isIntercepted())
1076 while (p !=
nullptr && p->flags.isIntercepted())
1094 static const mode_t orig_umask = umask(mask);
1095 umask(mask | orig_umask);
1106 if (strchr(str,
' ')) {
1112 const auto l = strcspn(str,
"\"\\\n\r");
1146#if HAVE_LIBCAP && HAVE_PRCTL && defined(PR_SET_KEEPCAPS)
1147 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
1148 Ip::Interceptor.StopTransparency(
"capability setting has failed.");
1159 caps = cap_get_proc();
1163 Ip::Interceptor.StopTransparency(
"Can't get current capabilities");
1167 cap_value_t cap_list[10];
1168 cap_list[ncaps] = CAP_NET_BIND_SERVICE;
1170 if (Ip::Interceptor.TransparentActive() ||
1173 Ip::Interceptor.InterceptActive() ||
1178 cap_list[ncaps] = CAP_NET_ADMIN;
1182 cap_clear_flag(caps, CAP_EFFECTIVE);
1183 rc |= cap_set_flag(caps, CAP_EFFECTIVE, ncaps, cap_list, CAP_SET);
1184 rc |= cap_set_flag(caps, CAP_PERMITTED, ncaps, cap_list, CAP_SET);
1186 if (rc || cap_set_proc(caps) != 0) {
1187 Ip::Interceptor.StopTransparency(
"Error enabling needed capabilities.");
1193 Ip::Interceptor.StopTransparency(
"Missing needed capability support.");
1207 return waitpid(
pid, &status, flags);
1211#if _SQUID_WINDOWS_ || _SQUID_MINGW_
1213WindowsErrorMessage(DWORD errorId)
1215 char *rawMessage =
nullptr;
1216 const auto length = FormatMessage(
1217 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1218 FORMAT_MESSAGE_FROM_SYSTEM |
1219 FORMAT_MESSAGE_IGNORE_INSERTS,
1222 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1223 static_cast<LPTSTR
>(&rawMessage),
1228 return ToSBuf(
"windows error ", errorId);
1230 const auto result =
SBuf(rawMessage, length);
1231 LocalFree(rawMessage);
int storeDirWriteCleanLogs(int reopen)
#define Here()
source code location of the caller
int TheProcessKind
ProcessKind for the current process.
@ pkWorker
general-purpose worker bee
@ pkCoordinator
manages all other kids
@ pkDisker
cache_dir manager
Kids TheKids
All kids being maintained.
AnyP::PortCfgPointer FtpPortList
list of Squid ftp_port configured
AnyP::PortCfgPointer HttpPortList
list of Squid http(s)_port configured
class SquidConfig2 Config2
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
#define USE_LIBNETFILTERCONNTRACK
static void parseOptions(char const *)
static void PrepareToDie()
static std::ostream & Extra(std::ostream &)
static char * debugOptions
static void FreeAddr(struct addrinfo *&ai)
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
size_t count() const
returns the number of kids
Kid & get(size_t i)
returns the kid by index, useful for kids iteration
void append(const char *c, int sz) override
void init(mb_size_t szInit, mb_size_t szMax)
SBuf & append(const SBuf &S)
Store::DiskConfig cacheSwap
int n_strands
number of disk processes required to support all cache_dirs
an std::runtime_error with thrower location info
void clientConnectionsClose()
#define debugs(SECTION, LEVEL, CONTENT)
void fatal_dump(const char *message)
void fatalf(const char *fmt,...)
void fqdncacheAddEntryFromHosts(char *addr, SBufList &hostnames)
const char * version_string
int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
int initgroups(const char *name, gid_t basegid)
Config TheConfig
Globally available instance of Qos::Config.
int intPercent(const int a, const int b)
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
std::list< SBuf > SBufList
#define LOCAL_ARRAY(type, name, size)
std::ostream & ForceAlert(std::ostream &s)
char * tempnam(const char *dir, const char *pfx)
int xgethostname(char *name, size_t nameLength)
POSIX gethostname(2) equivalent.
#define SQUID_RELEASE_TIME
const char * xstrerr(int error)