#include <pwd.h>
#include "lock.hh"
#include <getopt.h>
+#include <sys/resource.h>
#include "dnsdist-cache.hh"
#ifdef HAVE_SYSTEMD
}
}
+static void checkFileDescriptorsLimits(size_t udpBindsCount, size_t tcpBindsCount)
+{
+ /* stdin, stdout, stderr */
+ size_t requiredFDsCount = 3;
+ size_t backendsCount = g_dstates.getCopy().size();
+ requiredFDsCount += udpBindsCount;
+ requiredFDsCount += tcpBindsCount;
+ /* max TCP connections currently served */
+ requiredFDsCount += g_maxTCPClientThreads;
+ /* max pipes for communicatin between TCP acceptors and client threads */
+ requiredFDsCount += (g_maxTCPClientThreads * 2);
+ /* UDP sockets to backends */
+ requiredFDsCount += backendsCount;
+ /* TCP sockets to backends */
+ requiredFDsCount += (backendsCount * g_maxTCPClientThreads);
+ /* max TCP queued connections */
+ requiredFDsCount += (tcpBindsCount * g_maxTCPQueuedConnections);
+ /* DelayPipe pipe */
+ requiredFDsCount += 2;
+ /* syslog socket */
+ requiredFDsCount++;
+ /* webserver main socket */
+ requiredFDsCount++;
+ /* console main socket */
+ requiredFDsCount++;
+ /* carbon export */
+ requiredFDsCount++;
+ /* history file */
+ requiredFDsCount++;
+ struct rlimit rl;
+ getrlimit(RLIMIT_NOFILE, &rl);
+ if (((rl.rlim_cur * 3) / 4) < requiredFDsCount) {
+ warnlog("Warning, this configuration can use more than %d file descriptors, web server and console connections not included, and the current limit is %d.", std::to_string(requiredFDsCount), std::to_string(rl.rlim_cur));
+#ifdef HAVE_SYSTEMD
+ warnlog("You can increase this value by using LimitNOFILE= in the systemd unit file or ulimit.");
+#else
+ warnlog("You can increase this value by using ulimit.");
+#endif
+ }
+}
struct
{
int main(int argc, char** argv)
try
{
+ size_t udpBindsCount = 0;
+ size_t tcpBindsCount = 0;
rl_attempted_completion_function = my_completion;
rl_completion_append_character = 0;
SBind(cs->udpFD, cs->local);
toLaunch.push_back(cs);
g_frontends.push_back(cs);
+ udpBindsCount++;
}
for(const auto& local : g_locals) {
toLaunch.push_back(cs);
g_frontends.push_back(cs);
+ tcpBindsCount++;
}
#ifdef HAVE_DNSCRYPT
SBind(cs->udpFD, cs->local);
toLaunch.push_back(cs);
g_frontends.push_back(cs);
+ udpBindsCount++;
cs = new ClientState;
cs->local = std::get<0>(dcLocal);
warnlog("Listening on %s", cs->local.toStringWithPort());
toLaunch.push_back(cs);
g_frontends.push_back(cs);
+ tcpBindsCount++;
}
#endif
// you might define them later, but you need to know
}
+ checkFileDescriptorsLimits(udpBindsCount, tcpBindsCount);
+
for(auto& dss : g_dstates.getCopy()) { // it is a copy, but the internal shared_ptrs are the real deal
if(dss->availability==DownstreamState::Availability::Auto) {
bool newState=upCheck(*dss);