36#if HAVE_SYS_CAPABILITY_H
37#include <sys/capability.h>
43#include <sys/procctl.h>
62The Squid Cache (version %s) died.\n\
64You've encountered a fatal error in the Squid Cache version %s.\n\
65If a core file was created (possibly in the swap directory),\n\
66please execute 'gdb squid core' or 'dbx squid core', then type 'where',\n\
67and report the trace back to squid-bugs@lists.squid-cache.org.\n\
118 static char command[256];
127 const mode_t prev_umask=umask(S_IXUSR|S_IXGRP|S_IWGRP|S_IWOTH|S_IXOTH);
130 char filename[] =
"/tmp/squid-XXXXXX";
131 int tfd = mkstemp(filename);
132 if (tfd < 0 || (fp = fdopen(tfd,
"w")) ==
nullptr) {
141 (fp = fopen(filename,
"w")) ==
NULL) {
154 fprintf(fp,
"Subject: %s\n",
dead_msg());
158 if (system(command)) {}
168#if HAVE_MSTATS && HAVE_GNUMALLOC_H
170 struct mstats ms = mstats();
171 fprintf(
debug_log,
"\ttotal space in arena: %6d KB\n",
172 (
int) (ms.bytes_total >> 10));
173 fprintf(
debug_log,
"\tTotal free: %6d KB %d%%\n",
174 (
int) (ms.bytes_free >> 10),
182 memset(r,
'\0',
sizeof(
struct rusage));
183#if HAVE_GETRUSAGE && defined(RUSAGE_SELF)
189 getrusage(RUSAGE_SELF, r);
195#elif defined(PSAPI_VERSION)
197 if (WIN32_OS_version >= _WIN_OS_WINNT) {
201 PROCESS_MEMORY_COUNTERS pmc;
202 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
204 FALSE, GetCurrentProcessId());
208 FILETIME ftCreate, ftExit, ftKernel, ftUser;
209 if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
210 int64_t *ptUser = (int64_t *)&ftUser;
211 int64_t tUser64 = *ptUser / 10;
212 int64_t *ptKernel = (int64_t *)&ftKernel;
213 int64_t tKernel64 = *ptKernel / 10;
214 r->
ru_utime.tv_sec =(long)(tUser64 / 1000000);
215 r->
ru_stime.tv_sec =(long)(tKernel64 / 1000000);
216 r->
ru_utime.tv_usec =(long)(tUser64 % 1000000);
217 r->
ru_stime.tv_usec =(long)(tKernel64 % 1000000);
219 CloseHandle( hProcess );
223 if (GetProcessMemoryInfo( hProcess, &pmc,
sizeof(pmc))) {
224 r->
ru_maxrss=(DWORD)(pmc.WorkingSetSize / getpagesize());
227 CloseHandle( hProcess );
231 CloseHandle( hProcess );
240 return (
double) r->
ru_stime.tv_sec +
242 (
double) r->
ru_stime.tv_usec / 1000000.0 +
247#ifndef HAVE_GETPAGESIZE
248#define HAVE_GETPAGESIZE 0
255#if _SQUID_SGI_ && _ABIAPI
257#elif _SQUID_SGI_|| _SQUID_OSF_ || _SQUID_AIX_ || defined(BSD4_4)
260#elif defined(HAVE_GETPAGESIZE) && HAVE_GETPAGESIZE != 0
262 return (r->
ru_maxrss * getpagesize()) >> 10;
263#elif defined(PAGESIZE)
276#if _SQUID_SGI_ && _ABIAPI
290 const auto handleError = [](
const char *
const syscall,
const int savedErrno) {
293#if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
294 if (prctl(PR_SET_DUMPABLE, 1) != 0)
295 handleError(
"prctl(PR_SET_DUMPABLE)", errno);
296#elif HAVE_PROCCTL && defined(PROC_TRACE_CTL)
299 int traceable = PROC_TRACE_CTL_ENABLE;
300 if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &traceable) != 0)
301 handleError(
"procctl(PROC_TRACE_CTL_ENABLE)", errno);
303 if (setpflags(__PROC_PROTECT, 0) != 0)
304 handleError(
"setpflags(__PROC_PROTECT)", errno);
306 debugs(50, 2,
"WARNING: Assuming this process is traceable");
334 fprintf(
debug_log,
"CPU Usage: %.3f seconds = %.3f user + %.3f sys\n",
338 fprintf(
debug_log,
"Maximum Resident Size: %d KB\n",
340 fprintf(
debug_log,
"Page faults with physical i/o: %d\n",
349 else if (sig == SIGBUS)
357 extern void U_STACK_TRACE(
void);
364#if _SQUID_SOLARIS_ && HAVE_LIBOPCOM_STACK
366 extern void opcom_stack_trace(
void);
374#if HAVE_BACKTRACE_SYMBOLS_FD
376 static void *callarray[8192];
378 n = backtrace(callarray, 8192);
379 backtrace_symbols_fd(callarray, n, fileno(
debug_log));
385#if SA_RESETHAND == 0 && !_SQUID_WINDOWS_
386 signal(SIGSEGV, SIG_DFL);
388 signal(SIGBUS, SIG_DFL);
390 signal(sig, SIG_DFL);
425 kill(kid.getPid(), sig);
435 static int state = 0;
470 static int present = 0;
471 struct addrinfo *AI =
nullptr;
493 if (getnameinfo(AI->ai_addr, AI->ai_addrlen, host,
SQUIDHOSTNAMELEN,
nullptr, 0, NI_NAMEREQD ) == 0) {
496 debugs(50, 4,
"getMyHostname: resolved " << sa <<
" to '" << host <<
"'");
502 if (strchr(host,
'.'))
507 debugs(50, 2,
"WARNING: failed to resolve " << sa <<
" to a fully qualified hostname");
516 struct addrinfo hints;
517 memset(&hints, 0,
sizeof(addrinfo));
518 hints.ai_flags = AI_CANONNAME;
520 if (getaddrinfo(host,
nullptr,
nullptr, &AI) == 0) {
523 debugs(50, 6,
"getMyHostname: '" << host <<
"' has DNS resolution.");
540 debugs(50,
DBG_CRITICAL,
"WARNING: Could not determine this machines public hostname. " <<
541 "Please configure one or set 'visible_hostname'.");
543 return (
"localhost");
561 debugs(21, 3,
"leave_suid: PID " << getpid() <<
" called");
599 const auto xerrno = errno;
605 const auto xerrno = errno;
611 const auto xerrno = errno;
625 debugs(21, 3,
"enter_suid: PID " << getpid() <<
" taking root privileges");
627 if (setresuid((uid_t)-1, 0, (uid_t)-1) < 0) {
628 const auto xerrno = errno;
629 debugs (21, 3,
"enter_suid: setresuid failed: " <<
xstrerr(xerrno));
634 const auto xerrno = errno;
651 debugs(21, 3,
"no_suid: PID " << getpid() <<
" giving up root privileges forever");
658 if (setuid(uid) < 0) {
745 roles.
append(
" coordinator");
756#define RLIMIT_NOFILE RLIMIT_OFILE
764#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE)
769#if defined(getrlimit)
775 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
782 rl.rlim_cur = FD_SETSIZE;
787 if (rl.rlim_cur > rl.rlim_max)
788 rl.rlim_max = rl.rlim_cur;
789 if (setrlimit(RLIMIT_NOFILE, &rl)) {
792 getrlimit(RLIMIT_NOFILE, &rl);
793 rl.rlim_cur = rl.rlim_max;
794 if (setrlimit(RLIMIT_NOFILE, &rl)) {
800 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
813#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !_SQUID_CYGWIN_
819#if defined(getrlimit)
825 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
830 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
838#if HAVE_SETRLIMIT && defined(RLIMIT_DATA) && !_SQUID_CYGWIN_
839 if (getrlimit(RLIMIT_DATA, &rl) < 0) {
842 }
else if (rl.rlim_max > rl.rlim_cur) {
843 rl.rlim_cur = rl.rlim_max;
845 if (setrlimit(RLIMIT_DATA, &rl) < 0) {
856#if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) && !_SQUID_CYGWIN_
857 if (getrlimit(RLIMIT_VMEM, &rl) < 0) {
860 }
else if (rl.rlim_max > rl.rlim_cur) {
861 rl.rlim_cur = rl.rlim_max;
863 if (setrlimit(RLIMIT_VMEM, &rl) < 0) {
878 sa.sa_handler = func;
880 sigemptyset(&sa.sa_mask);
882 if (sigaction(sig, &sa,
nullptr) < 0) {
910 WIN32_ExceptionHandlerInit();
914 WIN32_ExceptionHandlerInit();
940 assert(label && obj && pm);
944 debugs(section, level,
"" << label <<
"" << mb.
buf <<
"");
971 setmode(fileno(fp),
O_TEXT);
974 while (fgets(buf, 1024, fp)) {
985 debugs(1, 5,
"etc_hosts: line is '" << buf <<
"'");
994 debugs(1, 5,
"etc_hosts: address is '" << addr <<
"'");
1000 while ((nt = strpbrk(lt,
w_space))) {
1001 char *host =
nullptr;
1004 debugs(1, 5,
"etc_hosts: multiple spaces, skipping");
1010 debugs(1, 5,
"etc_hosts: got hostname '" << lt <<
"'");
1015 strncpy(buf2, lt,
sizeof(buf2)-1);
1017 buf2[
sizeof(buf2)-1] =
'\0';
1028 hosts.emplace_back(
SBuf(host));
1046 while (p !=
nullptr && p->flags.isIntercepted())
1054 while (p !=
nullptr && p->flags.isIntercepted())
1072 static const mode_t orig_umask = umask(mask);
1073 umask(mask | orig_umask);
1084 if (strchr(str,
' ')) {
1090 int l = strcspn(str,
"\"\\\n\r");
1124#if USE_LIBCAP && HAVE_PRCTL && defined(PR_SET_KEEPCAPS)
1126 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
1139 caps = cap_get_proc();
1147 cap_value_t cap_list[10];
1148 cap_list[ncaps] = CAP_NET_BIND_SERVICE;
1151#
if USE_LIBNETFILTERCONNTRACK
1158 cap_list[ncaps] = CAP_NET_ADMIN;
1162 cap_clear_flag(caps, CAP_EFFECTIVE);
1163 rc |= cap_set_flag(caps, CAP_EFFECTIVE, ncaps, cap_list, CAP_SET);
1164 rc |= cap_set_flag(caps, CAP_PERMITTED, ncaps, cap_list, CAP_SET);
1166 if (rc || cap_set_proc(caps) != 0) {
1167 Ip::Interceptor.StopTransparency(
"Error enabling needed capabilities.");
1173 Ip::Interceptor.StopTransparency(
"Missing needed capability support.");
1185 return waitpid(
pid, &status, flags);
1191WindowsErrorMessage(DWORD errorId)
1193 char *rawMessage =
nullptr;
1194 const auto length = FormatMessage(
1195 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1196 FORMAT_MESSAGE_FROM_SYSTEM |
1197 FORMAT_MESSAGE_IGNORE_INSERTS,
1200 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1201 static_cast<LPTSTR
>(&rawMessage),
1206 return ToSBuf(
"windows error ", errorId);
1208 const auto result =
SBuf(rawMessage, length);
1209 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
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)
#define debug_log
change-avoidance macro; new code should call DebugStream() instead
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)
#define SQUID_RELEASE_TIME
const char * xstrerr(int error)