summaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
diff options
context:
space:
mode:
authorarcadia-devtools <[email protected]>2022-06-24 17:01:11 +0300
committerarcadia-devtools <[email protected]>2022-06-24 17:01:11 +0300
commit45ad9f6d8690a224820723ce2fe7cad1110c35f4 (patch)
tree316e3a8422df14c80f09830b0219f475c848bdc1 /library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
parent0796a2f91010abe8890cee7570eb2f61efab27c7 (diff)
intermediate changes
ref:66616c49c927fd0dbf4d07a83fea6830e84016a3
Diffstat (limited to 'library/cpp/actors/dnsresolver/dnsresolver_caching.cpp')
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver_caching.cpp376
1 files changed, 170 insertions, 206 deletions
diff --git a/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp b/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
index 02760f4c275..a7e38806c03 100644
--- a/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
+++ b/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
@@ -15,10 +15,13 @@ namespace NDnsResolver {
struct TMonCounters {
NMonitoring::TDynamicCounters::TCounterPtr OutgoingInFlightV4;
NMonitoring::TDynamicCounters::TCounterPtr OutgoingInFlightV6;
+ NMonitoring::TDynamicCounters::TCounterPtr OutgoingInFlightUnspec;
NMonitoring::TDynamicCounters::TCounterPtr OutgoingErrorsV4;
NMonitoring::TDynamicCounters::TCounterPtr OutgoingErrorsV6;
+ NMonitoring::TDynamicCounters::TCounterPtr OutgoingErrorsUnspec;
NMonitoring::TDynamicCounters::TCounterPtr OutgoingTotalV4;
NMonitoring::TDynamicCounters::TCounterPtr OutgoingTotalV6;
+ NMonitoring::TDynamicCounters::TCounterPtr OutgoingTotalUnspec;
NMonitoring::TDynamicCounters::TCounterPtr IncomingInFlight;
NMonitoring::TDynamicCounters::TCounterPtr IncomingErrors;
@@ -31,10 +34,13 @@ namespace NDnsResolver {
TMonCounters(const NMonitoring::TDynamicCounterPtr& counters)
: OutgoingInFlightV4(counters->GetCounter("DnsResolver/Outgoing/InFlight/V4", false))
, OutgoingInFlightV6(counters->GetCounter("DnsResolver/Outgoing/InFlight/V6", false))
+ , OutgoingInFlightUnspec(counters->GetCounter("DnsResolver/Outgoing/InFlight/Unspec", false))
, OutgoingErrorsV4(counters->GetCounter("DnsResolver/Outgoing/Errors/V4", true))
, OutgoingErrorsV6(counters->GetCounter("DnsResolver/Outgoing/Errors/V6", true))
+ , OutgoingErrorsUnspec(counters->GetCounter("DnsResolver/Outgoing/Errors/Unspec", true))
, OutgoingTotalV4(counters->GetCounter("DnsResolver/Outgoing/Total/V4", true))
, OutgoingTotalV6(counters->GetCounter("DnsResolver/Outgoing/Total/V6", true))
+ , OutgoingTotalUnspec(counters->GetCounter("DnsResolver/Outgoing/Total/Unspec", true))
, IncomingInFlight(counters->GetCounter("DnsResolver/Incoming/InFlight", false))
, IncomingErrors(counters->GetCounter("DnsResolver/Incoming/Errors", true))
, IncomingTotal(counters->GetCounter("DnsResolver/Incoming/Total", true))
@@ -42,6 +48,45 @@ namespace NDnsResolver {
, CacheHits(counters->GetCounter("DnsResolver/Cache/Hits", true))
, CacheMisses(counters->GetCounter("DnsResolver/Cache/Misses", true))
{ }
+
+ const NMonitoring::TDynamicCounters::TCounterPtr& OutgoingInFlightByFamily(int family) const {
+ switch (family) {
+ case AF_INET:
+ return OutgoingInFlightV4;
+ case AF_INET6:
+ return OutgoingInFlightV6;
+ case AF_UNSPEC:
+ return OutgoingInFlightUnspec;
+ default:
+ Y_FAIL("Unexpected family %d", family);
+ }
+ }
+
+ const NMonitoring::TDynamicCounters::TCounterPtr& OutgoingErrorsByFamily(int family) const {
+ switch (family) {
+ case AF_INET:
+ return OutgoingErrorsV4;
+ case AF_INET6:
+ return OutgoingErrorsV6;
+ case AF_UNSPEC:
+ return OutgoingErrorsUnspec;
+ default:
+ Y_FAIL("Unexpected family %d", family);
+ }
+ }
+
+ const NMonitoring::TDynamicCounters::TCounterPtr& OutgoingTotalByFamily(int family) const {
+ switch (family) {
+ case AF_INET:
+ return OutgoingTotalV4;
+ case AF_INET6:
+ return OutgoingTotalV6;
+ case AF_UNSPEC:
+ return OutgoingTotalUnspec;
+ default:
+ Y_FAIL("Unexpected family %d", family);
+ }
+ }
};
public:
@@ -97,19 +142,13 @@ namespace NDnsResolver {
WaitingRequests.erase(waitingIt);
switch (waitingInfo.Family) {
+ case AF_UNSPEC:
case AF_INET6:
- if (ev->Get()->Status) {
- ProcessErrorV6(waitingInfo.Position, ev->Get()->Status, std::move(ev->Get()->ErrorText));
- } else {
- ProcessAddrsV6(waitingInfo.Position, std::move(ev->Get()->AddrsV6));
- }
- break;
-
case AF_INET:
if (ev->Get()->Status) {
- ProcessErrorV4(waitingInfo.Position, ev->Get()->Status, std::move(ev->Get()->ErrorText));
+ ProcessError(waitingInfo.Family, waitingInfo.Position, ev->Get()->Status, std::move(ev->Get()->ErrorText));
} else {
- ProcessAddrsV4(waitingInfo.Position, std::move(ev->Get()->AddrsV4));
+ ProcessAddrs(waitingInfo.Family, waitingInfo.Position, std::move(ev->Get()->AddrsV6), std::move(ev->Get()->AddrsV4));
}
break;
@@ -127,12 +166,12 @@ namespace NDnsResolver {
WaitingRequests.erase(waitingIt);
switch (waitingInfo.Family) {
+ case AF_UNSPEC:
case AF_INET6:
- ProcessErrorV6(waitingInfo.Position, ARES_ENOTINITIALIZED, "Caching dns resolver cannot deliver to the underlying resolver");
- break;
case AF_INET:
- ProcessErrorV4(waitingInfo.Position, ARES_ENOTINITIALIZED, "Caching dns resolver cannot deliver to the underlying resolver");
+ ProcessError(waitingInfo.Family, waitingInfo.Position, ARES_ENOTINITIALIZED, "Caching dns resolver cannot deliver to the underlying resolver");
break;
+
default:
Y_FAIL("Unexpected request family %d", waitingInfo.Family);
}
@@ -170,26 +209,30 @@ namespace NDnsResolver {
switch (req->Family) {
case AF_UNSPEC:
+ if (Options.AllowIPv6 && Options.AllowIPv4) {
+ EnqueueRequest(AF_UNSPEC, std::move(req));
+ return;
+ }
if (Options.AllowIPv6) {
- EnqueueRequestIPv6(std::move(req));
+ EnqueueRequest(AF_INET6, std::move(req));
return;
}
if (Options.AllowIPv4) {
- EnqueueRequestIPv4(std::move(req));
+ EnqueueRequest(AF_INET, std::move(req));
return;
}
break;
case AF_INET6:
if (Options.AllowIPv6) {
- EnqueueRequestIPv6(std::move(req));
+ EnqueueRequest(AF_INET6, std::move(req));
return;
}
break;
case AF_INET:
if (Options.AllowIPv4) {
- EnqueueRequestIPv4(std::move(req));
+ EnqueueRequest(AF_INET, std::move(req));
return;
}
break;
@@ -198,7 +241,7 @@ namespace NDnsResolver {
ReplyWithError(std::move(req), ARES_EBADFAMILY);
}
- void EnqueueRequestIPv6(THolder<TIncomingRequest> req) {
+ void EnqueueRequest(int family, THolder<TIncomingRequest> req) {
auto now = TActivationContext::Now();
auto& fullState = NameToState[req->Name];
@@ -206,72 +249,33 @@ namespace NDnsResolver {
*MonCounters->CacheSize = NameToState.size();
}
- auto& state = fullState.StateIPv6;
- EnsureRequest(state, req->Name, AF_INET6, now);
+ auto& state = fullState.StateByFamily(family);
+ EnsureRequest(state, req->Name, family, now);
if (state.IsHardExpired(now)) {
Y_VERIFY(state.Waiting);
if (MonCounters) {
++*MonCounters->CacheMisses;
}
- // We need to wait for ipv6 reply, schedule ipv4 request in parallel if needed
- if (Options.AllowIPv4) {
- EnsureRequest(fullState.StateIPv4, req->Name, AF_INET, now);
- }
state.WaitingRequests.PushBack(req.Release());
return;
}
- // We want to retry AF_UNSPEC with IPv4 in some cases
- if (req->Family == AF_UNSPEC && Options.AllowIPv4 && state.RetryUnspec()) {
- EnqueueRequestIPv4(std::move(req));
- return;
- }
-
- if (MonCounters) {
- ++*MonCounters->CacheHits;
- }
-
- if (state.Status != 0) {
- ReplyWithError(std::move(req), state.Status, state.ErrorText);
- } else {
- ReplyWithAddrs(std::move(req), fullState.AddrsIPv6);
- }
- }
-
- void EnqueueRequestIPv4(THolder<TIncomingRequest> req, bool isCacheMiss = false) {
- auto now = TActivationContext::Now();
-
- auto& fullState = NameToState[req->Name];
if (MonCounters) {
- *MonCounters->CacheSize = NameToState.size();
- }
-
- auto& state = fullState.StateIPv4;
- EnsureRequest(state, req->Name, AF_INET, now);
-
- if (state.IsHardExpired(now)) {
- Y_VERIFY(state.Waiting);
- if (MonCounters && !isCacheMiss) {
- ++*MonCounters->CacheMisses;
- }
- state.WaitingRequests.PushBack(req.Release());
- return;
- }
-
- if (MonCounters && !isCacheMiss) {
++*MonCounters->CacheHits;
}
if (state.Status != 0) {
ReplyWithError(std::move(req), state.Status, state.ErrorText);
} else {
- ReplyWithAddrs(std::move(req), fullState.AddrsIPv4);
+ ReplyWithAddrs(std::move(req), state.AddrsIPv6, state.AddrsIPv4);
}
}
private:
struct TFamilyState {
+ TVector<struct in6_addr> AddrsIPv6;
+ TVector<struct in_addr> AddrsIPv4;
TIncomingRequestList WaitingRequests;
TInstant SoftDeadline;
TInstant HardDeadline;
@@ -287,13 +291,6 @@ namespace NDnsResolver {
return InSoftHeap || InHardHeap || Waiting;
}
- bool RetryUnspec() const {
- return (
- Status == ARES_ENODATA ||
- Status == ARES_EBADRESP ||
- Status == ARES_ETIMEOUT);
- }
-
bool ServerReplied() const {
return ServerReplied(Status);
}
@@ -315,13 +312,38 @@ namespace NDnsResolver {
};
struct TState {
+ TFamilyState StateUnspec;
TFamilyState StateIPv6;
TFamilyState StateIPv4;
- TVector<struct in6_addr> AddrsIPv6;
- TVector<struct in_addr> AddrsIPv4;
bool Needed() const {
- return StateIPv6.Needed() || StateIPv4.Needed();
+ return StateUnspec.Needed() || StateIPv6.Needed() || StateIPv4.Needed();
+ }
+
+ const TFamilyState& StateByFamily(int family) const {
+ switch (family) {
+ case AF_UNSPEC:
+ return StateUnspec;
+ case AF_INET6:
+ return StateIPv6;
+ case AF_INET:
+ return StateIPv4;
+ default:
+ Y_FAIL("Unsupported family %d", family);
+ }
+ }
+
+ TFamilyState& StateByFamily(int family) {
+ switch (family) {
+ case AF_UNSPEC:
+ return StateUnspec;
+ case AF_INET6:
+ return StateIPv6;
+ case AF_INET:
+ return StateIPv4;
+ default:
+ Y_FAIL("Unsupported family %d", family);
+ }
}
};
@@ -366,16 +388,8 @@ namespace NDnsResolver {
}
if (MonCounters) {
- switch (family) {
- case AF_INET6:
- ++*MonCounters->OutgoingInFlightV6;
- ++*MonCounters->OutgoingTotalV6;
- break;
- case AF_INET:
- ++*MonCounters->OutgoingInFlightV4;
- ++*MonCounters->OutgoingTotalV4;
- break;
- }
+ ++*MonCounters->OutgoingInFlightByFamily(family);
+ ++*MonCounters->OutgoingTotalByFamily(family);
}
ui64 reqId = ++LastRequestId;
@@ -406,6 +420,14 @@ namespace NDnsResolver {
}
}
+ void PushSoftUnspec(TNameToState::iterator it, TInstant newDeadline) {
+ PushToHeap<&TState::StateUnspec, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapUnspec, it, newDeadline);
+ }
+
+ void PushHardUnspec(TNameToState::iterator it, TInstant newDeadline) {
+ PushToHeap<&TState::StateUnspec, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapUnspec, it, newDeadline);
+ }
+
void PushSoftV6(TNameToState::iterator it, TInstant newDeadline) {
PushToHeap<&TState::StateIPv6, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapIPv6, it, newDeadline);
}
@@ -422,162 +444,111 @@ namespace NDnsResolver {
PushToHeap<&TState::StateIPv4, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapIPv4, it, newDeadline);
}
- void ProcessErrorV6(TNameToState::iterator it, int status, TString errorText) {
- auto now = TActivationContext::Now();
- if (MonCounters) {
- --*MonCounters->OutgoingInFlightV6;
- ++*MonCounters->OutgoingErrorsV6;
- }
-
- auto& state = it->second.StateIPv6;
- Y_VERIFY(state.Waiting, "Got error for a state we are not waiting");
- state.Waiting = false;
-
- // When we have a cached positive reply, don't overwrite it with spurious errors
- const bool serverReplied = TFamilyState::ServerReplied(status);
- if (!serverReplied && state.ServerReplied() && !state.IsHardExpired(now)) {
- PushSoftV6(it, now + Options.SoftNegativeExpireTime);
- if (state.Status == ARES_SUCCESS) {
- SendAddrsV6(it);
- } else {
- SendErrorsV6(it, now);
- }
- return;
- }
-
- state.Status = status;
- state.ErrorText = std::move(errorText);
- PushSoftV6(it, now + Options.SoftNegativeExpireTime);
- if (serverReplied) {
- // Server actually replied, so keep it cached for longer
- PushHardV6(it, now + Options.HardPositiveExpireTime);
- } else {
- PushHardV6(it, now + Options.HardNegativeExpireTime);
+ void PushSoft(int family, TNameToState::iterator it, TInstant newDeadline) {
+ switch (family) {
+ case AF_UNSPEC:
+ PushSoftUnspec(it, newDeadline);
+ break;
+ case AF_INET6:
+ PushSoftV6(it, newDeadline);
+ break;
+ case AF_INET:
+ PushSoftV4(it, newDeadline);
+ break;
+ default:
+ Y_FAIL("Unexpected family %d", family);
}
-
- SendErrorsV6(it, now);
}
- void SendErrorsV6(TNameToState::iterator it, TInstant now) {
- bool cleaned = false;
- auto& state = it->second.StateIPv6;
- while (state.WaitingRequests) {
- THolder<TIncomingRequest> req(state.WaitingRequests.PopFront());
- if (req->Family == AF_UNSPEC && Options.AllowIPv4 && state.RetryUnspec()) {
- if (!cleaned) {
- CleanupExpired(now);
- cleaned = true;
- }
- EnqueueRequestIPv4(std::move(req), /* isCacheMiss */ true);
- } else {
- ReplyWithError(std::move(req), state.Status, state.ErrorText);
- }
+ void PushHard(int family, TNameToState::iterator it, TInstant newDeadline) {
+ switch (family) {
+ case AF_UNSPEC:
+ PushHardUnspec(it, newDeadline);
+ break;
+ case AF_INET6:
+ PushHardV6(it, newDeadline);
+ break;
+ case AF_INET:
+ PushHardV4(it, newDeadline);
+ break;
+ default:
+ Y_FAIL("Unexpected family %d", family);
}
}
- void ProcessErrorV4(TNameToState::iterator it, int status, TString errorText) {
+ void ProcessError(int family, TNameToState::iterator it, int status, TString errorText) {
auto now = TActivationContext::Now();
if (MonCounters) {
- --*MonCounters->OutgoingInFlightV4;
- ++*MonCounters->OutgoingErrorsV4;
+ --*MonCounters->OutgoingInFlightByFamily(family);
+ ++*MonCounters->OutgoingErrorsByFamily(family);
}
- auto& state = it->second.StateIPv4;
+ auto& state = it->second.StateByFamily(family);
Y_VERIFY(state.Waiting, "Got error for a state we are not waiting");
state.Waiting = false;
// When we have a cached positive reply, don't overwrite it with spurious errors
const bool serverReplied = TFamilyState::ServerReplied(status);
if (!serverReplied && state.ServerReplied() && !state.IsHardExpired(now)) {
- PushSoftV4(it, now + Options.SoftNegativeExpireTime);
+ PushSoft(family, it, now + Options.SoftNegativeExpireTime);
if (state.Status == ARES_SUCCESS) {
- SendAddrsV4(it);
+ SendAddrs(family, it);
} else {
- SendErrorsV4(it);
+ SendErrors(family, it);
}
return;
}
state.Status = status;
state.ErrorText = std::move(errorText);
- PushSoftV4(it, now + Options.SoftNegativeExpireTime);
+ PushSoft(family, it, now + Options.SoftNegativeExpireTime);
if (serverReplied) {
// Server actually replied, so keep it cached for longer
- PushHardV4(it, now + Options.HardPositiveExpireTime);
+ PushHard(family, it, now + Options.HardPositiveExpireTime);
} else {
- PushHardV4(it, now + Options.HardNegativeExpireTime);
+ PushHard(family, it, now + Options.HardNegativeExpireTime);
}
- SendErrorsV4(it);
+ SendErrors(family, it);
}
- void SendErrorsV4(TNameToState::iterator it) {
- auto& state = it->second.StateIPv4;
+ void SendErrors(int family, TNameToState::iterator it) {
+ auto& state = it->second.StateByFamily(family);
while (state.WaitingRequests) {
THolder<TIncomingRequest> req(state.WaitingRequests.PopFront());
ReplyWithError(std::move(req), state.Status, state.ErrorText);
}
}
- void ProcessAddrsV6(TNameToState::iterator it, TVector<struct in6_addr> addrs) {
- if (Y_UNLIKELY(addrs.empty())) {
- // Probably unnecessary: we don't want to deal with empty address lists
- return ProcessErrorV6(it, ARES_ENODATA, ares_strerror(ARES_ENODATA));
- }
-
- auto now = TActivationContext::Now();
- if (MonCounters) {
- --*MonCounters->OutgoingInFlightV6;
- }
-
- auto& state = it->second.StateIPv6;
- Y_VERIFY(state.Waiting, "Got reply for a state we are not waiting");
- state.Waiting = false;
-
- state.Status = ARES_SUCCESS;
- it->second.AddrsIPv6 = std::move(addrs);
- PushSoftV6(it, now + Options.SoftPositiveExpireTime);
- PushHardV6(it, now + Options.HardPositiveExpireTime);
-
- SendAddrsV6(it);
- }
-
- void SendAddrsV6(TNameToState::iterator it) {
- auto& state = it->second.StateIPv6;
- while (state.WaitingRequests) {
- THolder<TIncomingRequest> req(state.WaitingRequests.PopFront());
- ReplyWithAddrs(std::move(req), it->second.AddrsIPv6);
- }
- }
-
- void ProcessAddrsV4(TNameToState::iterator it, TVector<struct in_addr> addrs) {
- if (Y_UNLIKELY(addrs.empty())) {
+ void ProcessAddrs(int family, TNameToState::iterator it, TVector<struct in6_addr> addrs6, TVector<struct in_addr> addrs4) {
+ if (Y_UNLIKELY(addrs6.empty() && addrs4.empty())) {
// Probably unnecessary: we don't want to deal with empty address lists
- return ProcessErrorV4(it, ARES_ENODATA, ares_strerror(ARES_ENODATA));
+ return ProcessError(family, it, ARES_ENODATA, ares_strerror(ARES_ENODATA));
}
auto now = TActivationContext::Now();
if (MonCounters) {
- --*MonCounters->OutgoingInFlightV4;
+ --*MonCounters->OutgoingInFlightByFamily(family);
}
- auto& state = it->second.StateIPv4;
+ auto& state = it->second.StateByFamily(family);
Y_VERIFY(state.Waiting, "Got reply for a state we are not waiting");
state.Waiting = false;
state.Status = ARES_SUCCESS;
- it->second.AddrsIPv4 = std::move(addrs);
- PushSoftV4(it, now + Options.SoftPositiveExpireTime);
- PushHardV4(it, now + Options.HardPositiveExpireTime);
+ state.AddrsIPv6 = std::move(addrs6);
+ state.AddrsIPv4 = std::move(addrs4);
+ PushSoft(family, it, now + Options.SoftPositiveExpireTime);
+ PushHard(family, it, now + Options.HardPositiveExpireTime);
- SendAddrsV4(it);
+ SendAddrs(family, it);
}
- void SendAddrsV4(TNameToState::iterator it) {
- auto& state = it->second.StateIPv4;
+ void SendAddrs(int family, TNameToState::iterator it) {
+ auto& state = it->second.StateByFamily(family);
while (state.WaitingRequests) {
THolder<TIncomingRequest> req(state.WaitingRequests.PopFront());
- ReplyWithAddrs(std::move(req), it->second.AddrsIPv4);
+ ReplyWithAddrs(std::move(req), state.AddrsIPv6, state.AddrsIPv4);
}
}
@@ -619,6 +590,8 @@ namespace NDnsResolver {
}
void CleanupExpired(TInstant now) {
+ DoCleanupExpired<&TState::StateUnspec, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapUnspec, now);
+ DoCleanupExpired<&TState::StateUnspec, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapUnspec, now);
DoCleanupExpired<&TState::StateIPv6, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapIPv6, now);
DoCleanupExpired<&TState::StateIPv6, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapIPv6, now);
DoCleanupExpired<&TState::StateIPv4, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapIPv4, now);
@@ -649,36 +622,24 @@ namespace NDnsResolver {
}
}
- void ReplyWithAddrs(THolder<TIncomingRequest> req, const TVector<struct in6_addr>& addrs) {
- switch (req->Type) {
- case EIncomingRequestType::GetHostByName: {
- auto reply = MakeHolder<TEvDns::TEvGetHostByNameResult>();
- reply->AddrsV6 = addrs;
- Send(req->Sender, reply.Release(), 0, req->Cookie);
- break;
- }
- case EIncomingRequestType::GetAddr: {
- Y_VERIFY(!addrs.empty());
- auto reply = MakeHolder<TEvDns::TEvGetAddrResult>();
- reply->Addr = addrs.front();
- Send(req->Sender, reply.Release(), 0, req->Cookie);
- break;
- }
- }
- }
-
- void ReplyWithAddrs(THolder<TIncomingRequest> req, const TVector<struct in_addr>& addrs) {
+ void ReplyWithAddrs(THolder<TIncomingRequest> req, const TVector<struct in6_addr>& addrs6, const TVector<struct in_addr>& addrs4) {
switch (req->Type) {
case EIncomingRequestType::GetHostByName: {
auto reply = MakeHolder<TEvDns::TEvGetHostByNameResult>();
- reply->AddrsV4 = addrs;
+ reply->AddrsV6 = addrs6;
+ reply->AddrsV4 = addrs4;
Send(req->Sender, reply.Release(), 0, req->Cookie);
break;
}
case EIncomingRequestType::GetAddr: {
- Y_VERIFY(!addrs.empty());
auto reply = MakeHolder<TEvDns::TEvGetAddrResult>();
- reply->Addr = addrs.front();
+ if (!addrs6.empty()) {
+ reply->Addr = addrs6.front();
+ } else if (!addrs4.empty()) {
+ reply->Addr = addrs4.front();
+ } else {
+ Y_FAIL("Unexpected reply with empty address list");
+ }
Send(req->Sender, reply.Release(), 0, req->Cookie);
break;
}
@@ -698,6 +659,7 @@ namespace NDnsResolver {
void DropPending(int status, const TString& errorText) {
for (auto& [name, state] : NameToState) {
+ DropPending(state.StateUnspec.WaitingRequests, status, errorText);
DropPending(state.StateIPv6.WaitingRequests, status, errorText);
DropPending(state.StateIPv4.WaitingRequests, status, errorText);
}
@@ -713,6 +675,8 @@ namespace NDnsResolver {
const THolder<TMonCounters> MonCounters;
TNameToState NameToState;
+ TStateHeap<&TState::StateUnspec, &TFamilyState::SoftDeadline> SoftHeapUnspec;
+ TStateHeap<&TState::StateUnspec, &TFamilyState::HardDeadline> HardHeapUnspec;
TStateHeap<&TState::StateIPv6, &TFamilyState::SoftDeadline> SoftHeapIPv6;
TStateHeap<&TState::StateIPv6, &TFamilyState::HardDeadline> HardHeapIPv6;
TStateHeap<&TState::StateIPv4, &TFamilyState::SoftDeadline> SoftHeapIPv4;