Go to the documentation of this file.
37 #if HAVE_SYS_CAPABILITY_H
38 #include <sys/capability.h>
41 #include <sys/prctl.h>
43 #if HAVE_SYS_PROCCTL_H
44 #include <sys/procctl.h>
63 The Squid Cache (version %s) died.\n\
65 You've encountered a fatal error in the Squid Cache version %s.\n\
66 If a core file was created (possibly in the swap directory),\n\
67 please execute 'gdb squid core' or 'dbx squid core', then type 'where',\n\
68 and report the trace back to squid-bugs@lists.squid-cache.org.\n\
80 SQUIDCEXTERN void backtrace_symbols_fd(
void *,
int,
int);
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_SGI_ && _ABIAPI
258 #elif _SQUID_SGI_|| _SQUID_OSF_ || _SQUID_AIX_ || defined(BSD4_4)
261 #elif defined(HAVE_GETPAGESIZE) && HAVE_GETPAGESIZE != 0
263 return (r->
ru_maxrss * getpagesize()) >> 10;
264 #elif defined(PAGESIZE)
277 #if _SQUID_SGI_ && _ABIAPI
291 const auto handleError = [](
const char *
const syscall,
const int savedErrno) {
294 #if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
295 if (prctl(PR_SET_DUMPABLE, 1) != 0)
296 handleError(
"prctl(PR_SET_DUMPABLE)", errno);
297 #elif HAVE_PROCCTL && defined(PROC_TRACE_CTL)
300 int traceable = PROC_TRACE_CTL_ENABLE;
301 if (procctl(P_PID, getpid(), PROC_TRACE_CTL, &traceable) != 0)
302 handleError(
"procctl(PROC_TRACE_CTL_ENABLE)", errno);
304 if (setpflags(__PROC_PROTECT, 0) != 0)
305 handleError(
"setpflags(__PROC_PROTECT)", errno);
307 debugs(50, 2,
"WARNING: Assuming this process is traceable");
335 fprintf(
DebugStream(),
"CPU Usage: %.3f seconds = %.3f user + %.3f sys\n",
339 fprintf(
DebugStream(),
"Maximum Resident Size: %d KB\n",
341 fprintf(
DebugStream(),
"Page faults with physical i/o: %d\n",
350 else if (sig == SIGBUS)
355 #if PRINT_STACK_TRACE
358 extern void U_STACK_TRACE(
void);
365 #if _SQUID_SOLARIS_ && HAVE_LIBOPCOM_STACK
367 extern void opcom_stack_trace(
void);
375 #if HAVE_BACKTRACE_SYMBOLS_FD
377 static void *callarray[8192];
379 n = backtrace(callarray, 8192);
380 backtrace_symbols_fd(callarray, n, fileno(
DebugStream()));
386 #if SA_RESETHAND == 0 && !_SQUID_WINDOWS_
387 signal(SIGSEGV, SIG_DFL);
389 signal(SIGBUS, SIG_DFL);
391 signal(sig, SIG_DFL);
426 kill(kid.getPid(), sig);
436 static int state = 0;
471 static int present = 0;
472 struct addrinfo *AI =
nullptr;
494 if (getnameinfo(AI->ai_addr, AI->ai_addrlen, host,
SQUIDHOSTNAMELEN,
nullptr, 0, NI_NAMEREQD ) == 0) {
497 debugs(50, 4,
"getMyHostname: resolved " << sa <<
" to '" << host <<
"'");
503 if (strchr(host,
'.'))
508 debugs(50, 2,
"WARNING: failed to resolve " << sa <<
" to a fully qualified hostname");
517 struct addrinfo hints;
518 memset(&hints, 0,
sizeof(addrinfo));
519 hints.ai_flags = AI_CANONNAME;
521 if (getaddrinfo(host,
nullptr,
nullptr, &AI) == 0) {
524 debugs(50, 6,
"getMyHostname: '" << host <<
"' has DNS resolution.");
541 debugs(50,
DBG_CRITICAL,
"WARNING: Could not determine this machines public hostname. " <<
542 "Please configure one or set 'visible_hostname'.");
544 return (
"localhost");
562 debugs(21, 3,
"leave_suid: PID " << getpid() <<
" called");
600 const auto xerrno = errno;
606 const auto xerrno = errno;
612 const auto xerrno = errno;
626 debugs(21, 3,
"enter_suid: PID " << getpid() <<
" taking root privileges");
628 if (setresuid((uid_t)-1, 0, (uid_t)-1) < 0) {
629 const auto xerrno = errno;
630 debugs (21, 3,
"enter_suid: setresuid failed: " <<
xstrerr(xerrno));
635 const auto xerrno = errno;
652 debugs(21, 3,
"no_suid: PID " << getpid() <<
" giving up root privileges forever");
659 if (setuid(uid) < 0) {
746 roles.
append(
" coordinator");
755 #ifndef RLIMIT_NOFILE
757 #define RLIMIT_NOFILE RLIMIT_OFILE
765 #if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE)
770 #if defined(getrlimit)
776 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
783 rl.rlim_cur = FD_SETSIZE;
788 if (rl.rlim_cur > rl.rlim_max)
789 rl.rlim_max = rl.rlim_cur;
790 if (setrlimit(RLIMIT_NOFILE, &rl)) {
793 getrlimit(RLIMIT_NOFILE, &rl);
794 rl.rlim_cur = rl.rlim_max;
795 if (setrlimit(RLIMIT_NOFILE, &rl)) {
801 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
814 #if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !_SQUID_CYGWIN_
820 #if defined(getrlimit)
826 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
831 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
839 #if HAVE_SETRLIMIT && defined(RLIMIT_DATA) && !_SQUID_CYGWIN_
840 if (getrlimit(RLIMIT_DATA, &rl) < 0) {
843 }
else if (rl.rlim_max > rl.rlim_cur) {
844 rl.rlim_cur = rl.rlim_max;
846 if (setrlimit(RLIMIT_DATA, &rl) < 0) {
857 #if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) && !_SQUID_CYGWIN_
858 if (getrlimit(RLIMIT_VMEM, &rl) < 0) {
861 }
else if (rl.rlim_max > rl.rlim_cur) {
862 rl.rlim_cur = rl.rlim_max;
864 if (setrlimit(RLIMIT_VMEM, &rl) < 0) {
879 sa.sa_handler = func;
881 sigemptyset(&sa.sa_mask);
883 if (sigaction(sig, &sa,
nullptr) < 0) {
911 WIN32_ExceptionHandlerInit();
915 WIN32_ExceptionHandlerInit();
941 assert(label && obj && pm);
945 debugs(section, level,
"" << label <<
"" << mb.
buf <<
"");
972 setmode(fileno(fp),
O_TEXT);
975 while (fgets(buf, 1024, fp)) {
986 debugs(1, 5,
"etc_hosts: line is '" << buf <<
"'");
995 debugs(1, 5,
"etc_hosts: address is '" << addr <<
"'");
1001 while ((nt = strpbrk(lt,
w_space))) {
1002 char *host =
nullptr;
1005 debugs(1, 5,
"etc_hosts: multiple spaces, skipping");
1011 debugs(1, 5,
"etc_hosts: got hostname '" << lt <<
"'");
1016 strncpy(buf2, lt,
sizeof(buf2)-1);
1018 buf2[
sizeof(buf2)-1] =
'\0';
1029 hosts.emplace_back(
SBuf(host));
1047 while (p !=
nullptr && p->flags.isIntercepted())
1055 while (p !=
nullptr && p->flags.isIntercepted())
1073 static const mode_t orig_umask = umask(mask);
1074 umask(mask | orig_umask);
1085 if (strchr(str,
' ')) {
1091 int l = strcspn(str,
"\"\\\n\r");
1125 #if HAVE_LIBCAP && HAVE_PRCTL && defined(PR_SET_KEEPCAPS)
1126 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
1138 caps = cap_get_proc();
1146 cap_value_t cap_list[10];
1147 cap_list[ncaps] = CAP_NET_BIND_SERVICE;
1150 #
if USE_LIBNETFILTERCONNTRACK
1157 cap_list[ncaps] = CAP_NET_ADMIN;
1161 cap_clear_flag(caps, CAP_EFFECTIVE);
1162 rc |= cap_set_flag(caps, CAP_EFFECTIVE, ncaps, cap_list, CAP_SET);
1163 rc |= cap_set_flag(caps, CAP_PERMITTED, ncaps, cap_list, CAP_SET);
1165 if (rc || cap_set_proc(caps) != 0) {
1186 return waitpid(
pid, &status, flags);
1190 #if _SQUID_WINDOWS_ || _SQUID_MINGW_
1192 WindowsErrorMessage(DWORD errorId)
1194 char *rawMessage =
nullptr;
1195 const auto length = FormatMessage(
1196 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1197 FORMAT_MESSAGE_FROM_SYSTEM |
1198 FORMAT_MESSAGE_IGNORE_INSERTS,
1201 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1202 static_cast<LPTSTR
>(&rawMessage),
1207 return ToSBuf(
"windows error ", errorId);
1209 const auto result =
SBuf(rawMessage, length);
1210 LocalFree(rawMessage);
1213 #endif // _SQUID_WINDOWS_ || _SQUID_MINGW_
static char * debugOptions
const char * xstrerr(int error)
#define Here()
source code location of the caller
void StopTransparency(const char *str)
int intPercent(const int a, const int b)
void clientConnectionsClose()
#define LOCAL_ARRAY(type, name, size)
AnyP::PortCfgPointer HttpPortList
list of Squid http(s)_port configured
int TheProcessKind
ProcessKind for the current process.
std::list< SBuf > SBufList
void init(mb_size_t szInit, mb_size_t szMax)
std::ostream & ForceAlert(std::ostream &s)
static void FreeAddr(struct addrinfo *&ai)
int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
Store::DiskConfig cacheSwap
size_t count() const
returns the number of kids
Kid & get(size_t i)
returns the kid by index, useful for kids iteration
class SquidConfig2 Config2
const char * version_string
void fqdncacheAddEntryFromHosts(char *addr, SBufList &hostnames)
char * tempnam(const char *dir, const char *pfx)
void append(const char *c, int sz) override
Kids TheKids
All kids being maintained.
int n_strands
number of disk processes required to support all cache_dirs
AnyP::PortCfgPointer FtpPortList
list of Squid ftp_port configured
static void PrepareToDie()
static void parseOptions(char const *)
void fatalf(const char *fmt,...)
int initgroups(const char *name, gid_t basegid)
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
void fatal_dump(const char *message)
static std::ostream & Extra(std::ostream &)
SBuf & append(const SBuf &S)
#define SQUID_RELEASE_TIME
int storeDirWriteCleanLogs(int reopen)
Config TheConfig
Globally available instance of Qos::Config.
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
@ pkWorker
general-purpose worker bee
an std::runtime_error with thrower location info
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
@ pkCoordinator
manages all other kids
#define debugs(SECTION, LEVEL, CONTENT)
int xgethostname(char *name, size_t nameLength)
POSIX gethostname(2) equivalent.
@ pkDisker
cache_dir manager