#ifdef NOD_ENABLED
#include "nod.hh"
#endif /* NOD_ENABLED */
+#include "query-local-address.hh"
#include "rec-protobuf.hh"
#include "rec-snmp.hh"
typedef vector<int> tcpListenSockets_t;
typedef map<int, ComboAddress> listenSocketsAddresses_t; // is shared across all threads right now
-static const ComboAddress g_local4("0.0.0.0"), g_local6("::");
static listenSocketsAddresses_t g_listenSocketsAddresses; // is shared across all threads right now
static set<int> g_fromtosockets; // listen sockets that use 'sendfromto()' mechanism
-static vector<ComboAddress> g_localQueryAddresses4, g_localQueryAddresses6;
static AtomicCounter counter;
static std::shared_ptr<SyncRes::domainmap_t> g_initialDomainMap; // new threads needs this to be setup
static std::shared_ptr<NetmaskGroup> g_initialAllowFrom; // new thread needs to be setup with this
{
Socket s(dest.sin4.sin_family, SOCK_DGRAM);
s.setNonBlocking();
- ComboAddress local = getQueryLocalAddress(dest.sin4.sin_family, 0);
+ ComboAddress local = pdns::getQueryLocalAddress(dest.sin4.sin_family, 0);
s.bind(local);
s.connect(dest);
return data;
}
-//! pick a random query local address
-ComboAddress getQueryLocalAddress(int family, uint16_t port)
-{
- ComboAddress ret;
- if(family==AF_INET) {
- if(g_localQueryAddresses4.empty())
- ret = g_local4;
- else
- ret = g_localQueryAddresses4[dns_random(g_localQueryAddresses4.size())];
- ret.sin4.sin_port = htons(port);
- }
- else {
- if(g_localQueryAddresses6.empty())
- ret = g_local6;
- else
- ret = g_localQueryAddresses6[dns_random(g_localQueryAddresses6.size())];
-
- ret.sin6.sin6_port = htons(port);
- }
- return ret;
-}
-
static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t&);
static void setSocketBuffer(int fd, int optname, uint32_t size)
while (s_avoidUdpSourcePorts.count(port));
}
- sin=getQueryLocalAddress(family, port); // does htons for us
+ sin=pdns::getQueryLocalAddress(family, port); // does htons for us
if (::bind(ret, (struct sockaddr *)&sin, sin.getSocklen()) >= 0)
break;
checkLinuxIPv6Limits();
try {
- vector<string> addrs;
- if(!::arg()["query-local-address6"].empty()) {
- SyncRes::s_doIPv6=true;
- g_log<<Logger::Warning<<"Enabling IPv6 transport for outgoing queries"<<endl;
-
- stringtok(addrs, ::arg()["query-local-address6"], ", ;");
- for(const string& addr : addrs) {
- g_localQueryAddresses6.push_back(ComboAddress(addr));
- }
- }
- else {
- g_log<<Logger::Warning<<"NOT using IPv6 for outgoing queries - set 'query-local-address6=::' to enable"<<endl;
- }
- addrs.clear();
- stringtok(addrs, ::arg()["query-local-address"], ", ;");
- for(const string& addr : addrs) {
- g_localQueryAddresses4.push_back(ComboAddress(addr));
+ pdns::parseQueryLocalAddress(::arg()["query-local-address"]);
+ if (!::arg()["query-local-address6"].empty()) {
+ // TODO remove in 4.5.0
+ g_log<<Logger::Warning<<"query-local-address6 is deprecated and will be removed in a future version. Please use query-local-address for IPv6 addresses as well"<<endl;
+ pdns::parseQueryLocalAddress(::arg()["query-local-address6"]);
}
}
catch(std::exception& e) {
exit(99);
}
+ if(pdns::isQueryLocalAddressFamilyEnabled(AF_INET6)) {
+ SyncRes::s_doIPv6=true;
+ g_log<<Logger::Warning<<"Enabling IPv6 transport for outgoing queries"<<endl;
+ }
+ else {
+ g_log<<Logger::Warning<<"NOT using IPv6 for outgoing queries - add an IPv6 address (like '::') to query-local-address to enable"<<endl;
+ }
+
// keep this ABOVE loadRecursorLuaConfig!
if(::arg()["dnssec"]=="off")
g_dnssecmode=DNSSECMode::Off;
SyncRes::setECSScopeZeroAddress(Netmask(scopeZero, scopeZero.isIPv4() ? 32 : 128));
}
else {
- bool found = false;
- for (const auto& addr : g_localQueryAddresses4) {
- if (!IsAnyAddress(addr)) {
- SyncRes::setECSScopeZeroAddress(Netmask(addr, 32));
- found = true;
- break;
- }
+ Netmask nm;
+ bool done = false;
+
+ auto addr = pdns::getNonAnyQueryLocalAddress(AF_INET);
+ if (addr.sin4.sin_family != 0) {
+ nm = Netmask(addr, 32);
+ done = true;
}
- if (!found) {
- for (const auto& addr : g_localQueryAddresses6) {
- if (!IsAnyAddress(addr)) {
- SyncRes::setECSScopeZeroAddress(Netmask(addr, 128));
- found = true;
- break;
- }
- }
- if (!found) {
- SyncRes::setECSScopeZeroAddress(Netmask("127.0.0.1/32"));
+ if (!done) {
+ addr = pdns::getNonAnyQueryLocalAddress(AF_INET6);
+ if (addr.sin4.sin_family != 0) {
+ nm = Netmask(addr, 128);
+ done = true;
}
}
+ if (!done) {
+ nm = Netmask(ComboAddress("127.0.0.1"), 32);
+ }
+ SyncRes::setECSScopeZeroAddress(nm);
}
SyncRes::parseEDNSSubnetWhitelist(::arg()["edns-subnet-whitelist"]);
#endif
::arg().set("delegation-only","Which domains we only accept delegations from")="";
::arg().set("query-local-address","Source IP address for sending queries")="0.0.0.0";
- ::arg().set("query-local-address6","Source IPv6 address for sending queries. IF UNSET, IPv6 WILL NOT BE USED FOR OUTGOING QUERIES")="";
+ ::arg().set("query-local-address6","DEPRECATED: Use query-local-address for IPv6 as well. Source IPv6 address for sending queries. IF UNSET, IPv6 WILL NOT BE USED FOR OUTGOING QUERIES")="";
::arg().set("client-tcp-timeout","Timeout in seconds when talking to TCP clients")="2";
::arg().set("max-mthreads", "Maximum number of simultaneous Mtasker threads")="2048";
::arg().set("max-tcp-clients","Maximum number of simultaneous TCP clients")="128";