summaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/interconnect/interconnect_resolve.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /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.cpp174
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