diff options
| author | Alexander Rutkovsky <[email protected]> | 2022-06-01 02:44:57 +0300 | 
|---|---|---|
| committer | Alexander Rutkovsky <[email protected]> | 2022-06-01 02:44:57 +0300 | 
| commit | 355c1d13d2b6783e59de81735dd9d6d71d5a27bb (patch) | |
| tree | 1d8010884229e0cd51824d44b3b392515c4a38ef /library/cpp | |
| parent | 1f8fed0d87db2306d61b41c0dfb7b33ce7417341 (diff) | |
Support for automatic IPv6/v4 selection in IC KIKIMR-14977
ref:9fc307f23e6bd58288b342be1ced17b0f82fbb9a
Diffstat (limited to 'library/cpp')
5 files changed, 59 insertions, 38 deletions
| diff --git a/library/cpp/actors/interconnect/interconnect_address.h b/library/cpp/actors/interconnect/interconnect_address.h index e9e0faec814..5a78193abbc 100644 --- a/library/cpp/actors/interconnect/interconnect_address.h +++ b/library/cpp/actors/interconnect/interconnect_address.h @@ -25,5 +25,21 @@ namespace NInterconnect {          ui16 GetPort() const;          TString GetAddress() const;          TString ToString() const; + +        static TAddress AnyIPv4(ui16 port) { +            TAddress res; +            res.Addr.Ipv4.sin_family = AF_INET; +            res.Addr.Ipv4.sin_port = htons(port); +            res.Addr.Ipv4.sin_addr.s_addr = htonl(INADDR_ANY); +            return res; +        } + +        static TAddress AnyIPv6(ui16 port) { +            TAddress res; +            res.Addr.Ipv6.sin6_family = AF_INET6; +            res.Addr.Ipv6.sin6_port = htons(port); +            res.Addr.Ipv6.sin6_addr = in6addr_any; +            return res; +        }      };  } diff --git a/library/cpp/actors/interconnect/interconnect_stream.cpp b/library/cpp/actors/interconnect/interconnect_stream.cpp index 158ebc9e1d5..ad46453acb7 100644 --- a/library/cpp/actors/interconnect/interconnect_stream.cpp +++ b/library/cpp/actors/interconnect/interconnect_stream.cpp @@ -92,11 +92,14 @@ namespace NInterconnect {      ///////////////////////////////////////////////////////////////// -    TIntrusivePtr<TStreamSocket> TStreamSocket::Make(int domain) { +    TIntrusivePtr<TStreamSocket> TStreamSocket::Make(int domain, int *error) {          const SOCKET res = ::socket(domain, SOCK_STREAM | SOCK_NONBLOCK, 0);          if (res == -1) {              const int err = LastSocketError();              Y_VERIFY(err != EMFILE && err != ENFILE); +            if (error) { +                *error = err; +            }          }          return MakeIntrusive<TStreamSocket>(res);      } diff --git a/library/cpp/actors/interconnect/interconnect_stream.h b/library/cpp/actors/interconnect/interconnect_stream.h index 074adc6e74c..3ba7914f775 100644 --- a/library/cpp/actors/interconnect/interconnect_stream.h +++ b/library/cpp/actors/interconnect/interconnect_stream.h @@ -46,7 +46,7 @@ namespace NInterconnect {      public:          TStreamSocket(SOCKET fd); -        static TIntrusivePtr<TStreamSocket> Make(int domain); +        static TIntrusivePtr<TStreamSocket> Make(int domain, int *error = nullptr);          virtual ssize_t Send(const void* msg, size_t len, TString *err = nullptr) const;          virtual ssize_t Recv(void* buf, size_t len, TString *err = nullptr) const; diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp index b95c994598d..aad8677ca46 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp +++ b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp @@ -10,7 +10,8 @@ namespace NActors {      TInterconnectListenerTCP::TInterconnectListenerTCP(const TString& address, ui16 port, TInterconnectProxyCommon::TPtr common, const TMaybe<SOCKET>& socket)          : TActor(&TThis::Initial)          , TInterconnectLoggingBase(Sprintf("ICListener: %s", SelfId().ToString().data())) -        , Address(address.c_str(), port) +        , Address(address) +        , Port(port)          , Listener(              socket              ? new NInterconnect::TStreamSocket(*socket) @@ -33,54 +34,54 @@ namespace NActors {      }      int TInterconnectListenerTCP::Bind() { -        NInterconnect::TAddress addr = Address; - -        if (ProxyCommonCtx->Settings.BindOnAllAddresses) { -            switch (addr.GetFamily()) { -                case AF_INET: { -                    auto *sa = reinterpret_cast<sockaddr_in*>(addr.SockAddr()); -                    sa->sin_addr = {INADDR_ANY}; -                    break; -                } - -                case AF_INET6: { -                    auto *sa = reinterpret_cast<sockaddr_in6*>(addr.SockAddr()); -                    sa->sin6_addr = in6addr_any; -                    break; -                } - -                default: -                    Y_FAIL("Unsupported address family"); +        auto doTry = [&](NInterconnect::TAddress addr) { +            int error; +            Listener = NInterconnect::TStreamSocket::Make(addr.GetFamily(), &error); +            if (*Listener == -1) { +                return error;              } -        } +            SetNonBlock(*Listener); +            Listener->SetSendBufferSize(ProxyCommonCtx->Settings.GetSendBufferSize()); // TODO(alexvru): WTF? +            SetSockOpt(*Listener, SOL_SOCKET, SO_REUSEADDR, 1); +            if (addr.GetFamily() == AF_INET6) { +                SetSockOpt(*Listener, IPPROTO_IPV6, IPV6_V6ONLY, 0); +            } +            if (const auto e = -Listener->Bind(addr)) { +                return e; +            } else if (const auto e = -Listener->Listen(SOMAXCONN)) { +                return e; +            } else { +                return 0; +            } +        }; -        Listener = NInterconnect::TStreamSocket::Make(addr.GetFamily()); -        if (*Listener == -1) { -            return errno; -        } -        SetNonBlock(*Listener); -        Listener->SetSendBufferSize(ProxyCommonCtx->Settings.GetSendBufferSize()); // TODO(alexvru): WTF? -        SetSockOpt(*Listener, SOL_SOCKET, SO_REUSEADDR, 1); -        if (const auto e = -Listener->Bind(addr)) { -            return e; -        } else if (const auto e = -Listener->Listen(SOMAXCONN)) { -            return e; +        if (Address) { +            NInterconnect::TAddress addr(Address, Port); +            if (ProxyCommonCtx->Settings.BindOnAllAddresses) { +                addr = addr.GetFamily() == AF_INET ? NInterconnect::TAddress::AnyIPv4(Port) : +                    addr.GetFamily() == AF_INET6 ? NInterconnect::TAddress::AnyIPv6(Port) : addr; +            } +            return doTry(addr);          } else { -            return 0; +            int error = doTry(NInterconnect::TAddress::AnyIPv6(Port)); +            if (error == EAFNOSUPPORT || error == EPROTONOSUPPORT) { +                error = doTry(NInterconnect::TAddress::AnyIPv4(Port)); +            } +            return error;          }      }      void TInterconnectListenerTCP::Bootstrap(const TActorContext& ctx) {          if (!Listener) {              if (const int err = Bind()) { -                LOG_ERROR_IC("ICL01", "Bind failed: %s (%s)", strerror(err), Address.ToString().data()); +                LOG_ERROR_IC("ICL01", "Bind failed: %s (%s:%u)", strerror(err), Address.data(), Port);                  Listener.Reset();                  Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap);                  return;              }          }          if (const auto& callback = ProxyCommonCtx->InitWhiteboard) { -            callback(Address.GetPort(), TlsActivationContext->ExecutorThread.ActorSystem); +            callback(Port, TlsActivationContext->ExecutorThread.ActorSystem);          }          const bool success = ctx.Send(MakePollerActorId(), new TEvPollerRegister(Listener, SelfId(), {}));          Y_VERIFY(success); @@ -103,7 +104,7 @@ namespace NActors {                  continue;              } else if (-r != EAGAIN && -r != EWOULDBLOCK) {                  Y_VERIFY(-r != ENFILE && -r != EMFILE && !ExternalSocket); -                LOG_ERROR_IC("ICL06", "Listen failed: %s (%s)", strerror(-r), Address.ToString().data()); +                LOG_ERROR_IC("ICL06", "Listen failed: %s (%s:%u)", strerror(-r), Address.data(), Port);                  Listener.Reset();                  PollerToken.Reset();                  Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap); diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.h b/library/cpp/actors/interconnect/interconnect_tcp_server.h index fc71073c2df..d3538940b70 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_server.h +++ b/library/cpp/actors/interconnect/interconnect_tcp_server.h @@ -43,7 +43,8 @@ namespace NActors {          void Process(const TActorContext& ctx); -        const NInterconnect::TAddress Address; +        const TString Address; +        const ui16 Port;          TIntrusivePtr<NInterconnect::TStreamSocket> Listener;          const bool ExternalSocket;          TPollerToken::TPtr PollerToken; | 
