return ret;
}
-void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface)
+void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface, std::set<int>& cpus)
{
if (vars) {
if (vars->count("doTCP")) {
if (vars->count("interface")) {
interface = boost::get<std::string>((*vars)["interface"]);
}
+ if (vars->count("cpus")) {
+ for (const auto cpu : boost::get<std::vector<std::pair<int,int>>>((*vars)["cpus"])) {
+ cpus.insert(cpu.second);
+ }
+ }
}
}
bool reusePort = false;
int tcpFastOpenQueueSize = 0;
std::string interface;
+ std::set<int> cpus;
- parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+ parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus);
try {
ComboAddress loc(addr, 53);
g_locals.clear();
- g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface)); /// only works pre-startup, so no sync necessary
+ g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus)); /// only works pre-startup, so no sync necessary
}
catch(std::exception& e) {
g_outputBuffer="Error: "+string(e.what())+"\n";
bool reusePort = false;
int tcpFastOpenQueueSize = 0;
std::string interface;
+ std::set<int> cpus;
- parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+ parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus);
try {
ComboAddress loc(addr, 53);
- g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface)); /// only works pre-startup, so no sync necessary
+ g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus)); /// only works pre-startup, so no sync necessary
}
catch(std::exception& e) {
g_outputBuffer="Error: "+string(e.what())+"\n";
*/
#pragma once
-typedef std::unordered_map<std::string, boost::variant<bool, int, std::string> > localbind_t;
-void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface);
+typedef std::unordered_map<std::string, boost::variant<bool, int, std::string, std::vector<std::pair<int,int> > > > localbind_t;
+void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface, std::set<int>& cpus);
typedef boost::variant<string, vector<pair<int, string>>, std::shared_ptr<DNSRule>, DNSName, vector<pair<int, DNSName> > > luadnsrule_t;
std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var);
bool reusePort = false;
int tcpFastOpenQueueSize = 0;
std::string interface;
+ std::set<int> cpus;
- parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+ parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus);
try {
DnsCryptContext ctx(providerName, certFile, keyFile);
- g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort, tcpFastOpenQueueSize, interface));
+ g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort, tcpFastOpenQueueSize, interface, cpus));
}
catch(std::exception& e) {
errlog(e.what());
GlobalStateHolder<NetmaskGroup> g_ACL;
string g_outputBuffer;
-vector<std::tuple<ComboAddress, bool, bool, int, string>> g_locals;
+vector<std::tuple<ComboAddress, bool, bool, int, string, std::set<int>>> g_locals;
#ifdef HAVE_DNSCRYPT
-std::vector<std::tuple<ComboAddress,DnsCryptContext,bool, int, string>> g_dnsCryptLocals;
+std::vector<std::tuple<ComboAddress,DnsCryptContext,bool, int, string, std::set<int>>> g_dnsCryptLocals;
#endif
#ifdef HAVE_EBPF
shared_ptr<BPFFilter> g_defaultBPFFilter;
if(g_cmdLine.locals.size()) {
g_locals.clear();
for(auto loc : g_cmdLine.locals)
- g_locals.push_back(std::make_tuple(ComboAddress(loc, 53), true, false, 0, ""));
+ g_locals.push_back(std::make_tuple(ComboAddress(loc, 53), true, false, 0, "", std::set<int>()));
}
if(g_locals.empty())
- g_locals.push_back(std::make_tuple(ComboAddress("127.0.0.1", 53), true, false, 0, ""));
+ g_locals.push_back(std::make_tuple(ComboAddress("127.0.0.1", 53), true, false, 0, "", std::set<int>()));
g_configurationDone = true;
}
#endif /* HAVE_EBPF */
+ cs->cpus = std::get<5>(local);
+
SBind(cs->udpFD, cs->local);
toLaunch.push_back(cs);
g_frontends.push_back(cs);
bindAny(cs->local.sin4.sin_family, cs->tcpFD);
SBind(cs->tcpFD, cs->local);
SListen(cs->tcpFD, 64);
- warnlog("Listening on %s",cs->local.toStringWithPort());
+ warnlog("Listening on %s", cs->local.toStringWithPort());
toLaunch.push_back(cs);
g_frontends.push_back(cs);
vinfolog("Attaching default BPF Filter to TCP DNSCrypt frontend %s", cs->local.toStringWithPort());
}
#endif /* HAVE_EBPF */
+
+ cs->cpus = std::get<5>(dcLocal);
+
bindAny(cs->local.sin4.sin_family, cs->tcpFD);
SBind(cs->tcpFD, cs->local);
SListen(cs->tcpFD, 64);
for(auto& cs : toLaunch) {
if (cs->udpFD >= 0) {
thread t1(udpClientThread, cs);
+ if (!cs->cpus.empty()) {
+ mapThreadToCPUList(t1.native_handle(), cs->cpus);
+ }
t1.detach();
}
else if (cs->tcpFD >= 0) {
thread t1(tcpAcceptorThread, cs);
+ if (!cs->cpus.empty()) {
+ mapThreadToCPUList(t1.native_handle(), cs->cpus);
+ }
t1.detach();
}
}
struct ClientState
{
+ std::set<int> cpus;
ComboAddress local;
#ifdef HAVE_DNSCRYPT
DnsCryptContext* dnscryptCtx{0};
extern ComboAddress g_serverControl; // not changed during runtime
-extern std::vector<std::tuple<ComboAddress, bool, bool, int, std::string>> g_locals; // not changed at runtime (we hope XXX)
+extern std::vector<std::tuple<ComboAddress, bool, bool, int, std::string, std::set<int>>> g_locals; // not changed at runtime (we hope XXX)
extern vector<ClientState*> g_frontends;
extern std::string g_key; // in theory needs locking
extern bool g_truncateTC;
void restoreFlags(struct dnsheader* dh, uint16_t origFlags);
#ifdef HAVE_DNSCRYPT
-extern std::vector<std::tuple<ComboAddress,DnsCryptContext,bool,int, std::string>> g_dnsCryptLocals;
+extern std::vector<std::tuple<ComboAddress,DnsCryptContext,bool,int, std::string, std::set<int>>> g_dnsCryptLocals;
int handleDnsCryptQuery(DnsCryptContext* ctx, char* packet, uint16_t len, std::shared_ptr<DnsCryptQuery>& query, uint16_t* decryptedQueryLen, bool tcp, std::vector<uint8_t>& response);
bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr<DnsCryptQuery> dnsCryptQuery, dnsheader** dh, dnsheader* dhCopy);
AC_PROG_CC
AC_PROG_CXX
AC_LANG([C++])
+AC_GNU_SOURCE
LT_PREREQ([2.2.2])
LT_INIT([disable-static])
PDNS_CHECK_OS
PDNS_CHECK_NETWORK_LIBS
+PDNS_CHECK_PTHREAD_NP
boost_required_version=1.35
--- /dev/null
+../../../m4/pdns_check_pthread_np.m4
\ No newline at end of file