diff options
author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/actors/interconnect/interconnect_resolve.cpp |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/actors/interconnect/interconnect_resolve.cpp')
-rw-r--r-- | library/cpp/actors/interconnect/interconnect_resolve.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/library/cpp/actors/interconnect/interconnect_resolve.cpp b/library/cpp/actors/interconnect/interconnect_resolve.cpp new file mode 100644 index 00000000000..14296194df9 --- /dev/null +++ b/library/cpp/actors/interconnect/interconnect_resolve.cpp @@ -0,0 +1,174 @@ +#include "interconnect.h" +#include "interconnect_address.h" +#include "events_local.h" + +#include <library/cpp/actors/core/actor_bootstrapped.h> +#include <library/cpp/actors/core/hfunc.h> +#include <library/cpp/actors/dnsresolver/dnsresolver.h> + +namespace NActors { + + using namespace NActors::NDnsResolver; + + class TInterconnectResolveActor : public TActorBootstrapped<TInterconnectResolveActor> { + public: + TInterconnectResolveActor( + const TString& host, ui16 port, ui32 nodeId, const TString& defaultAddress, + const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline) + : Host(host) + , NodeId(nodeId) + , Port(port) + , DefaultAddress(defaultAddress) + , ReplyTo(replyTo) + , ReplyFrom(replyFrom) + , Deadline(deadline) + { } + + TInterconnectResolveActor( + const TString& host, ui16 port, + const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline) + : Host(host) + , Port(port) + , ReplyTo(replyTo) + , ReplyFrom(replyFrom) + , Deadline(deadline) + { } + + static constexpr EActivityType ActorActivityType() { + return NAMESERVICE; + } + + void Bootstrap() { + TMaybe<TString> errorText; + if (auto addr = ExtractDefaultAddr(errorText)) { + return SendAddrAndDie(std::move(addr)); + } + + if (errorText) { + SendErrorAndDie(*errorText); + } + + auto now = TActivationContext::Now(); + if (Deadline < now) { + SendErrorAndDie("Deadline"); + return; + } + + Send(MakeDnsResolverActorId(), + new TEvDns::TEvGetAddr(Host, AF_UNSPEC), + IEventHandle::FlagTrackDelivery); + + if (Deadline != TInstant::Max()) { + Schedule(Deadline, new TEvents::TEvWakeup); + } + + Become(&TThis::StateWork); + } + + STRICT_STFUNC(StateWork, { + sFunc(TEvents::TEvWakeup, HandleTimeout); + sFunc(TEvents::TEvUndelivered, HandleUndelivered); + hFunc(TEvDns::TEvGetAddrResult, Handle); + }); + + void HandleTimeout() { + SendErrorAndDie("Deadline"); + } + + void HandleUndelivered() { + SendErrorAndDie("Dns resolver is unavailable"); + } + + void Handle(TEvDns::TEvGetAddrResult::TPtr& ev) { + if (auto addr = ExtractAddr(ev->Get())) { + return SendAddrAndDie(std::move(addr)); + } + + SendErrorAndDie(ev->Get()->ErrorText); + } + + void SendAddrAndDie(NAddr::IRemoteAddrPtr addr) { + if (NodeId) { + auto reply = new TEvLocalNodeInfo; + reply->NodeId = *NodeId; + reply->Address = std::move(addr); + TActivationContext::Send(new IEventHandle(ReplyTo, ReplyFrom, reply)); + } else { + auto reply = new TEvAddressInfo; + reply->Address = std::move(addr); + TActivationContext::Send(new IEventHandle(ReplyTo, ReplyFrom, reply)); + } + PassAway(); + } + + void SendErrorAndDie(const TString& errorText) { + auto *event = new TEvResolveError; + event->Explain = errorText; + TActivationContext::Send(new IEventHandle(ReplyTo, ReplyFrom, event)); + PassAway(); + } + + NAddr::IRemoteAddrPtr ExtractAddr(TEvDns::TEvGetAddrResult* msg) { + if (msg->Status == 0) { + if (msg->IsV6()) { + struct sockaddr_in6 sin6; + Zero(sin6); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = msg->GetAddrV6(); + sin6.sin6_port = HostToInet(Port); + return MakeHolder<NAddr::TIPv6Addr>(sin6); + } + + if (msg->IsV4()) { + return MakeHolder<NAddr::TIPv4Addr>(TIpAddress(msg->GetAddrV4().s_addr, Port)); + } + + Y_FAIL("Unexpected result address family"); + } + + return nullptr; + } + + NAddr::IRemoteAddrPtr ExtractDefaultAddr(TMaybe<TString>& errorText) { + if (DefaultAddress) { + NInterconnect::TAddress address(DefaultAddress.data(), Port); + + switch (address.GetFamily()) { + case AF_INET: + return MakeHolder<NAddr::TIPv4Addr>(*(sockaddr_in*)address.SockAddr()); + case AF_INET6: + return MakeHolder<NAddr::TIPv6Addr>(*(sockaddr_in6*)address.SockAddr()); + default: + errorText = "Unsupported default address: " + DefaultAddress; + break; + } + } + + return nullptr; + } + + private: + const TString Host; + const std::optional<ui32> NodeId; + const ui16 Port; + const TString DefaultAddress; + const TActorId ReplyTo; + const TActorId ReplyFrom; + const TInstant Deadline; + }; + + IActor* CreateResolveActor( + const TString& host, ui16 port, ui32 nodeId, const TString& defaultAddress, + const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline) + { + return new TInterconnectResolveActor(host, port, nodeId, defaultAddress, replyTo, replyFrom, deadline); + } + + IActor* CreateResolveActor( + const TString& host, ui16 port, + const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline) + { + return new TInterconnectResolveActor(host, port, replyTo, replyFrom, deadline); + } + +} // namespace NActors |