Convert grpc_ares_wrapper to C++ (#25108)

pull/25754/head
apolcyn 4 years ago committed by GitHub
parent 98fd4e1e36
commit 2ee70175bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  2. 78
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  3. 6
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
  4. 14
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
  5. 1749
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  6. 321
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  7. 6
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
  8. 6
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
  9. 6
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
  10. 28
      test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
  11. 33
      test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
  12. 38
      test/core/end2end/goaway_server_test.cc
  13. 52
      test/cpp/naming/address_sorting_test.cc
  14. 7
      test/cpp/naming/cancel_ares_query_test.cc
  15. 9
      test/cpp/naming/resolver_component_test.cc

@ -81,9 +81,8 @@ class AresDnsResolver : public Resolver {
void StartResolvingLocked();
static void OnNextResolution(void* arg, grpc_error* error);
static void OnResolved(void* arg, grpc_error* error);
void OnNextResolutionLocked(grpc_error* error);
void OnResolvedLocked(grpc_error* error);
void OnNextResolutionLocked(grpc_error* error);
/// DNS server to use (if not system default)
std::string dns_server_;
@ -107,11 +106,10 @@ class AresDnsResolver : public Resolver {
/// closures used by the work_serializer
grpc_closure on_next_resolution_;
grpc_closure on_resolved_;
/// are we currently resolving?
bool resolving_ = false;
/// the pending resolving request
grpc_ares_request* pending_request_ = nullptr;
OrphanablePtr<AresRequest> pending_request_;
/// next resolution timer
bool have_next_resolution_timer_ = false;
grpc_timer next_resolution_timer_;
@ -124,7 +122,7 @@ class AresDnsResolver : public Resolver {
/// currently resolving balancer addresses
std::unique_ptr<ServerAddressList> balancer_addresses_;
/// currently resolving service config
char* service_config_json_ = nullptr;
absl::optional<std::string> service_config_json_;
// has shutdown been initiated
bool shutdown_initiated_ = false;
};
@ -156,7 +154,6 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args)
// Closure initialization.
GRPC_CLOSURE_INIT(&on_next_resolution_, OnNextResolution, this,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&on_resolved_, OnResolved, this, grpc_schedule_on_exec_ctx);
}
AresDnsResolver::~AresDnsResolver() {
@ -188,9 +185,7 @@ void AresDnsResolver::ShutdownLocked() {
if (have_next_resolution_timer_) {
grpc_timer_cancel(&next_resolution_timer_);
}
if (pending_request_ != nullptr) {
grpc_cancel_ares_request_locked(pending_request_);
}
pending_request_.reset();
}
void AresDnsResolver::OnNextResolution(void* arg, grpc_error* error) {
@ -226,7 +221,7 @@ bool ValueInJsonArray(const Json::Array& array, const char* value) {
return false;
}
std::string ChooseServiceConfig(char* service_config_choice_json,
std::string ChooseServiceConfig(absl::string_view service_config_choice_json,
grpc_error** error) {
Json json = Json::Parse(service_config_choice_json, error);
if (*error != GRPC_ERROR_NONE) return "";
@ -305,18 +300,10 @@ std::string ChooseServiceConfig(char* service_config_choice_json,
return service_config->Dump();
}
void AresDnsResolver::OnResolved(void* arg, grpc_error* error) {
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg);
GRPC_ERROR_REF(error); // ref owned by lambda
r->work_serializer_->Run([r, error]() { r->OnResolvedLocked(error); },
DEBUG_LOCATION);
}
void AresDnsResolver::OnResolvedLocked(grpc_error* error) {
GPR_ASSERT(resolving_);
resolving_ = false;
gpr_free(pending_request_);
pending_request_ = nullptr;
pending_request_.reset();
if (shutdown_initiated_) {
Unref(DEBUG_LOCATION, "OnResolvedLocked() shutdown");
GRPC_ERROR_UNREF(error);
@ -327,10 +314,9 @@ void AresDnsResolver::OnResolvedLocked(grpc_error* error) {
if (addresses_ != nullptr) {
result.addresses = std::move(*addresses_);
}
if (service_config_json_ != nullptr) {
if (service_config_json_.has_value()) {
std::string service_config_string = ChooseServiceConfig(
service_config_json_, &result.service_config_error);
gpr_free(service_config_json_);
service_config_json_.value(), &result.service_config_error);
if (result.service_config_error == GRPC_ERROR_NONE &&
!service_config_string.empty()) {
GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s",
@ -421,16 +407,17 @@ void AresDnsResolver::StartResolvingLocked() {
Ref(DEBUG_LOCATION, "dns-resolving").release();
GPR_ASSERT(!resolving_);
resolving_ = true;
service_config_json_ = nullptr;
pending_request_ = grpc_dns_lookup_ares_locked(
dns_server_.c_str(), name_to_resolve_.c_str(), kDefaultPort,
interested_parties_, &on_resolved_, &addresses_,
service_config_json_.reset();
auto on_done = [this](grpc_error* error) { OnResolvedLocked(error); };
pending_request_ = LookupAresLocked(
dns_server_, name_to_resolve_, kDefaultPort, interested_parties_,
std::move(on_done), &addresses_,
enable_srv_queries_ ? &balancer_addresses_ : nullptr,
request_service_config_ ? &service_config_json_ : nullptr,
query_timeout_ms_, work_serializer_);
last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now();
GRPC_CARES_TRACE_LOG("resolver:%p Started resolving. pending_request_:%p",
this, pending_request_);
this, pending_request_.get());
}
//
@ -463,7 +450,7 @@ static grpc_error* blocking_resolve_address_ares(
}
static grpc_address_resolver_vtable ares_resolver = {
grpc_resolve_address_ares, blocking_resolve_address_ares};
grpc_core::ResolveAddressAres, blocking_resolve_address_ares};
#ifdef GRPC_UV
/* TODO(murgatroid99): Remove this when we want the cares resolver to be the
@ -490,7 +477,7 @@ void grpc_resolver_dns_ares_init() {
g_use_ares_dns_resolver = true;
gpr_log(GPR_DEBUG, "Using ares dns resolver");
address_sorting_init();
grpc_error* error = grpc_ares_init();
grpc_error* error = grpc_core::AresRequest::Init();
if (error != GRPC_ERROR_NONE) {
GRPC_LOG_IF_ERROR("grpc_ares_init() failed", error);
return;
@ -509,7 +496,7 @@ void grpc_resolver_dns_ares_init() {
void grpc_resolver_dns_ares_shutdown() {
if (g_use_ares_dns_resolver) {
address_sorting_shutdown();
grpc_ares_cleanup();
grpc_core::AresRequest::Shutdown();
}
}

@ -1,20 +1,18 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
//
// Copyright 2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
@ -27,40 +25,49 @@
namespace grpc_core {
/* A wrapped fd that integrates with the grpc iomgr of the current platform.
* A GrpcPolledFd knows how to create grpc platform-specific iomgr endpoints
* from "ares_socket_t" sockets, and then sign up for readability/writeability
* with that poller, and do shutdown and destruction. */
/// A wrapped fd that integrates with the grpc iomgr of the current platform.
/// A GrpcPolledFd knows how to create grpc platform-specific iomgr endpoints
/// from "ares_socket_t" sockets, and then sign up for readability/writeability
/// with that poller, and do shutdown and destruction.
class GrpcPolledFd {
public:
virtual ~GrpcPolledFd() {}
/* Called when c-ares library is interested and there's no pending callback */
// Called when c-ares library is interested and there's no pending callback
virtual void RegisterForOnReadableLocked(grpc_closure* read_closure) = 0;
/* Called when c-ares library is interested and there's no pending callback */
// Called when c-ares library is interested and there's no pending callback
virtual void RegisterForOnWriteableLocked(grpc_closure* write_closure) = 0;
/* Indicates if there is data left even after just being read from */
// Indicates if there is data left even after just being read from
virtual bool IsFdStillReadableLocked() = 0;
/* Called once and only once. Must cause cancellation of any pending
* read/write callbacks. */
// Called once and only once. Must cause cancellation of any pending
// read/write callbacks.
virtual void ShutdownLocked(grpc_error* error) = 0;
/* Get the underlying ares_socket_t that this was created from */
// Get the underlying ares_socket_t that this was created from
virtual ares_socket_t GetWrappedAresSocketLocked() = 0;
/* A unique name, for logging */
// A unique name, for logging
virtual const char* GetName() = 0;
};
/* A GrpcPolledFdFactory is 1-to-1 with and owned by the
* ares event driver. It knows how to create GrpcPolledFd's
* for the current platform, and the ares driver uses it for all of
* its fd's. */
/// A GrpcPolledFdFactory is 1-to-1 with and owned by the
/// ares event driver. It knows how to create GrpcPolledFd's
/// for the current platform, and the ares driver uses it for all of
/// its fd's.
class GrpcPolledFdFactory {
public:
virtual ~GrpcPolledFdFactory() {}
/* Creates a new wrapped fd for the current platform */
/// Creates a new wrapped fd for the current platform.
///
/// Note about \a driver_pollset_set lifetime: the \a driver_pollset_set
/// param exists in this factory function because some \a GrpcPolledFd
/// implementations need to use it. If a \a GrpcPolledFd object does need
/// to use \a driver_pollset_set, it is safe to access it up through the point
/// that \a GrpcPolledFd::ShutdownLocked has been run, and it is no longer
/// safe to access after that.
virtual GrpcPolledFd* NewGrpcPolledFdLocked(
ares_socket_t as, grpc_pollset_set* driver_pollset_set,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer) = 0;
/* Optionally configures the ares channel after creation */
/// Optionally configures the ares channel after creation
virtual void ConfigureAresChannelLocked(ares_channel channel) = 0;
};
@ -69,5 +76,4 @@ std::unique_ptr<GrpcPolledFdFactory> NewGrpcPolledFdFactory(
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H \
*/
#endif // GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H

@ -50,7 +50,6 @@ class GrpcPolledFdPosix : public GrpcPolledFd {
}
~GrpcPolledFdPosix() override {
grpc_pollset_set_del_fd(driver_pollset_set_, fd_);
/* c-ares library will close the fd inside grpc_fd. This fd may be picked up
immediately by another thread, and should not be closed by the following
grpc_fd_orphan. */
@ -73,6 +72,11 @@ class GrpcPolledFdPosix : public GrpcPolledFd {
}
void ShutdownLocked(grpc_error* error) override {
// After we return, driver_pollset_set_ is no longer
// safe to access because the overall \a LookupAresLocked call may
// complete, after which its owner may destroy it. So delete the fd now.
grpc_pollset_set_del_fd(driver_pollset_set_, fd_);
driver_pollset_set_ = nullptr;
grpc_fd_shutdown(fd_, error);
}

@ -246,7 +246,7 @@ class GrpcPolledFdWindows {
break;
case WRITE_PENDING:
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
abort();
GPR_ASSERT(0);
}
}
}
@ -346,7 +346,7 @@ class GrpcPolledFdWindows {
case SOCK_STREAM:
return SendVTCP(wsa_error_ctx, iov, iov_count);
default:
abort();
GPR_ASSERT(0);
}
}
@ -417,7 +417,7 @@ class GrpcPolledFdWindows {
tcp_write_state_ = WRITE_IDLE;
return total_sent;
}
abort();
GPR_ASSERT(0);
}
static void OnTcpConnect(void* arg, grpc_error* error) {
@ -483,7 +483,7 @@ class GrpcPolledFdWindows {
case SOCK_STREAM:
return ConnectTCP(wsa_error_ctx, target, target_len);
default:
abort();
GPR_ASSERT(0);
}
}
@ -722,7 +722,9 @@ class SockToPolledFdMap {
return node->polled_fd;
}
}
abort();
gpr_log(GPR_ERROR, "LookupPolledFd for socket: %d failed. head_: %p", s,
head_);
GPR_ASSERT(0);
}
void RemoveEntry(SOCKET s) {
@ -737,7 +739,7 @@ class SockToPolledFdMap {
}
prev = &node->next;
}
abort();
GPR_ASSERT(0);
}
/* These virtual socket functions are called from within the c-ares

@ -23,10 +23,16 @@
#include <ares.h>
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/work_serializer.h"
#define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 120000
@ -42,61 +48,284 @@ extern grpc_core::TraceFlag grpc_trace_cares_resolver;
} \
} while (0)
typedef struct grpc_ares_request grpc_ares_request;
/* Asynchronously resolve \a name. Use \a default_port if a port isn't
designated in \a name, otherwise use the port in \a name. grpc_ares_init()
must be called at least once before this function. \a on_done may be
called directly in this function without being scheduled with \a exec_ctx,
so it must not try to acquire locks that are being held by the caller. */
extern void (*grpc_resolve_address_ares)(const char* name,
const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
grpc_resolved_addresses** addresses);
/* Asynchronously resolve \a name. It will try to resolve grpclb SRV records in
addition to the normal address records. For normal address records, it uses
\a default_port if a port isn't designated in \a name, otherwise it uses the
port in \a name. grpc_ares_init() must be called at least once before this
function. \a on_done may be called directly in this function without being
scheduled with \a exec_ctx, so it must not try to acquire locks that are
being held by the caller. The returned grpc_ares_request object is owned
by the caller and it is safe to free after on_done is called back. */
extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
namespace grpc_core {
/// An AresRequest is a handle over a complete name resolution process
/// (A queries, AAAA queries, etc.). An AresRequest is created with a call
/// to LookupAresLocked, and the name resolution process begins when
/// it's created. The name resolution process can be terminated abruptly
/// by invoking \a Orphan. The \a interested_parties parameter must remain
/// alive until either the \a Orphan is invoked, or \a on_done is called,
/// whichever happens first.
class AresRequest final : public InternallyRefCounted<AresRequest> {
public:
static OrphanablePtr<AresRequest> Create(
absl::string_view dns_server, absl::string_view name,
absl::string_view default_port, grpc_pollset_set* interested_parties,
std::function<void(grpc_error*)> on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addrs,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addrs,
absl::optional<std::string>* service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer);
/// Callers should only create an AresRequest via \a LookupAresLocked, this
/// ctor is made public only to help the factory method.
AresRequest(
std::unique_ptr<grpc_core::ServerAddressList>* addresses_out,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses_out,
absl::optional<std::string>* service_config_json_out,
grpc_pollset_set* pollset_set, int query_timeout_ms,
std::function<void(grpc_error*)> on_done,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer);
~AresRequest() final;
/// Unref and Cancel the pending request if it's still in flight. Must be
/// called while holding the WorkSerializer that was used to call \a
/// LookupAresLocked.
void Orphan() override;
/// Initialize the gRPC ares wrapper. Must be called at least once before
/// ResolveAddressAres().
static grpc_error* Init(void);
/// Uninitialized the gRPC ares wrapper. If there was more than one previous
/// call to AresInit(), this function uninitializes the gRPC ares
/// wrapper only if it has been called the same number of times as
/// AresInit().
static void Shutdown(void);
private:
/// Tracks state needed to perform one A or AAAA lookup with the c-ares lib.
/// Note that \a Create both constructs an AddressQuery object and arranges
/// for it's deletion.
class AddressQuery final {
public:
static void Create(AresRequest* request, const std::string& host,
uint16_t port, bool is_balancer, int address_family);
~AddressQuery();
private:
AddressQuery(AresRequest* request, const std::string& host, uint16_t port,
bool is_balancer, int address_family);
static void OnHostByNameDoneLocked(void* arg, int status, int timeouts,
struct hostent* hostent);
// the request which spawned this query
AresRequest* request_;
// host to resolve
const std::string host_;
// port to use in resulting socket addresses, in network byte order
const uint16_t port_;
// is it a grpclb address
const bool is_balancer_;
// for logging and errors: the query type ("A" or "AAAA")
const char* qtype_;
// the address family (AF_INET or AF_INET6)
const int address_family_;
};
/// Tracks state needed to perform one SRV lookup with the c-ares lib.
/// Note that \a Create both constructs an AddressQuery object and arranges
/// for it's deletion.
class SRVQuery final {
public:
static void Create(AresRequest* request);
~SRVQuery();
private:
explicit SRVQuery(AresRequest* request);
static void OnSRVQueryDoneLocked(void* arg, int status, int timeouts,
unsigned char* abuf, int alen);
// the request which spawned this query
AresRequest* request_;
};
/// Tracks state needed to perform one TXT lookup with the c-ares lib.
/// Note that \a Create both constructs an AddressQuery object and arranges
/// for it's deletion.
class TXTQuery final {
public:
static void Create(AresRequest* request);
~TXTQuery();
private:
explicit TXTQuery(AresRequest* request);
static void OnTXTDoneLocked(void* arg, int status, int timeouts,
unsigned char* buf, int len);
// the request which spawned this query
AresRequest* request_;
};
// An FdNode tracks an fd and its relevant state for polling it as
// needed to carry out a c-ares resolution.
class FdNode final {
public:
FdNode(RefCountedPtr<AresRequest> request,
std::unique_ptr<grpc_core::GrpcPolledFd> grpc_polled_fd);
~FdNode();
void MaybeRegisterForOnReadableLocked();
void MaybeRegisterForOnWritableLocked();
void MaybeShutdownLocked(absl::string_view reason);
bool IsActiveLocked();
bool shutdown() { return shutdown_; }
GrpcPolledFd* grpc_polled_fd() { return grpc_polled_fd_.get(); }
private:
void OnReadableLocked(grpc_error* error);
static void OnReadable(void* arg, grpc_error* error);
void OnWritableLocked(grpc_error* error);
static void OnWritable(void* arg, grpc_error* error);
RefCountedPtr<AresRequest> request_;
// a closure wrapping OnReadableLocked, which should be
// invoked when the fd in this node becomes readable.
grpc_closure read_closure_;
// a closure wrapping OnWritableLocked, which should be
// invoked when the fd in this node becomes writable.
grpc_closure write_closure_;
// wrapped fd that's polled by grpc's poller for the current platform
std::unique_ptr<grpc_core::GrpcPolledFd> grpc_polled_fd_;
// if the readable closure has been registered
bool readable_registered_ = false;
// if the writable closure has been registered
bool writable_registered_ = false;
// if the fd has been shutdown yet from grpc iomgr perspective
bool shutdown_ = false;
};
void ShutdownIOLocked(absl::string_view reason);
grpc_millis CalculateNextAresBackupPollAlarm() const;
void OnTimeoutLocked(grpc_error* error);
static void OnTimeout(void* arg, grpc_error* error);
void OnAresBackupPollAlarmLocked(grpc_error* error);
static void OnAresBackupPollAlarm(void* arg, grpc_error* error);
void NotifyOnEventLocked();
void ContinueAfterCheckLocalhostAndIPLiteralsLocked(
absl::string_view dns_server);
void DecrementPendingQueries();
void MaybeCallOnDoneLocked();
bool ResolveAsIPLiteralLocked();
bool MaybeResolveLocalHostManuallyLocked();
std::string srv_qname() const {
return absl::StrCat("_grpclb._tcp.", target_host_);
}
std::string txt_qname() const {
return absl::StrCat("_grpc_config.", target_host_);
}
// the host component of the service name to resolve
std::string target_host_;
// the numeric port number to access the service on, stored in
// network byte order
uint16_t target_port_ = 0;
// the pointer to receive the resolved addresses
std::unique_ptr<grpc_core::ServerAddressList>* addresses_out_;
// the pointer to receive the resolved balancer addresses
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses_out_;
// the pointer to receive the service config in JSON
absl::optional<std::string>* service_config_json_out_;
// the ares_channel owned by this request
ares_channel channel_ = nullptr;
// pollset set for driving the IO events of the channel
grpc_pollset_set* pollset_set_;
// work_serializer to synchronize c-ares and I/O callbacks on
std::shared_ptr<grpc_core::WorkSerializer> work_serializer_;
// Number of active DNS queries (one for A, another for AAAA, etc.).
int pending_queries_ = 0;
// the fds that this request is currently using.
std::map<ares_socket_t, std::unique_ptr<FdNode>> fds_;
// is this request being shut down
bool shutting_down_ = false;
// Owned by the ev_driver. Creates new GrpcPolledFd's
std::unique_ptr<grpc_core::GrpcPolledFdFactory> polled_fd_factory_;
// query timeout in milliseconds
int query_timeout_ms_;
// alarm to cancel active queries
grpc_timer query_timeout_;
// cancels queries on a timeout
grpc_closure on_timeout_locked_;
// alarm to poll ares_process on in case fd events don't happen
grpc_timer ares_backup_poll_alarm_;
// polls ares_process on a periodic timer
grpc_closure on_ares_backup_poll_alarm_locked_;
// callback to schedule when the request completes, empty means that
// we've already scheduled the callback
std::function<void(grpc_error*)> on_done_;
// the errors explaining query failures, appended to in query callbacks
grpc_error* error_ = GRPC_ERROR_NONE;
};
/// Asynchronously resolve \a name. Use \a default_port if a port isn't
/// designated in \a name, otherwise use the port in \a name.
/// AresInit() must be called at least once before this function.
extern void (*ResolveAddressAres)(const char* name, const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
grpc_resolved_addresses** addresses);
/// Asynchronously resolve \a name. It will try to resolve grpclb SRV records in
/// addition to the normal address records if \a balancer_addresses is not
/// nullptr. For normal address records, it uses \a default_port if a port isn't
/// designated in \a name, otherwise it uses the port in \a name. AresInit()
/// must be called at least once before this function. The returned
/// AresRequest is safe to destroy after \a on_done is called back.
///
/// TODO(apolcyn): as a part of moving to new gRPC DNS API, remove the
/// work_serializer parameter and synchronize internally instead.
extern OrphanablePtr<AresRequest> (*LookupAresLocked)(
absl::string_view dns_server, absl::string_view name,
absl::string_view default_port, grpc_pollset_set* interested_parties,
std::function<void(grpc_error*)> on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses,
char** service_config_json, int query_timeout_ms,
absl::optional<std::string>* service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer);
/* Cancel the pending grpc_ares_request \a request */
extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request);
/* Initialize gRPC ares wrapper. Must be called at least once before
grpc_resolve_address_ares(). */
grpc_error* grpc_ares_init(void);
/// Indicates whether or not AAAA queries should be attempted.
/// E.g., return false if ipv6 is known to not be available.
bool AresQueryIPv6();
/* Uninitialized gRPC ares wrapper. If there was more than one previous call to
grpc_ares_init(), this function uninitializes the gRPC ares wrapper only if
it has been called the same number of times as grpc_ares_init(). */
void grpc_ares_cleanup(void);
/// Sorts destinations in \a addresses according to RFC 6724.
void AddressSortingSort(const AresRequest* request,
ServerAddressList* addresses,
const std::string& logging_prefix);
/** Schedules the desired callback for request completion
* and destroys the grpc_ares_request */
void grpc_ares_complete_request_locked(grpc_ares_request* request);
namespace internal {
/* Indicates whether or not AAAA queries should be attempted. */
/* E.g., return false if ipv6 is known to not be available. */
bool grpc_ares_query_ipv6();
/// Exposed in this header for C-core tests only
extern void (*AresTestOnlyInjectConfig)(ares_channel channel);
/* Sorts destinations in lb_addrs according to RFC 6724. */
void grpc_cares_wrapper_address_sorting_sort(
const grpc_ares_request* request, grpc_core::ServerAddressList* addresses);
} // namespace internal
/* Exposed in this header for C-core tests only */
extern void (*grpc_ares_test_only_inject_config)(ares_channel channel);
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \
*/

@ -28,11 +28,15 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/parse_address.h"
bool grpc_ares_query_ipv6() {
namespace grpc_core {
bool AresQueryIPv6() {
/* The libuv grpc code currently does not have the code to probe for this,
* so we assume for now that IPv6 is always available in contexts where this
* code will be used. */
return true;
}
} // namespace grpc_core
#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */

@ -24,6 +24,10 @@
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
namespace grpc_core {
bool AresQueryIPv6() { return grpc_ipv6_loopback_available(); }
} // namespace grpc_core
#endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) */

@ -29,6 +29,10 @@
#include "src/core/lib/iomgr/parse_address.h"
#include "src/core/lib/iomgr/socket_windows.h"
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
namespace grpc_core {
bool AresQueryIPv6() { return grpc_ipv6_loopback_available(); }
} // namespace grpc_core
#endif /* GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) */

@ -60,15 +60,19 @@ static void my_resolve_address(const char* addr, const char* /*default_port*/,
static grpc_address_resolver_vtable test_resolver = {my_resolve_address,
nullptr};
static grpc_ares_request* my_dns_lookup_ares_locked(
const char* /*dns_server*/, const char* addr, const char* /*default_port*/,
grpc_pollset_set* /*interested_parties*/, grpc_closure* on_done,
static grpc_core::OrphanablePtr<grpc_core::AresRequest>
my_dns_lookup_ares_locked(
absl::string_view /*dns_server*/, absl::string_view addr,
absl::string_view /*default_port*/,
grpc_pollset_set* /*interested_parties*/,
std::function<void(grpc_error*)> on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::ServerAddressList>* /*balancer_addresses*/,
char** /*service_config_json*/, int /*query_timeout_ms*/,
std::shared_ptr<grpc_core::WorkSerializer> /*combiner*/) { // NOLINT
absl::optional<std::string>* /*service_config_json*/,
int /*query_timeout_ms*/,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer) { // NOLINT
gpr_mu_lock(&g_mu);
GPR_ASSERT(0 == strcmp("test", addr));
GPR_ASSERT("test" == addr);
grpc_error* error = GRPC_ERROR_NONE;
if (g_fail_resolution) {
g_fail_resolution = false;
@ -82,14 +86,10 @@ static grpc_ares_request* my_dns_lookup_ares_locked(
phony_resolved_address.len = 123;
(*addresses)->emplace_back(phony_resolved_address, nullptr);
}
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_done, error);
work_serializer->Run([on_done, error]() { on_done(error); }, DEBUG_LOCATION);
return nullptr;
}
static void my_cancel_ares_request_locked(grpc_ares_request* request) {
GPR_ASSERT(request == nullptr);
}
static grpc_core::OrphanablePtr<grpc_core::Resolver> create_resolver(
const char* name,
std::unique_ptr<grpc_core::Resolver::ResultHandler> result_handler) {
@ -166,8 +166,7 @@ int main(int argc, char** argv) {
auto work_serializer = std::make_shared<grpc_core::WorkSerializer>();
g_work_serializer = &work_serializer;
grpc_set_resolver_impl(&test_resolver);
grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked;
grpc_cancel_ares_request_locked = my_cancel_ares_request_locked;
grpc_core::LookupAresLocked = my_dns_lookup_ares_locked;
{
grpc_core::ExecCtx exec_ctx;
@ -177,7 +176,8 @@ int main(int argc, char** argv) {
std::unique_ptr<grpc_core::Resolver::ResultHandler>(result_handler));
ResultHandler::ResolverOutput output1;
result_handler->SetOutput(&output1);
resolver->StartLocked();
grpc_core::Resolver* r = resolver.get();
work_serializer->Run([r]() { r->StartLocked(); }, DEBUG_LOCATION);
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(wait_loop(5, &output1.ev));
GPR_ASSERT(output1.result.addresses.empty());

@ -37,12 +37,14 @@ static grpc_address_resolver_vtable* default_resolve_address;
static std::shared_ptr<grpc_core::WorkSerializer>* g_work_serializer;
static grpc_ares_request* (*g_default_dns_lookup_ares_locked)(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
static grpc_core::OrphanablePtr<grpc_core::AresRequest> (
*g_default_dns_lookup_ares_locked)(
absl::string_view dns_server, absl::string_view name,
absl::string_view default_port, grpc_pollset_set* interested_parties,
std::function<void(grpc_error*)> on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses,
char** service_config_json, int query_timeout_ms,
absl::optional<std::string>* service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer);
// Counter incremented by test_resolve_address_impl indicating the number of
@ -96,17 +98,20 @@ static grpc_error* test_blocking_resolve_address_impl(
static grpc_address_resolver_vtable test_resolver = {
test_resolve_address_impl, test_blocking_resolve_address_impl};
static grpc_ares_request* test_dns_lookup_ares_locked(
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* /*interested_parties*/, grpc_closure* on_done,
static grpc_core::OrphanablePtr<grpc_core::AresRequest>
test_dns_lookup_ares_locked(
absl::string_view dns_server, absl::string_view name,
absl::string_view default_port, grpc_pollset_set* /*interested_parties*/,
std::function<void(grpc_error*)> on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses,
char** service_config_json, int query_timeout_ms,
absl::optional<std::string>* service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer) {
grpc_ares_request* result = g_default_dns_lookup_ares_locked(
dns_server, name, default_port, g_iomgr_args.pollset_set, on_done,
addresses, balancer_addresses, service_config_json, query_timeout_ms,
std::move(work_serializer));
grpc_core::OrphanablePtr<grpc_core::AresRequest> result =
g_default_dns_lookup_ares_locked(
dns_server, name, default_port, g_iomgr_args.pollset_set, on_done,
addresses, balancer_addresses, service_config_json, query_timeout_ms,
std::move(work_serializer));
++g_resolution_count;
static grpc_millis last_resolution_time = 0;
grpc_millis now =
@ -340,8 +345,8 @@ int main(int argc, char** argv) {
auto work_serializer = std::make_shared<grpc_core::WorkSerializer>();
g_work_serializer = &work_serializer;
g_default_dns_lookup_ares_locked = grpc_dns_lookup_ares_locked;
grpc_dns_lookup_ares_locked = test_dns_lookup_ares_locked;
g_default_dns_lookup_ares_locked = grpc_core::LookupAresLocked;
grpc_core::LookupAresLocked = test_dns_lookup_ares_locked;
default_resolve_address = grpc_resolve_address_impl;
grpc_set_resolver_impl(&test_resolver);

@ -49,16 +49,16 @@ static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
static gpr_mu g_mu;
static int g_resolve_port = -1;
static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
static grpc_core::OrphanablePtr<grpc_core::AresRequest> (
*iomgr_dns_lookup_ares_locked)(
absl::string_view dns_server, absl::string_view addr,
absl::string_view default_port, grpc_pollset_set* interested_parties,
std::function<void(grpc_error*)> on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses,
char** service_config_json, int query_timeout_ms,
absl::optional<std::string>* service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> combiner);
static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request);
static void set_resolve_port(int port) {
gpr_mu_lock(&g_mu);
g_resolve_port = port;
@ -107,14 +107,16 @@ static grpc_error* my_blocking_resolve_address(
static grpc_address_resolver_vtable test_resolver = {
my_resolve_address, my_blocking_resolve_address};
static grpc_ares_request* my_dns_lookup_ares_locked(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
static grpc_core::OrphanablePtr<grpc_core::AresRequest>
my_dns_lookup_ares_locked(
absl::string_view dns_server, absl::string_view addr,
absl::string_view default_port, grpc_pollset_set* interested_parties,
std::function<void(grpc_error*)> on_done,
std::unique_ptr<grpc_core::ServerAddressList>* addresses,
std::unique_ptr<grpc_core::ServerAddressList>* balancer_addresses,
char** service_config_json, int query_timeout_ms,
absl::optional<std::string>* service_config_json, int query_timeout_ms,
std::shared_ptr<grpc_core::WorkSerializer> work_serializer) {
if (0 != strcmp(addr, "test")) {
if (addr != "test") {
return iomgr_dns_lookup_ares_locked(
dns_server, addr, default_port, interested_parties, on_done, addresses,
balancer_addresses, service_config_json, query_timeout_ms,
@ -135,16 +137,10 @@ static grpc_ares_request* my_dns_lookup_ares_locked(
(*addresses)->emplace_back(&sa, sizeof(sa), nullptr);
gpr_mu_unlock(&g_mu);
}
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_done, error);
work_serializer->Run([on_done, error] { on_done(error); }, DEBUG_LOCATION);
return nullptr;
}
static void my_cancel_ares_request_locked(grpc_ares_request* request) {
if (request != nullptr) {
iomgr_cancel_ares_request_locked(request);
}
}
int main(int argc, char** argv) {
grpc_completion_queue* cq;
cq_verifier* cqv;
@ -157,10 +153,8 @@ int main(int argc, char** argv) {
grpc_init();
default_resolver = grpc_resolve_address_impl;
grpc_set_resolver_impl(&test_resolver);
iomgr_dns_lookup_ares_locked = grpc_dns_lookup_ares_locked;
iomgr_cancel_ares_request_locked = grpc_cancel_ares_request_locked;
grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked;
grpc_cancel_ares_request_locked = my_cancel_ares_request_locked;
iomgr_dns_lookup_ares_locked = grpc_core::LookupAresLocked;
grpc_core::LookupAresLocked = my_dns_lookup_ares_locked;
int was_cancelled1;
int was_cancelled2;

@ -205,7 +205,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
{"1.2.3.4:443", AF_INET},
{"5.6.7.8:443", AF_INET},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"1.2.3.4:443",
"5.6.7.8:443",
@ -224,7 +224,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
{"[2607:f8b0:400a:801::1002]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"1.2.3.4:443",
"[2607:f8b0:400a:801::1002]:443",
@ -244,7 +244,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
{"[2607:f8b0:400a:801::1002]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[2607:f8b0:400a:801::1002]:443",
"1.2.3.4:443",
@ -268,7 +268,7 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
{"[2000:f8b0:400a:801::1002]:443", AF_INET6},
{"[fec0::5000]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[fec0::5000]:443",
"[2000:f8b0:400a:801::1002]:443",
@ -291,7 +291,7 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
{"[2002::5001]:443", AF_INET6},
{"[2001::5001]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[2001::5001]:443",
"[2002::5001]:443",
@ -314,7 +314,7 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
{"[2001::5001]:443", AF_INET6},
{"[2002::5001]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[2001::5001]:443",
"[2002::5001]:443",
@ -337,7 +337,7 @@ TEST_F(AddressSortingTest,
{"[3ffe::5001]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(
lb_addrs, {
// The AF_INET address should be IPv4-mapped by the sort,
@ -370,7 +370,7 @@ TEST_F(AddressSortingTest,
{v4_compat_dest, AF_INET6},
{"[::1]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
v4_compat_dest,
@ -393,7 +393,7 @@ TEST_F(AddressSortingTest,
{"[1234::2]:443", AF_INET6},
{"[::1]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(
lb_addrs,
{
@ -417,7 +417,7 @@ TEST_F(AddressSortingTest,
{"[2001::1234]:443", AF_INET6},
{"[2000::5001]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(
lb_addrs, {
// The 2000::/16 address should match the ::/0 prefix rule
@ -441,7 +441,7 @@ TEST_F(
{"[2001::1231]:443", AF_INET6},
{"[2000::5001]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[2000::5001]:443",
"[2001::1231]:443",
@ -462,7 +462,7 @@ TEST_F(AddressSortingTest,
{"[fec0::1234]:443", AF_INET6},
{"[fc00::5001]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[fc00::5001]:443",
"[fec0::1234]:443",
@ -487,7 +487,7 @@ TEST_F(
{"[::ffff:1.1.1.2]:443", AF_INET6},
{"[1234::2]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
// ::ffff:0:2 should match the v4-mapped
// precedence entry and be deprioritized.
@ -514,7 +514,7 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
{"[3ffe::5001]:443", AF_INET6},
{"[fec0::1234]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[fec0::1234]:443",
"[3ffe::5001]:443",
@ -539,7 +539,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
{"[3ffe:5001::]:443", AF_INET6},
{"[3ffe:1234::]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:1234::]:443",
"[3ffe:5001::]:443",
@ -560,7 +560,7 @@ TEST_F(AddressSortingTest,
{"[3ffe::5001]:443", AF_INET6},
{"[3ffe::1234]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1234]:443",
"[3ffe::5001]:443",
@ -580,7 +580,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
{"[3ffe:8000::]:443", AF_INET6},
{"[3ffe:2000::]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:2000::]:443",
"[3ffe:8000::]:443",
@ -600,7 +600,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
{"[3ffe:6::]:443", AF_INET6},
{"[3ffe:c::]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:c::]:443",
"[3ffe:6::]:443",
@ -622,7 +622,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
{"[3ffe:1111:1111:1110::]:443", AF_INET6},
{"[3ffe:1111:1111:1111::]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:1111:1111:1111::]:443",
"[3ffe:1111:1111:1110::]:443",
@ -644,7 +644,7 @@ TEST_F(AddressSortingTest, TestStableSort) {
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1234]:443",
"[3ffe::1235]:443",
@ -670,7 +670,7 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) {
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1231]:443",
"[3ffe::1232]:443",
@ -691,7 +691,7 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1231]:443",
"[3ffe::1232]:443",
@ -709,7 +709,7 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
{"[::ffff:5.6.7.8]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[::ffff:5.6.7.8]:443",
"1.2.3.4:443",
@ -737,7 +737,7 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
{"[fec0::2000]:443", AF_INET6},
{v4_compat_dest, AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs,
{
// The sort should be stable since
@ -758,7 +758,7 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
{"[::1]:443", AF_INET6},
{"127.0.0.1:443", AF_INET},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
"127.0.0.1:443",
@ -772,7 +772,7 @@ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
{"127.0.0.1:443", AF_INET},
{"[::1]:443", AF_INET6},
});
grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
grpc_core::AddressSortingSort(nullptr, &lb_addrs, "test-addresses");
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
"127.0.0.1:443",

@ -35,6 +35,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/global_config_generic.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/pollset.h"
@ -55,6 +56,8 @@
#define BAD_SOCKET_RETURN_VAL (-1)
#endif
GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_abort_on_leaks);
namespace {
void* Tag(intptr_t t) { return reinterpret_cast<void*>(t); }
@ -405,6 +408,10 @@ TEST_F(
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(argc, argv);
// see notes in
// https://github.com/grpc/grpc/pull/25108#pullrequestreview-577881514 for
// motivation.
GPR_GLOBAL_CONFIG_SET(grpc_abort_on_leaks, true);
::testing::InitGoogleTest(&argc, argv);
auto result = RUN_ALL_TESTS();
return result;

@ -44,6 +44,7 @@
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/global_config_generic.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/iomgr/executor.h"
@ -126,6 +127,8 @@ ABSL_FLAG(std::string, expected_lb_policy, "",
"Expected lb policy name that appears in resolver result channel "
"arg. Empty for none.");
GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_abort_on_leaks);
namespace {
class GrpcLBAddress final {
@ -584,7 +587,7 @@ void RunResolvesRelevantRecordsTest(
absl::make_unique<grpc::testing::FakeNonResponsiveDNSServer>(
g_fake_non_responsive_dns_server_port);
grpc_ares_test_only_inject_config = InjectBrokenNameServerList;
grpc_core::internal::AresTestOnlyInjectConfig = InjectBrokenNameServerList;
whole_uri = absl::StrCat("dns:///", absl::GetFlag(FLAGS_target_name));
} else if (absl::GetFlag(FLAGS_inject_broken_nameserver_list) == "False") {
gpr_log(GPR_INFO, "Specifying authority in uris to: %s",
@ -668,6 +671,10 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) {
int main(int argc, char** argv) {
grpc_init();
grpc::testing::TestEnvironment env(argc, argv);
// see notes in
// https://github.com/grpc/grpc/pull/25108#pullrequestreview-577881514 for
// motivation.
GPR_GLOBAL_CONFIG_SET(grpc_abort_on_leaks, true);
::testing::InitGoogleTest(&argc, argv);
grpc::testing::InitTest(&argc, &argv, true);
if (absl::GetFlag(FLAGS_target_name).empty()) {

Loading…
Cancel
Save