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 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
775 rl.rlim_cur = FD_SETSIZE;
780 if (rl.rlim_cur > rl.rlim_max)
781 rl.rlim_max = rl.rlim_cur;
782 if (setrlimit(RLIMIT_NOFILE, &rl)) {
785 getrlimit(RLIMIT_NOFILE, &rl);
786 rl.rlim_cur = rl.rlim_max;
787 if (setrlimit(RLIMIT_NOFILE, &rl)) {
793 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
806#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !_SQUID_CYGWIN_
812#if defined(getrlimit)
818 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
823 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
831#if HAVE_SETRLIMIT && defined(RLIMIT_DATA) && !_SQUID_CYGWIN_
832 if (getrlimit(RLIMIT_DATA, &rl) < 0) {
835 }
else if (rl.rlim_max > rl.rlim_cur) {
836 rl.rlim_cur = rl.rlim_max;
838 if (setrlimit(RLIMIT_DATA, &rl) < 0) {
849#if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) && !_SQUID_CYGWIN_
850 if (getrlimit(RLIMIT_VMEM, &rl) < 0) {
853 }
else if (rl.rlim_max > rl.rlim_cur) {
854 rl.rlim_cur = rl.rlim_max;
856 if (setrlimit(RLIMIT_VMEM, &rl) < 0) {
871 sa.sa_handler = func;
873 sigemptyset(&sa.sa_mask);
875 if (sigaction(sig, &sa,
nullptr) < 0) {
903 WIN32_ExceptionHandlerInit();
907 WIN32_ExceptionHandlerInit();
933 assert(label && obj && pm);
937 debugs(section, level,
"" << label <<
"" << mb.
buf <<
"");
964 setmode(fileno(fp),
O_TEXT);
967 while (fgets(buf, 1024, fp)) {
978 debugs(1, 5,
"etc_hosts: line is '" << buf <<
"'");
987 debugs(1, 5,
"etc_hosts: address is '" << addr <<
"'");
993 while ((nt = strpbrk(lt,
w_space))) {
994 char *host =
nullptr;
997 debugs(1, 5,
"etc_hosts: multiple spaces, skipping");
1003 debugs(1, 5,
"etc_hosts: got hostname '" << lt <<
"'");
1008 strncpy(buf2, lt,
sizeof(buf2)-1);
1010 buf2[
sizeof(buf2)-1] =
'\0';
1021 hosts.emplace_back(
SBuf(host));
1039 while (p !=
nullptr && p->flags.isIntercepted())
1047 while (p !=
nullptr && p->flags.isIntercepted())
1065 static const mode_t orig_umask = umask(mask);
1066 umask(mask | orig_umask);
1077 if (strchr(str,
' ')) {
1083 const auto l = strcspn(str,
"\"\\\n\r");
1117#if HAVE_LIBCAP && HAVE_PRCTL && defined(PR_SET_KEEPCAPS)
1118 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
1119 Ip::Interceptor.StopTransparency(
"capability setting has failed.");
1130 caps = cap_get_proc();
1134 Ip::Interceptor.StopTransparency(
"Can't get current capabilities");
1138 cap_value_t cap_list[10];
1139 cap_list[ncaps] = CAP_NET_BIND_SERVICE;
1141 if (Ip::Interceptor.TransparentActive() ||
1144 Ip::Interceptor.InterceptActive() ||
1149 cap_list[ncaps] = CAP_NET_ADMIN;
1153 cap_clear_flag(caps, CAP_EFFECTIVE);
1154 rc |= cap_set_flag(caps, CAP_EFFECTIVE, ncaps, cap_list, CAP_SET);
1155 rc |= cap_set_flag(caps, CAP_PERMITTED, ncaps, cap_list, CAP_SET);
1157 if (rc || cap_set_proc(caps) != 0) {
1158 Ip::Interceptor.StopTransparency(
"Error enabling needed capabilities.");
1164 Ip::Interceptor.StopTransparency(
"Missing needed capability support.");
1178 return waitpid(
pid, &status, flags);
1182#if _SQUID_WINDOWS_ || _SQUID_MINGW_
1184WindowsErrorMessage(DWORD errorId)
1186 char *rawMessage =
nullptr;
1187 const auto length = FormatMessage(
1188 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1189 FORMAT_MESSAGE_FROM_SYSTEM |
1190 FORMAT_MESSAGE_IGNORE_INSERTS,
1193 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1194 static_cast<LPTSTR
>(&rawMessage),
1199 return ToSBuf(
"windows error ", errorId);
1201 const auto result =
SBuf(rawMessage, length);
1202 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)