From: Otto Moerbeek Date: Thu, 11 Jun 2026 08:10:06 +0000 (+0200) Subject: Initial plumbing, untested but should be no-op X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8755a31dc0668daa7ba0ecd0640a73e9d3d93e06;p=thirdparty%2Fpdns.git Initial plumbing, untested but should be no-op Signed-off-by: Otto Moerbeek --- diff --git a/pdns/axfr-retriever.cc b/pdns/axfr-retriever.cc index 35193c746c..12af1c0e67 100644 --- a/pdns/axfr-retriever.cc +++ b/pdns/axfr-retriever.cc @@ -45,7 +45,7 @@ AXFRRetriever::AXFRRetriever(Logr::log_t slog, if (!pdns::isQueryLocalAddressFamilyEnabled(remote.sin4.sin_family)) { throw ResolverException("Unable to determine source address for AXFR request to " + remote.toStringWithPort() + " for " + domain.toLogString() + ". Address family is not configured for outgoing queries"); } - local = pdns::getQueryLocalAddress(remote.sin4.sin_family, 0); + local = pdns::getQueryLocalAddress(remote.sin4.sin_family, 0).d_address; } d_sock = -1; try { diff --git a/pdns/query-local-address.cc b/pdns/query-local-address.cc index 2acccabf8e..7a7c9dd98c 100644 --- a/pdns/query-local-address.cc +++ b/pdns/query-local-address.cc @@ -23,55 +23,56 @@ #include "iputils.hh" #include "dns_random.hh" -namespace pdns { +namespace pdns +{ static const ComboAddress local4("0.0.0.0"); static const ComboAddress local6("::"); - static vector g_localQueryAddresses4; - static vector g_localQueryAddresses6; + static vector g_localQueryAddresses4; + static vector g_localQueryAddresses6; - ComboAddress getQueryLocalAddress(const sa_family_t family, const in_port_t port) { - ComboAddress ret; + AddressAndInterface getQueryLocalAddress(const sa_family_t family, const in_port_t port) { + AddressAndInterface ret; if (family==AF_INET) { if (g_localQueryAddresses4.empty()) { - ret = local4; + ret.d_address = local4; } else if (g_localQueryAddresses4.size() == 1) { ret = g_localQueryAddresses4.at(0); } else { ret = g_localQueryAddresses4[dns_random(g_localQueryAddresses4.size())]; } - ret.sin4.sin_port = htons(port); + ret.d_address.sin4.sin_port = htons(port); } else { if (g_localQueryAddresses6.empty()) { - ret = local6; + ret.d_address = local6; } else if (g_localQueryAddresses6.size() == 1) { ret = g_localQueryAddresses6.at(0); } else { ret = g_localQueryAddresses6[dns_random(g_localQueryAddresses6.size())]; } - ret.sin6.sin6_port = htons(port); + ret.d_address.sin6.sin6_port = htons(port); } return ret; } - ComboAddress getNonAnyQueryLocalAddress(const sa_family_t family) { + AddressAndInterface getNonAnyQueryLocalAddress(const sa_family_t family) { if (family == AF_INET) { for (const auto& addr : pdns::g_localQueryAddresses4) { - if (!IsAnyAddress(addr)) { + if (!IsAnyAddress(addr.d_address)) { return addr; } } } if (family == AF_INET6) { for (const auto& addr : pdns::g_localQueryAddresses6) { - if (!IsAnyAddress(addr)) { + if (!IsAnyAddress(addr.d_address)) { return addr; } } } - ComboAddress ret("0.0.0.0"); - ret.reset(); // Ensure all is zero, even the addr family + AddressAndInterface ret{ComboAddress{"0.0.0.0"}, std::nullopt}; + ret.d_address.reset(); // Ensure all is zero, even the addr family return ret; } @@ -79,12 +80,12 @@ namespace pdns { vector addrs; stringtok(addrs, qla, ", ;"); for(const string& addr : addrs) { - ComboAddress tmp(addr); - if (tmp.isIPv4()) { - g_localQueryAddresses4.push_back(tmp); + AddressAndInterface tmp{ComboAddress{addr}, std::nullopt}; + if (tmp.d_address.isIPv4()) { + g_localQueryAddresses4.emplace_back(std::move(tmp)); continue; } - g_localQueryAddresses6.push_back(tmp); + g_localQueryAddresses6.emplace_back(std::move(tmp)); } } diff --git a/pdns/query-local-address.hh b/pdns/query-local-address.hh index 9515f4a358..ab95bb9512 100644 --- a/pdns/query-local-address.hh +++ b/pdns/query-local-address.hh @@ -24,6 +24,22 @@ #include "iputils.hh" namespace pdns { + + struct Interface + { + std::string d_name; + int d_index{-1}; + }; + struct AddressAndInterface + { + ComboAddress d_address; + std::optional d_interface; + bool operator<(const AddressAndInterface& arg) const + { + return d_address < arg.d_address; // XXX + }; + }; + /*! pick a random query local address for family * * Will always return a ComboAddress. @@ -31,13 +47,13 @@ namespace pdns { * @param family Address Family, only AF_INET and AF_INET6 are supported * @param port Port to set in the returned ComboAddress */ - ComboAddress getQueryLocalAddress(const sa_family_t family, const in_port_t port); + AddressAndInterface getQueryLocalAddress(sa_family_t family, in_port_t port); /*! Returns a non-Any address QLA, or an empty QLA when the QLA is any * * @param family Address Family */ - ComboAddress getNonAnyQueryLocalAddress(const sa_family_t family); + AddressAndInterface getNonAnyQueryLocalAddress(sa_family_t family); /*! Populate the query local address vectors * @@ -55,5 +71,5 @@ namespace pdns { * * @param family Address Family, only AF_INET and AF_INET6 are supported */ - bool isQueryLocalAddressFamilyEnabled(const sa_family_t family); + bool isQueryLocalAddressFamilyEnabled(sa_family_t family); } // namespace pdns diff --git a/pdns/recursordist/lwres.cc b/pdns/recursordist/lwres.cc index eb623ed1b0..70d300f0d1 100644 --- a/pdns/recursordist/lwres.cc +++ b/pdns/recursordist/lwres.cc @@ -358,7 +358,7 @@ class BindError { }; -static bool tcpconnect(const OptLog& log, const ComboAddress& remote, const std::optional localBind, TCPOutConnectionManager::Connection& connection, bool& dnsOverTLS, const std::string& nsName, std::string& subjectName) +static bool tcpconnect(const OptLog& log, const ComboAddress& remote, const std::optional localBind, TCPOutConnectionManager::Connection& connection, bool& dnsOverTLS, const std::string& nsName, std::string& subjectName) { dnsOverTLS = SyncRes::s_dot_to_port_853 && remote.getPort() == 853; @@ -373,16 +373,16 @@ static bool tcpconnect(const OptLog& log, const ComboAddress& remote, const std: sock.setNonBlocking(); setTCPNoDelay(sock.getHandle()); // Bind to the same address the cookie is associated with (RFC 9018 section 3 last paragraph) - ComboAddress localip = localBind ? *localBind : pdns::getQueryLocalAddress(remote.sin4.sin_family, 0); + pdns::AddressAndInterface localip = localBind ? *localBind : pdns::getQueryLocalAddress(remote.sin4.sin_family, 0); if (localBind) { - VLOG(log, "Connecting TCP to " << remote.toStringWithPortExcept(53) << " with specific local address " << localip.toString() << endl); + VLOG(log, "Connecting TCP to " << remote.toStringWithPortExcept(53) << " with specific local address " << localip.d_address.toString() << endl); } else { VLOG(log, "Connecting TCP to " << remote.toStringWithPortExcept(53) << " with no specific local address" << endl); } try { - sock.bind(localip); + sock.bind(localip.d_address); } catch (const NetworkError& e) { if (localBind) { @@ -498,7 +498,7 @@ static void addPadding(const DNSPacketWriter& pw, size_t bufsize, DNSPacketWrite } } -static void outgoingCookie(const OptLog& log, const ComboAddress& address, const timeval& now, DNSPacketWriter::optvect_t& opts, std::optional& cookieSentOut, std::optional& addressToBindTo) +static void outgoingCookie(const OptLog& log, const ComboAddress& address, const timeval& now, DNSPacketWriter::optvect_t& opts, std::optional& cookieSentOut, std::optional& addressToBindTo) { auto lock = s_cookiestore.lock(); if (auto found = lock->find(address); found != lock->end()) { @@ -528,7 +528,7 @@ static void outgoingCookie(const OptLog& log, const ComboAddress& address, const VLOG(log, "Sending new client cookie info to " << address.toString() << ": " << entry.d_cookie.toDisplayString() << endl); } -static std::pair incomingCookie(const OptLog& log, const ComboAddress& address, const ComboAddress& localip, const timeval& now, const std::optional& cookieSentOut, const EDNSOpts& edo, bool doTCP, LWResult& lwr, bool& cookieFoundInReply) +static std::pair incomingCookie(const OptLog& log, const ComboAddress& address, const pdns::AddressAndInterface& localip, const timeval& now, const std::optional& cookieSentOut, const EDNSOpts& edo, bool doTCP, LWResult& lwr, bool& cookieFoundInReply) { auto lock = s_cookiestore.lock(); auto found = lock->find(address); @@ -548,10 +548,10 @@ static std::pair incomingCookie(const OptLog& log, const cookieFoundInReply = true; VLOG(log, "Received cookie info back from " << address.toString() << ": " << received.toDisplayString() << endl); if (cookieSentOut && received.getClient() == cookieSentOut->getClient()) { - VLOG(log, "Client cookie from " << address.toString() << " matched! Storing with localAddress " << localip.toString() << endl); + VLOG(log, "Client cookie from " << address.toString() << " matched! Storing with localAddress " << localip.d_address.toString() << endl); ++t_Counters.at(rec::Counter::cookieMatched); found->d_localaddress = localip; - found->d_localaddress.setPort(0); + found->d_localaddress.d_address.setPort(0); found->d_cookie = std::move(received); if (found->getSupport() == CookieEntry::Support::Probing) { ++t_Counters.at(rec::Counter::cookieProbeSupported); @@ -562,20 +562,20 @@ static std::pair incomingCookie(const OptLog& log, const if (ercode == ERCode::BADCOOKIE) { lwr.d_validpacket = true; ++t_Counters.at(rec::Counter::cookieRetry); - VLOG(log, "Server " << localip.toString() << " returned BADCOOKIE " << endl); + VLOG(log, "Server " << localip.d_address.toString() << " returned BADCOOKIE " << endl); return {true, LWResult::Result::BadCookie}; // We did update the entry, retry should succeed } } else { if (!doTCP) { // Server responded with a wrong client cookie, fall back to TCP, RFC 7873 5.3 - VLOG(log, "Server " << localip.toString() << " responded with wrong client cookie, fall back to TCP" << endl); + VLOG(log, "Server " << localip.d_address.toString() << " responded with wrong client cookie, fall back to TCP" << endl); lwr.d_validpacket = true; ++t_Counters.at(rec::Counter::cookieMismatchedOverUDP); return {true, LWResult::Result::Spoofed}; } // mismatched cookie when already doing TCP, ignore that - VLOG(log, "Server " << localip.toString() << " responded with wrong client cookie over TCP, ignoring that" << endl); + VLOG(log, "Server " << localip.d_address.toString() << " responded with wrong client cookie over TCP, ignoring that" << endl); ++t_Counters.at(rec::Counter::cookieMismatchedOverTCP); } } @@ -627,7 +627,7 @@ static LWResult::Result asyncresolve(const OptLog& log, const ComboAddress& addr pw.getHeader()->cd = (sendRDQuery && g_dnssecmode != DNSSECMode::Off); std::optional subnetOpts = std::nullopt; - std::optional addressToBindTo; + std::optional addressToBindTo; std::optional cookieSentOut; if (EDNS0Level > 0) { @@ -745,7 +745,7 @@ static LWResult::Result asyncresolve(const OptLog& log, const ComboAddress& addr // Cookie info already has been added to packet, so we must retry from a higher level auto lock = s_cookiestore.lock(); lock->erase(address); - VLOG(log, "BindError remote: " << address.toString() << " localAddress: " << (addressToBindTo ? addressToBindTo->toString() : "none") << endl); + VLOG(log, "BindError remote: " << address.toString() << " localAddress: " << (addressToBindTo ? addressToBindTo->d_address.toString() : "none") << endl); return LWResult::Result::BindError; } catch (const NetworkError& nwe) { @@ -874,7 +874,7 @@ static LWResult::Result asyncresolve(const OptLog& log, const ComboAddress& addr } } if (g_cookies && cookieSentOut && !*chained) { - auto [done, result] = incomingCookie(log, address, localip, *now, cookieSentOut, edo, doTCP, *lwr, cookieFoundInReply); + auto [done, result] = incomingCookie(log, address, {localip, std::nullopt}, *now, cookieSentOut, edo, doTCP, *lwr, cookieFoundInReply); if (done) { return result; } diff --git a/pdns/recursordist/lwres.hh b/pdns/recursordist/lwres.hh index d997ba71a5..aae4cbbad0 100644 --- a/pdns/recursordist/lwres.hh +++ b/pdns/recursordist/lwres.hh @@ -28,6 +28,7 @@ #include "pdnsexception.hh" #include "noinitvector.hh" #include "remote_logger.hh" +#include "query-local-address.hh" class FrameStreamLogger; struct DNSRecord; @@ -81,7 +82,7 @@ public: class EDNSSubnetOpts; LWResult::Result asendto(const void* data, size_t len, const ComboAddress& toAddress, - std::optional& localAddress, uint16_t qid, + std::optional& localAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, const std::optional& ecs, int* fileDesc, timeval& now); LWResult::Result arecvfrom(PacketBuffer& packet, const ComboAddress& fromAddr, size_t& len, uint16_t qid, const DNSName& domain, uint16_t qtype, int fileDesc, const std::optional& ecs, const struct timeval& now); diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 8b9496c17e..890ecccfae 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -100,7 +100,7 @@ GlobalStateHolder g_dontThrottleNetmasks; GlobalStateHolder g_DoTToAuthNames; uint64_t g_latencyStatSize; -LWResult::Result UDPClientSocks::getSocket(const ComboAddress& toaddr, const std::optional& localAddress, int* fileDesc) +LWResult::Result UDPClientSocks::getSocket(const ComboAddress& toaddr, const std::optional& localAddress, int* fileDesc) { *fileDesc = makeClientSocket(toaddr.sin4.sin_family, localAddress); if (*fileDesc < 0) { // temporary error - receive exception otherwise @@ -148,7 +148,7 @@ void UDPClientSocks::returnSocket(int fileDesc) } // returns -1 for errors which might go away, throws for ones that won't -int UDPClientSocks::makeClientSocket(int family, const std::optional& localAddress) +int UDPClientSocks::makeClientSocket(int family, const std::optional& localAddress) { int ret = socket(family, SOCK_DGRAM, 0); // turns out that setting CLO_EXEC and NONBLOCK from here is not a performance win on Linux (oddly enough) @@ -183,11 +183,11 @@ int UDPClientSocks::makeClientSocket(int family, const std::optionald_address; sin.setPort(port); } else { - sin = pdns::getQueryLocalAddress(family, port); // does htons for us + sin = pdns::getQueryLocalAddress(family, port).d_address; // does htons for us } if (::bind(ret, reinterpret_cast(&sin), sin.getSocklen()) >= 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) break; @@ -240,7 +240,7 @@ PacketBuffer GenUDPQueryResponse(const ComboAddress& dest, const string& query) { Socket socket(dest.sin4.sin_family, SOCK_DGRAM); socket.setNonBlocking(); - ComboAddress local = pdns::getQueryLocalAddress(dest.sin4.sin_family, 0); + ComboAddress local = pdns::getQueryLocalAddress(dest.sin4.sin_family, 0).d_address; socket.bind(local); socket.connect(dest); @@ -285,7 +285,7 @@ unsigned int authWaitTimeMSec(const std::unique_ptr& mtasker) /* these two functions are used by LWRes */ LWResult::Result asendto(const void* data, size_t len, - const ComboAddress& toAddress, std::optional& localAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, const std::optional& ecs, int* fileDesc, timeval& now) + const ComboAddress& toAddress, std::optional& localAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, const std::optional& ecs, int* fileDesc, timeval& now) { auto pident = std::make_shared(); diff --git a/pdns/recursordist/rec-cookiestore.cc b/pdns/recursordist/rec-cookiestore.cc index 37a63741c9..1a5dd2c9c5 100644 --- a/pdns/recursordist/rec-cookiestore.cc +++ b/pdns/recursordist/rec-cookiestore.cc @@ -48,7 +48,7 @@ uint64_t CookieStore::dump(int fileDesc) const timebuf_t tmp; fprintf(filePtr.get(), "%s\t%s\t%s\t%s\t%s\n", entry.d_address.toStringWithPortExcept(53).c_str(), - entry.d_localaddress.isUnspecified() ? "-" : entry.d_localaddress.toString().c_str(), + entry.d_localaddress.d_address.isUnspecified() ? "-" : entry.d_localaddress.d_address.toString().c_str(), entry.d_support == CookieEntry::Support::Unsupported ? "-" : entry.d_cookie.toDisplayString().c_str(), CookieEntry::toString(entry.d_support).c_str(), entry.d_lastused == std::numeric_limits::max() ? "Forever" : timestamp(entry.d_lastused, tmp)); diff --git a/pdns/recursordist/rec-cookiestore.hh b/pdns/recursordist/rec-cookiestore.hh index 00d8025968..a89e850768 100644 --- a/pdns/recursordist/rec-cookiestore.hh +++ b/pdns/recursordist/rec-cookiestore.hh @@ -46,6 +46,7 @@ #include "iputils.hh" #include "ednscookies.hh" +#include "query-local-address.hh" using namespace ::boost::multi_index; @@ -88,7 +89,7 @@ struct CookieEntry } ComboAddress d_address; - mutable ComboAddress d_localaddress; // The address we were bound to, see RFC 9018 + mutable pdns::AddressAndInterface d_localaddress; // The address we were bound to, see RFC 9018 mutable EDNSCookiesOpt d_cookie; // Contains both client and server cookie mutable time_t d_lastused{}; mutable Support d_support{Support::Unsupported}; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index c95aeb005d..547a328734 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1851,13 +1851,13 @@ static int initSyncRes(Logr::log_t log) Netmask netmask; bool done = false; - auto addr = pdns::getNonAnyQueryLocalAddress(AF_INET); + auto addr = pdns::getNonAnyQueryLocalAddress(AF_INET).d_address; if (addr.sin4.sin_family != 0) { netmask = Netmask(addr, 32); done = true; } if (!done) { - addr = pdns::getNonAnyQueryLocalAddress(AF_INET6); + addr = pdns::getNonAnyQueryLocalAddress(AF_INET6).d_address; if (addr.sin4.sin_family != 0) { netmask = Netmask(addr, 128); done = true; diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index 5d388f2bae..66aa0860fe 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -153,7 +153,7 @@ extern DoneRunning g_doneRunning; class UDPClientSocks { public: - LWResult::Result getSocket(const ComboAddress& toaddr, const std::optional& localAddress, int* fileDesc); + LWResult::Result getSocket(const ComboAddress& toaddr, const std::optional& localAddress, int* fileDesc); // return a socket to the pool, or simply erase it void returnSocket(int fileDesc); @@ -161,7 +161,7 @@ public: private: unsigned int d_numsocks{0}; // returns -1 for errors which might go away, throws for ones that won't - static int makeClientSocket(int family, const std::optional& localAddress); + static int makeClientSocket(int family, const std::optional& localAddress); }; enum class PaddingMode : uint8_t diff --git a/pdns/recursordist/rec-tcpout.hh b/pdns/recursordist/rec-tcpout.hh index df88b406ce..685c56018f 100644 --- a/pdns/recursordist/rec-tcpout.hh +++ b/pdns/recursordist/rec-tcpout.hh @@ -24,6 +24,7 @@ #include "iputils.hh" #include "tcpiohandler.hh" +#include "query-local-address.hh" namespace pdns::rust::settings::rec { @@ -53,13 +54,13 @@ public: } std::shared_ptr d_handler; - std::optional d_local; + std::optional d_local; timeval d_last_used{0, 0}; size_t d_numqueries{0}; bool d_verboseLogging{false}; }; - using endpoints_t = std::pair>; + using endpoints_t = std::pair>; void store(const struct timeval& now, const endpoints_t& endpoints, Connection&& connection); Connection get(const endpoints_t& pair); diff --git a/pdns/recursordist/rec-xfr.cc b/pdns/recursordist/rec-xfr.cc index 7f75f30ab3..a4e30bbfe2 100644 --- a/pdns/recursordist/rec-xfr.cc +++ b/pdns/recursordist/rec-xfr.cc @@ -180,7 +180,7 @@ static shared_ptr loadZoneFromServer(Logr::log_t plogger ComboAddress local(localAddress); if (local == ComboAddress()) { - local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); + local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0).d_address; } AXFRRetriever axfr(logger, primary, zoneName, tsigTriplet, &local, maxReceivedBytes, axfrTimeout); @@ -331,7 +331,7 @@ bool FWCatZoneXFR::zoneTrackerIteration(const DNSName& zoneName, std::shared_ptr ComboAddress local(d_params.localAddress); if (local == ComboAddress()) { - local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); + local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0).d_address; } try { diff --git a/pdns/recursordist/rec-zonetocache.cc b/pdns/recursordist/rec-zonetocache.cc index 04e460c917..4730fd32e4 100644 --- a/pdns/recursordist/rec-zonetocache.cc +++ b/pdns/recursordist/rec-zonetocache.cc @@ -146,7 +146,7 @@ pdns::ZoneMD::Result ZoneData::getByAXFR(const RecZoneToCache::Config& config, p const TSIGTriplet tsigTriplet = config.d_tt; ComboAddress local = config.d_local; if (local == ComboAddress()) { - local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); + local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0).d_address; } AXFRRetriever axfr(d_log, primary, d_zone, tsigTriplet, &local, maxReceivedBytes, axfrTimeout); diff --git a/pdns/recursordist/rpzloader.cc b/pdns/recursordist/rpzloader.cc index 4a9c2fe038..7bf7486346 100644 --- a/pdns/recursordist/rpzloader.cc +++ b/pdns/recursordist/rpzloader.cc @@ -253,7 +253,7 @@ static shared_ptr loadRPZFromServer(Logr::log_t plogger, ComboAddress local(localAddress); if (local == ComboAddress()) { - local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); + local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0).d_address; } AXFRRetriever axfr(logger, primary, zoneName, tsigTriplet, &local, maxReceivedBytes, axfrTimeout); @@ -568,7 +568,7 @@ static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneNam ComboAddress local(params.zoneXFRParams.localAddress); if (local == ComboAddress()) { - local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); + local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0).d_address; } try { diff --git a/pdns/resolver.cc b/pdns/resolver.cc index 05c0446acf..27c5118cf9 100644 --- a/pdns/resolver.cc +++ b/pdns/resolver.cc @@ -103,10 +103,10 @@ Resolver::Resolver(Logr::log_t slog) : d_slog(slog) locals["default6"] = -1; try { if (pdns::isQueryLocalAddressFamilyEnabled(AF_INET)) { - locals["default4"] = makeQuerySocket(pdns::getQueryLocalAddress(AF_INET, 0), true, ::arg().mustDo("non-local-bind")); + locals["default4"] = makeQuerySocket(pdns::getQueryLocalAddress(AF_INET, 0).d_address, true, ::arg().mustDo("non-local-bind")); } if (pdns::isQueryLocalAddressFamilyEnabled(AF_INET6)) { - locals["default6"] = makeQuerySocket(pdns::getQueryLocalAddress(AF_INET6, 0), true, ::arg().mustDo("non-local-bind")); + locals["default6"] = makeQuerySocket(pdns::getQueryLocalAddress(AF_INET6, 0).d_address, true, ::arg().mustDo("non-local-bind")); } } catch(...) {