diff --git a/BUILD b/BUILD index 1f1d9affc34..98bb2548b69 100644 --- a/BUILD +++ b/BUILD @@ -561,6 +561,7 @@ grpc_cc_library( "src/core/lib/profiling/timers.h", ], external_deps = [ + "absl/memory", "absl/strings", ], language = "c++", diff --git a/BUILD.gn b/BUILD.gn index 8dc1e1f1590..193816d66b1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -162,6 +162,7 @@ config("grpc_config") { ] deps = [ ":absl/container:inlined_vector", + ":absl/memory:memory", ":absl/strings:strings", ":absl/types:optional", ] diff --git a/CMakeLists.txt b/CMakeLists.txt index f9a15dd8289..120b951eebc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1439,6 +1439,7 @@ target_include_directories(gpr target_link_libraries(gpr ${_gRPC_ALLTARGETS_LIBRARIES} absl::inlined_vector + absl::memory absl::strings absl::optional ) diff --git a/build.yaml b/build.yaml index 4a6de9e6ada..f685917fe0d 100644 --- a/build.yaml +++ b/build.yaml @@ -271,6 +271,7 @@ filegroups: - src/core/lib/profiling/stap_timers.cc deps: - absl/container:inlined_vector + - absl/memory:memory - absl/strings:strings - absl/types:optional uses: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 44a59f601cb..e8b61788f7c 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -215,6 +215,7 @@ Pod::Spec.new do |s| ss.dependency 'gRPC-Core', version abseil_version = '0.20190808.1' ss.dependency 'abseil/container/inlined_vector', abseil_version + ss.dependency 'abseil/memory/memory', abseil_version ss.dependency 'abseil/strings/strings', abseil_version ss.dependency 'abseil/types/optional', abseil_version diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 6fdda1cb52e..43f3be101a9 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -175,6 +175,7 @@ Pod::Spec.new do |s| ss.dependency 'BoringSSL-GRPC', '0.0.7' abseil_version = '0.20190808.1' ss.dependency 'abseil/container/inlined_vector', abseil_version + ss.dependency 'abseil/memory/memory', abseil_version ss.dependency 'abseil/strings/strings', abseil_version ss.dependency 'abseil/types/optional', abseil_version ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' diff --git a/grpc.gyp b/grpc.gyp index 3f3fd1fd814..4197a676c7c 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -442,6 +442,7 @@ 'type': 'static_library', 'dependencies': [ 'absl/container:inlined_vector', + 'absl/memory:memory', 'absl/strings:strings', 'absl/types:optional', ], diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 4987ae8207b..7fddb7912df 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1595,7 +1595,7 @@ void ChannelData::CreateResolvingLoadBalancingPolicyLocked() { LoadBalancingPolicy::Args lb_args; lb_args.combiner = combiner_; lb_args.channel_control_helper = - grpc_core::MakeUnique(this); + absl::make_unique(this); lb_args.args = channel_args_; grpc_core::UniquePtr target_uri(gpr_strdup(target_uri_.get())); resolving_lb_policy_.reset(new ResolvingLoadBalancingPolicy( @@ -1871,7 +1871,7 @@ void ChannelData::StartTransportOpLocked(void* arg, grpc_error* /*ignored*/) { MemoryOrder::RELEASE); chand->UpdateStateAndPickerLocked( GRPC_CHANNEL_SHUTDOWN, "shutdown from API", - grpc_core::MakeUnique( + absl::make_unique( GRPC_ERROR_REF(op->disconnect_with_error))); } } diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc index cc8c5b02b1c..6e8c84e4a63 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -385,5 +385,5 @@ void grpc_http_connect_register_handshaker_factory() { using namespace grpc_core; HandshakerRegistry::RegisterHandshakerFactory( true /* at_start */, HANDSHAKER_CLIENT, - grpc_core::MakeUnique()); + absl::make_unique()); } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 8035008d036..0e2d6cc7fb5 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -714,9 +714,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, client_stats = parent_->lb_calld_->client_stats()->Ref(); } parent_->channel_control_helper()->UpdateState( - state, grpc_core::MakeUnique(parent_.get(), parent_->serverlist_, - std::move(picker), - std::move(client_stats))); + state, + absl::make_unique(parent_.get(), parent_->serverlist_, + std::move(picker), std::move(client_stats))); } void GrpcLb::Helper::RequestReresolution() { @@ -1946,7 +1946,7 @@ bool maybe_add_client_load_reporting_filter(grpc_channel_stack_builder* builder, void grpc_lb_policy_grpclb_init() { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( - grpc_core::MakeUnique()); + absl::make_unique()); grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_client_load_reporting_filter, diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 278af3fde75..246b15a3549 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -201,7 +201,7 @@ void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() { GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(error)); + absl::make_unique(error)); return; } // If one of the subchannels in the new list is already in state @@ -319,10 +319,10 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(error)); + absl::make_unique(error)); } else { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, grpc_core::MakeUnique(p->Ref( + GRPC_CHANNEL_CONNECTING, absl::make_unique(p->Ref( DEBUG_LOCATION, "QueuePicker"))); } } else { @@ -338,7 +338,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; p->subchannel_list_.reset(); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, grpc_core::MakeUnique( + GRPC_CHANNEL_IDLE, absl::make_unique( p->Ref(DEBUG_LOCATION, "QueuePicker"))); } else { // This is unlikely but can happen when a subchannel has been asked @@ -347,10 +347,10 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( if (connectivity_state == GRPC_CHANNEL_READY) { p->channel_control_helper()->UpdateState( GRPC_CHANNEL_READY, - grpc_core::MakeUnique(subchannel()->Ref())); + absl::make_unique(subchannel()->Ref())); } else { // CONNECTING p->channel_control_helper()->UpdateState( - connectivity_state, grpc_core::MakeUnique( + connectivity_state, absl::make_unique( p->Ref(DEBUG_LOCATION, "QueuePicker"))); } } @@ -395,7 +395,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(error)); + absl::make_unique(error)); } } sd->CheckConnectivityStateAndStartWatchingLocked(); @@ -406,7 +406,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // Only update connectivity state in case 1. if (subchannel_list() == p->subchannel_list_.get()) { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, grpc_core::MakeUnique(p->Ref( + GRPC_CHANNEL_CONNECTING, absl::make_unique(p->Ref( DEBUG_LOCATION, "QueuePicker"))); } break; @@ -446,7 +446,7 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { } p->selected_ = this; p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, grpc_core::MakeUnique(subchannel()->Ref())); + GRPC_CHANNEL_READY, absl::make_unique(subchannel()->Ref())); for (size_t i = 0; i < subchannel_list()->num_subchannels(); ++i) { if (i != Index()) { subchannel_list()->subchannel(i)->ShutdownLocked(); @@ -503,7 +503,7 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { void grpc_lb_policy_pick_first_init() { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } void grpc_lb_policy_pick_first_shutdown() {} diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index a26d0b53994..a5ab488ec55 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -322,12 +322,12 @@ void RoundRobin::RoundRobinSubchannelList:: if (num_ready_ > 0) { /* 1) READY */ p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, grpc_core::MakeUnique(p, this)); + GRPC_CHANNEL_READY, absl::make_unique(p, this)); } else if (num_connecting_ > 0) { /* 2) CONNECTING */ p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, grpc_core::MakeUnique( - p->Ref(DEBUG_LOCATION, "QueuePicker"))); + GRPC_CHANNEL_CONNECTING, + absl::make_unique(p->Ref(DEBUG_LOCATION, "QueuePicker"))); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ grpc_error* error = @@ -336,7 +336,7 @@ void RoundRobin::RoundRobinSubchannelList:: GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); p->channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(error)); + absl::make_unique(error)); } } @@ -453,7 +453,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(error)); + absl::make_unique(error)); subchannel_list_ = std::move(latest_pending_subchannel_list_); } else if (subchannel_list_ == nullptr) { // If there is no current list, immediately promote the new list to @@ -498,7 +498,7 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { void grpc_lb_policy_round_robin_init() { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } void grpc_lb_policy_round_robin_shutdown() {} diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc index 5344cb3ddb1..41c031b97d8 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc @@ -148,7 +148,7 @@ void CdsLb::ClusterWatcher::OnClusterChanged(XdsApi::CdsUpdate cluster_data) { LoadBalancingPolicy::Args args; args.combiner = parent_->combiner(); args.args = parent_->args_; - args.channel_control_helper = grpc_core::MakeUnique(parent_->Ref()); + args.channel_control_helper = absl::make_unique(parent_->Ref()); parent_->child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( "xds_experimental", std::move(args)); @@ -173,7 +173,7 @@ void CdsLb::ClusterWatcher::OnError(grpc_error* error) { if (parent_->child_policy_ == nullptr) { parent_->channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(error)); + absl::make_unique(error)); } else { GRPC_ERROR_UNREF(error); } @@ -273,7 +273,7 @@ void CdsLb::UpdateLocked(UpdateArgs args) { xds_client_->CancelClusterDataWatch( StringView(old_config->cluster().c_str()), cluster_watcher_); } - auto watcher = grpc_core::MakeUnique(Ref()); + auto watcher = absl::make_unique(Ref()); cluster_watcher_ = watcher.get(); xds_client_->WatchClusterData(StringView(config_->cluster().c_str()), std::move(watcher)); @@ -335,7 +335,7 @@ class CdsFactory : public LoadBalancingPolicyFactory { void grpc_lb_policy_cds_init() { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } void grpc_lb_policy_cds_shutdown() {} diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 5cd24724f6e..3dda5904a08 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -809,7 +809,7 @@ void XdsLb::UpdateLocked(UpdateArgs args) { xds_client()->CancelEndpointDataWatch(StringView(old_eds_service_name), endpoint_watcher_); } - auto watcher = grpc_core::MakeUnique( + auto watcher = absl::make_unique( Ref(DEBUG_LOCATION, "EndpointWatcher")); endpoint_watcher_ = watcher.get(); xds_client()->WatchEndpointData(StringView(eds_service_name()), @@ -1060,7 +1060,7 @@ void XdsLb::UpdateXdsPickerLocked() { GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(error)); + absl::make_unique(error)); return; } priorities_[current_priority_]->UpdateXdsPickerLocked(); @@ -1150,7 +1150,7 @@ XdsLb::LocalityMap::LocalityMap(RefCountedPtr xds_policy, if (priority_ == 0) { xds_policy_->channel_control_helper()->UpdateState( GRPC_CHANNEL_CONNECTING, - grpc_core::MakeUnique( + absl::make_unique( xds_policy_->Ref(DEBUG_LOCATION, "QueuePicker"))); } } @@ -1225,7 +1225,7 @@ void XdsLb::LocalityMap::UpdateXdsPickerLocked() { } xds_policy()->channel_control_helper()->UpdateState( GRPC_CHANNEL_READY, - grpc_core::MakeUnique( + absl::make_unique( xds_policy_->Ref(DEBUG_LOCATION, "LocalityPicker"), std::move(picker_list))); } @@ -1870,7 +1870,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { void grpc_lb_policy_xds_init() { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } void grpc_lb_policy_xds_shutdown() {} diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 7f8ccafc0f2..a8215439d2a 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -499,7 +499,7 @@ void grpc_resolver_dns_ares_init() { } grpc_set_resolver_impl(&ares_resolver); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } else { g_use_ares_dns_resolver = false; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index 62576c706ba..37bb903a3a5 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -173,7 +173,7 @@ class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { std::unique_ptr NewGrpcPolledFdFactory( Combiner* combiner) { - return grpc_core::MakeUnique(); + return absl::make_unique(); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc index 8a51475d4ec..0b571a2bf33 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc @@ -99,7 +99,7 @@ class GrpcPolledFdFactoryPosix : public GrpcPolledFdFactory { std::unique_ptr NewGrpcPolledFdFactory( Combiner* /*combiner*/) { - return grpc_core::MakeUnique(); + return absl::make_unique(); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index ed3daf3af77..0742c97a6fb 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -934,7 +934,7 @@ class GrpcPolledFdFactoryWindows : public GrpcPolledFdFactory { std::unique_ptr NewGrpcPolledFdFactory( Combiner* combiner) { - return grpc_core::MakeUnique(combiner); + return absl::make_unique(combiner); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index d2c00000fdc..761bed9a82d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -185,7 +185,7 @@ static void on_hostbyname_done_locked(void* arg, int status, int /*timeouts*/, "request:%p on_hostbyname_done_locked host=%s ARES_SUCCESS", r, hr->host); if (*r->addresses_out == nullptr) { - *r->addresses_out = grpc_core::MakeUnique(); + *r->addresses_out = absl::make_unique(); } ServerAddressList& addresses = **r->addresses_out; for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { @@ -480,7 +480,7 @@ static bool inner_resolve_as_ip_literal_locked( grpc_parse_ipv6_hostport(hostport->get(), &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); + *addrs = absl::make_unique(); (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); return true; } @@ -543,7 +543,7 @@ static bool inner_maybe_resolve_localhost_manually_locked( } if (gpr_stricmp(host->get(), "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); + *addrs = absl::make_unique(); uint16_t numeric_port = grpc_strhtons(port->get()); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index d7028a5eaa3..3b5b902effc 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -305,7 +305,7 @@ void grpc_resolver_dns_native_init() { if (gpr_stricmp(resolver.get(), "native") == 0) { gpr_log(GPR_DEBUG, "Using native dns resolver"); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } else { grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::ResolverFactory* existing_factory = @@ -313,7 +313,7 @@ void grpc_resolver_dns_native_init() { if (existing_factory == nullptr) { gpr_log(GPR_DEBUG, "Using native dns resolver"); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } } } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 906dad2b6aa..30666894511 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -386,7 +386,7 @@ class FakeResolverFactory : public ResolverFactory { void grpc_resolver_fake_init() { grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } void grpc_resolver_fake_shutdown() {} diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index e946a911e6a..ef1304392cb 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -176,12 +176,12 @@ class UnixResolverFactory : public ResolverFactory { void grpc_resolver_sockaddr_init() { grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); #ifdef GRPC_HAVE_UNIX_SOCKET grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); #endif } diff --git a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc index e7eed60c446..8b7354f8621 100644 --- a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc @@ -91,7 +91,7 @@ void XdsResolver::StartLocked() { grpc_error* error = GRPC_ERROR_NONE; xds_client_ = MakeOrphanable( combiner(), interested_parties_, StringView(server_name_.get()), - grpc_core::MakeUnique(Ref()), *args_, &error); + absl::make_unique(Ref()), *args_, &error); if (error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Failed to create xds client -- channel will remain in " @@ -129,7 +129,7 @@ class XdsResolverFactory : public ResolverFactory { void grpc_resolver_xds_init() { grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( - grpc_core::MakeUnique()); + absl::make_unique()); } void grpc_resolver_xds_shutdown() {} diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 8b9f9ec7c74..080ecd354e6 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -54,7 +54,7 @@ size_t ClientChannelServiceConfigParser::ParserIndex() { void ClientChannelServiceConfigParser::Register() { g_client_channel_service_config_parser_index = ServiceConfig::RegisterParser( - grpc_core::MakeUnique()); + absl::make_unique()); } namespace { @@ -95,7 +95,7 @@ std::unique_ptr ParseRetryPolicy( const Json& json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); auto retry_policy = - grpc_core::MakeUnique(); + absl::make_unique(); if (json.type() != Json::Type::OBJECT) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryPolicy error:should be of type object"); @@ -387,7 +387,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json, *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel global parser", &error_list); if (*error == GRPC_ERROR_NONE) { - return grpc_core::MakeUnique( + return absl::make_unique( std::move(parsed_lb_config), std::move(lb_policy_name), retry_throttling, health_check_service_name); } @@ -433,7 +433,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const Json& json, } *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list); if (*error == GRPC_ERROR_NONE) { - return grpc_core::MakeUnique( + return absl::make_unique( timeout, wait_for_ready, std::move(retry_policy)); } return nullptr; diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 26766801243..e27aa661476 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -188,15 +188,15 @@ ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( GPR_ASSERT(process_resolver_result != nullptr); resolver_ = ResolverRegistry::CreateResolver( target_uri_.get(), args.args, interested_parties(), combiner(), - grpc_core::MakeUnique(Ref())); + absl::make_unique(Ref())); // Since the validity of args has been checked when create the channel, // CreateResolver() must return a non-null result. GPR_ASSERT(resolver_ != nullptr); if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); } - channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, grpc_core::MakeUnique(Ref())); + channel_control_helper()->UpdateState(GRPC_CHANNEL_CONNECTING, + absl::make_unique(Ref())); resolver_->StartLocked(); } @@ -262,7 +262,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { "Resolver transient failure", &error, 1); channel_control_helper()->UpdateState( GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_core::MakeUnique(state_error)); + absl::make_unique(state_error)); } GRPC_ERROR_UNREF(error); } diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index de3eafac778..884f68f2090 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -95,7 +95,7 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigVectorTable( const Json& json, InlinedVector::Entry, 10>* entries) { - auto objs_vector = grpc_core::MakeUnique(); + auto objs_vector = absl::make_unique(); InlinedVector error_list; for (size_t i = 0; i < g_registered_parsers->size(); i++) { grpc_error* parser_error = GRPC_ERROR_NONE; diff --git a/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc b/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc index 8befdb153c8..fcc079819bc 100644 --- a/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +++ b/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc @@ -42,7 +42,7 @@ std::unique_ptr XdsBootstrap::ReadFromFile(grpc_error** error) { Json json = Json::Parse(StringViewFromSlice(contents), error); grpc_slice_unref_internal(contents); if (*error != GRPC_ERROR_NONE) return nullptr; - return grpc_core::MakeUnique(std::move(json), error); + return absl::make_unique(std::move(json), error); } XdsBootstrap::XdsBootstrap(Json json, grpc_error** error) { @@ -192,7 +192,7 @@ grpc_error* XdsBootstrap::ParseChannelCreds(Json* json, size_t idx, grpc_error* XdsBootstrap::ParseNode(Json* json) { InlinedVector error_list; - node_ = grpc_core::MakeUnique(); + node_ = absl::make_unique(); auto it = json->mutable_object()->find("id"); if (it != json->mutable_object()->end()) { if (it->second.type() != Json::Type::STRING) { diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 6cecb943156..75f97d7aa08 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -86,13 +86,13 @@ MessageSizeParser::ParsePerMethodParams(const Json& json, grpc_error** error) { *error = GRPC_ERROR_CREATE_FROM_VECTOR("Message size parser", &error_list); return nullptr; } - return grpc_core::MakeUnique( - max_request_message_bytes, max_response_message_bytes); + return absl::make_unique(max_request_message_bytes, + max_response_message_bytes); } void MessageSizeParser::Register() { g_message_size_parser_index = - ServiceConfig::RegisterParser(grpc_core::MakeUnique()); + ServiceConfig::RegisterParser(absl::make_unique()); } size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index 8206c34ffe3..4edc9b3d9c7 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -28,6 +28,8 @@ #include #include +#include "absl/memory/memory.h" + namespace grpc_core { class DefaultDeleteChar { @@ -44,12 +46,6 @@ class DefaultDeleteChar { template using UniquePtr = std::unique_ptr; -// TODO(veblush): Replace this with absl::make_unique once abseil is added. -template -inline std::unique_ptr MakeUnique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); -} - } // namespace grpc_core #endif /* GRPC_CORE_LIB_GPRPP_MEMORY_H */ diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 1f37b7f7763..4566657da72 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -559,10 +559,10 @@ RefCountedPtr SecurityHandshakerCreate( void SecurityRegisterHandshakerFactories() { HandshakerRegistry::RegisterHandshakerFactory( false /* at_start */, HANDSHAKER_CLIENT, - grpc_core::MakeUnique()); + absl::make_unique()); HandshakerRegistry::RegisterHandshakerFactory( false /* at_start */, HANDSHAKER_SERVER, - grpc_core::MakeUnique()); + absl::make_unique()); } } // namespace grpc_core diff --git a/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc b/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc index a2d71a4afac..612ecfffd46 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +++ b/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc @@ -49,7 +49,7 @@ class BoringSslCachedSession : public SslCachedSession { std::unique_ptr SslCachedSession::Create( SslSessionPtr session) { - return grpc_core::MakeUnique(std::move(session)); + return absl::make_unique(std::move(session)); } } // namespace tsi diff --git a/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc b/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc index 2787f4b9b38..f45205cecce 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +++ b/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc @@ -67,7 +67,7 @@ class OpenSslCachedSession : public SslCachedSession { std::unique_ptr SslCachedSession::Create( SslSessionPtr session) { - return grpc_core::MakeUnique(std::move(session)); + return absl::make_unique(std::move(session)); } } // namespace tsi diff --git a/src/cpp/common/alts_util.cc b/src/cpp/common/alts_util.cc index b6e0d26480f..f565894674c 100644 --- a/src/cpp/common/alts_util.cc +++ b/src/cpp/common/alts_util.cc @@ -53,7 +53,7 @@ std::unique_ptr GetAltsContextFromAuthContext( gpr_log(GPR_ERROR, "security_level is invalid."); return nullptr; } - return grpc_core::MakeUnique(AltsContext(ctx)); + return absl::make_unique(AltsContext(ctx)); } grpc::Status AltsClientAuthzCheck( diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index ebbbc31f6dd..b16d2d53e0b 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -481,8 +481,8 @@ TEST_F(ChannelzRegistryBasedTest, GetTopChannelsUuidAfterCompaction) { // these will delete and unregister themselves after this block. std::vector> odd_channels; for (int i = 0; i < kLoopIterations; i++) { - odd_channels.push_back(grpc_core::MakeUnique()); - even_channels.push_back(grpc_core::MakeUnique()); + odd_channels.push_back(absl::make_unique()); + even_channels.push_back(absl::make_unique()); } } std::string json_str = ChannelzRegistry::GetTopChannels(0); diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 95eafeff54f..56a552ea9ca 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -75,7 +75,7 @@ static grpc_ares_request* my_dns_lookup_ares_locked( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); - *addresses = grpc_core::MakeUnique(); + *addresses = absl::make_unique(); grpc_resolved_address dummy_resolved_address; memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); dummy_resolved_address.len = 123; diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index f86f52b4e92..12d5d186f14 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -45,7 +45,7 @@ static void test_succeeds(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - args.result_handler = grpc_core::MakeUnique(); + args.result_handler = absl::make_unique(); grpc_core::OrphanablePtr resolver = factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver != nullptr); @@ -62,7 +62,7 @@ static void test_fails(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - args.result_handler = grpc_core::MakeUnique(); + args.result_handler = absl::make_unique(); grpc_core::OrphanablePtr resolver = factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver == nullptr); diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc index 9b1d6779e8e..a6999f6ffbc 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc @@ -47,7 +47,7 @@ static void test_succeeds(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - args.result_handler = grpc_core::MakeUnique(); + args.result_handler = absl::make_unique(); grpc_core::OrphanablePtr resolver = factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver != nullptr); @@ -68,7 +68,7 @@ static void test_fails(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - args.result_handler = grpc_core::MakeUnique(); + args.result_handler = absl::make_unique(); grpc_core::OrphanablePtr resolver = factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver == nullptr); diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 27ea0580e69..ad874736ffb 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -59,7 +59,7 @@ class TestParser1 : public ServiceConfig::Parser { GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); return nullptr; } - return grpc_core::MakeUnique(value); + return absl::make_unique(value); } return nullptr; } @@ -91,7 +91,7 @@ class TestParser2 : public ServiceConfig::Parser { GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); return nullptr; } - return grpc_core::MakeUnique(value); + return absl::make_unique(value); } return nullptr; } @@ -139,10 +139,10 @@ class ServiceConfigTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser( - grpc_core::MakeUnique()) == 0); - EXPECT_TRUE(ServiceConfig::RegisterParser( - grpc_core::MakeUnique()) == 1); + EXPECT_TRUE( + ServiceConfig::RegisterParser(absl::make_unique()) == 0); + EXPECT_TRUE( + ServiceConfig::RegisterParser(absl::make_unique()) == 1); } }; @@ -301,10 +301,10 @@ class ErroredParsersScopingTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser( - grpc_core::MakeUnique()) == 0); - EXPECT_TRUE(ServiceConfig::RegisterParser( - grpc_core::MakeUnique()) == 1); + EXPECT_TRUE( + ServiceConfig::RegisterParser(absl::make_unique()) == 0); + EXPECT_TRUE( + ServiceConfig::RegisterParser(absl::make_unique()) == 1); } }; @@ -346,9 +346,10 @@ class ClientChannelParserTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser( - grpc_core::MakeUnique< - internal::ClientChannelServiceConfigParser>()) == 0); + EXPECT_TRUE( + ServiceConfig::RegisterParser( + absl::make_unique()) == + 0); } }; @@ -915,7 +916,7 @@ class MessageSizeParserTest : public ::testing::Test { ServiceConfig::Shutdown(); ServiceConfig::Init(); EXPECT_TRUE(ServiceConfig::RegisterParser( - grpc_core::MakeUnique()) == 0); + absl::make_unique()) == 0); } }; diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc new file mode 100644 index 00000000000..7b9883f29f8 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -0,0 +1,1206 @@ +/* + * + * 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. + * + */ + +#include + +#include +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/iomgr/timer_manager.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/metadata.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/fuzzer_util.h" +#include "test/core/util/passthru_endpoint.h" + +using grpc_core::testing::grpc_fuzzer_get_next_byte; +using grpc_core::testing::grpc_fuzzer_get_next_string; +using grpc_core::testing::grpc_fuzzer_get_next_uint32; +using grpc_core::testing::input_stream; + +//////////////////////////////////////////////////////////////////////////////// +// logging + +bool squelch = true; +bool leak_check = true; + +static void dont_log(gpr_log_func_args* /*args*/) {} + +//////////////////////////////////////////////////////////////////////////////// +// global state + +static gpr_timespec g_now; +static grpc_server* g_server; +static grpc_channel* g_channel; +static grpc_resource_quota* g_resource_quota; + +extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); + +static gpr_timespec now_impl(gpr_clock_type clock_type) { + GPR_ASSERT(clock_type != GPR_TIMESPAN); + gpr_timespec ts = g_now; + ts.clock_type = clock_type; + return ts; +} + +static void end(input_stream* inp) { inp->cur = inp->end; } + +static void read_buffer(input_stream* inp, char** buffer, size_t* length, + bool* special) { + *length = grpc_fuzzer_get_next_byte(inp); + if (*length == 255) { + if (special != nullptr) *special = true; + *length = grpc_fuzzer_get_next_byte(inp); + } else { + if (special != nullptr) *special = false; + } + *buffer = static_cast(gpr_malloc(*length)); + for (size_t i = 0; i < *length; i++) { + (*buffer)[i] = static_cast(grpc_fuzzer_get_next_byte(inp)); + } +} + +static grpc_slice maybe_intern(grpc_slice s, bool intern) { + grpc_slice r = intern ? grpc_slice_intern(s) : grpc_slice_ref(s); + grpc_slice_unref(s); + return r; +} + +static grpc_slice read_string_like_slice(input_stream* inp) { + bool special; + char* s = grpc_fuzzer_get_next_string(inp, &special); + grpc_slice r = maybe_intern(grpc_slice_from_copied_string(s), special); + gpr_free(s); + return r; +} + +static grpc_slice read_buffer_like_slice(input_stream* inp) { + char* buffer; + size_t length; + bool special; + read_buffer(inp, &buffer, &length, &special); + grpc_slice r = + maybe_intern(grpc_slice_from_copied_buffer(buffer, length), special); + gpr_free(buffer); + return r; +} + +static uint32_t read_uint22(input_stream* inp) { + uint8_t b = grpc_fuzzer_get_next_byte(inp); + uint32_t x = b & 0x7f; + if (b & 0x80) { + x <<= 7; + b = grpc_fuzzer_get_next_byte(inp); + x |= b & 0x7f; + if (b & 0x80) { + x <<= 8; + x |= grpc_fuzzer_get_next_byte(inp); + } + } + return x; +} + +static grpc_byte_buffer* read_message(input_stream* inp) { + grpc_slice slice = grpc_slice_malloc(read_uint22(inp)); + memset(GRPC_SLICE_START_PTR(slice), 0, GRPC_SLICE_LENGTH(slice)); + grpc_byte_buffer* out = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + return out; +} + +static int read_int(input_stream* inp) { + return static_cast(grpc_fuzzer_get_next_uint32(inp)); +} + +static grpc_channel_args* read_args(input_stream* inp) { + size_t n = grpc_fuzzer_get_next_byte(inp); + grpc_arg* args = static_cast(gpr_malloc(sizeof(*args) * n)); + for (size_t i = 0; i < n; i++) { + switch (grpc_fuzzer_get_next_byte(inp)) { + case 1: + args[i].type = GRPC_ARG_STRING; + args[i].key = grpc_fuzzer_get_next_string(inp, nullptr); + args[i].value.string = grpc_fuzzer_get_next_string(inp, nullptr); + break; + case 2: + args[i].type = GRPC_ARG_INTEGER; + args[i].key = grpc_fuzzer_get_next_string(inp, nullptr); + args[i].value.integer = read_int(inp); + break; + case 3: + args[i].type = GRPC_ARG_POINTER; + args[i].key = gpr_strdup(GRPC_ARG_RESOURCE_QUOTA); + args[i].value.pointer.vtable = grpc_resource_quota_arg_vtable(); + args[i].value.pointer.p = g_resource_quota; + grpc_resource_quota_ref(g_resource_quota); + break; + default: + end(inp); + n = i; + break; + } + } + grpc_channel_args* a = + static_cast(gpr_malloc(sizeof(*a))); + a->args = args; + a->num_args = n; + return a; +} + +typedef struct cred_artifact_ctx { + int num_release; + char* release[3]; +} cred_artifact_ctx; +#define CRED_ARTIFACT_CTX_INIT \ + { \ + 0, { 0 } \ + } + +static void cred_artifact_ctx_finish(cred_artifact_ctx* ctx) { + for (int i = 0; i < ctx->num_release; i++) { + gpr_free(ctx->release[i]); + } +} + +static const char* read_cred_artifact(cred_artifact_ctx* ctx, input_stream* inp, + const char** builtins, + size_t num_builtins) { + uint8_t b = grpc_fuzzer_get_next_byte(inp); + if (b == 0) return nullptr; + if (b == 1) + return ctx->release[ctx->num_release++] = + grpc_fuzzer_get_next_string(inp, nullptr); + if (b >= num_builtins + 1) { + end(inp); + return nullptr; + } + return builtins[b - 1]; +} + +static grpc_channel_credentials* read_ssl_channel_creds(input_stream* inp) { + cred_artifact_ctx ctx = CRED_ARTIFACT_CTX_INIT; + static const char* builtin_root_certs[] = {test_root_cert}; + static const char* builtin_private_keys[] = { + test_server1_key, test_self_signed_client_key, test_signed_client_key}; + static const char* builtin_cert_chains[] = { + test_server1_cert, test_self_signed_client_cert, test_signed_client_cert}; + const char* root_certs = read_cred_artifact( + &ctx, inp, builtin_root_certs, GPR_ARRAY_SIZE(builtin_root_certs)); + const char* private_key = read_cred_artifact( + &ctx, inp, builtin_private_keys, GPR_ARRAY_SIZE(builtin_private_keys)); + const char* certs = read_cred_artifact(&ctx, inp, builtin_cert_chains, + GPR_ARRAY_SIZE(builtin_cert_chains)); + grpc_ssl_pem_key_cert_pair key_cert_pair = {private_key, certs}; + grpc_channel_credentials* creds = grpc_ssl_credentials_create( + root_certs, + private_key != nullptr && certs != nullptr ? &key_cert_pair : nullptr, + nullptr, nullptr); + cred_artifact_ctx_finish(&ctx); + return creds; +} + +static grpc_call_credentials* read_call_creds(input_stream* inp, int depth) { + if (depth > 64) { + // prevent creating infinitely deep call creds + end(inp); + return nullptr; + } + switch (grpc_fuzzer_get_next_byte(inp)) { + default: + end(inp); + return nullptr; + case 0: + return nullptr; + case 1: { + grpc_call_credentials* c1 = read_call_creds(inp, depth + 1); + grpc_call_credentials* c2 = read_call_creds(inp, depth + 1); + if (c1 != nullptr && c2 != nullptr) { + grpc_call_credentials* out = + grpc_composite_call_credentials_create(c1, c2, nullptr); + grpc_call_credentials_release(c1); + grpc_call_credentials_release(c2); + return out; + } else if (c1 != nullptr) { + return c1; + } else if (c2 != nullptr) { + return c2; + } else { + return nullptr; + } + GPR_UNREACHABLE_CODE(return nullptr); + } + case 2: { + cred_artifact_ctx ctx = CRED_ARTIFACT_CTX_INIT; + const char* access_token = read_cred_artifact(&ctx, inp, nullptr, 0); + grpc_call_credentials* out = + access_token == nullptr + ? nullptr + : grpc_access_token_credentials_create(access_token, nullptr); + cred_artifact_ctx_finish(&ctx); + return out; + } + case 3: { + cred_artifact_ctx ctx = CRED_ARTIFACT_CTX_INIT; + const char* auth_token = read_cred_artifact(&ctx, inp, nullptr, 0); + const char* auth_selector = read_cred_artifact(&ctx, inp, nullptr, 0); + grpc_call_credentials* out = + auth_token == nullptr || auth_selector == nullptr + ? nullptr + : grpc_google_iam_credentials_create(auth_token, auth_selector, + nullptr); + cred_artifact_ctx_finish(&ctx); + return out; + } + /* TODO(ctiller): more cred types here */ + } +} + +static grpc_channel_credentials* read_channel_creds(input_stream* inp) { + switch (grpc_fuzzer_get_next_byte(inp)) { + case 0: + return read_ssl_channel_creds(inp); + break; + case 1: { + grpc_channel_credentials* c1 = read_channel_creds(inp); + grpc_call_credentials* c2 = read_call_creds(inp, 0); + if (c1 != nullptr && c2 != nullptr) { + grpc_channel_credentials* out = + grpc_composite_channel_credentials_create(c1, c2, nullptr); + grpc_channel_credentials_release(c1); + grpc_call_credentials_release(c2); + return out; + } else if (c1) { + return c1; + } else if (c2) { + grpc_call_credentials_release(c2); + return nullptr; + } else { + return nullptr; + } + GPR_UNREACHABLE_CODE(return nullptr); + } + case 2: + return nullptr; + default: + end(inp); + return nullptr; + } +} + +static bool is_eof(input_stream* inp) { return inp->cur == inp->end; } + +//////////////////////////////////////////////////////////////////////////////// +// dns resolution + +typedef struct addr_req { + grpc_timer timer; + char* addr; + grpc_closure* on_done; + grpc_resolved_addresses** addrs; + std::unique_ptr* addresses; +} addr_req; + +static void finish_resolve(void* arg, grpc_error* error) { + addr_req* r = static_cast(arg); + + if (error == GRPC_ERROR_NONE && 0 == strcmp(r->addr, "server")) { + if (r->addrs != nullptr) { + grpc_resolved_addresses* addrs = + static_cast(gpr_malloc(sizeof(*addrs))); + addrs->naddrs = 1; + addrs->addrs = static_cast( + gpr_malloc(sizeof(*addrs->addrs))); + addrs->addrs[0].len = 0; + *r->addrs = addrs; + } else if (r->addresses != nullptr) { + *r->addresses = absl::make_unique(); + grpc_resolved_address dummy_resolved_address; + memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); + dummy_resolved_address.len = 0; + (*r->addresses)->emplace_back(dummy_resolved_address, nullptr); + } + grpc_core::ExecCtx::Run(DEBUG_LOCATION, r->on_done, GRPC_ERROR_NONE); + } else { + grpc_core::ExecCtx::Run(DEBUG_LOCATION, r->on_done, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolution failed", &error, 1)); + } + + gpr_free(r->addr); + delete r; +} + +void my_resolve_address(const char* addr, const char* /*default_port*/, + grpc_pollset_set* /*interested_parties*/, + grpc_closure* on_done, + grpc_resolved_addresses** addrs) { + addr_req* r = new addr_req(); + r->addr = gpr_strdup(addr); + r->on_done = on_done; + r->addrs = addrs; + grpc_timer_init( + &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), + GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); +} + +static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address, + nullptr}; + +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, + std::unique_ptr* addresses, + bool /*check_grpclb*/, char** /*service_config_json*/, + int /*query_timeout*/, grpc_core::Combiner* /*combiner*/) { + addr_req* r = static_cast(gpr_malloc(sizeof(*r))); + r->addr = gpr_strdup(addr); + r->on_done = on_done; + r->addrs = nullptr; + r->addresses = addresses; + grpc_timer_init( + &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), + GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); + return nullptr; +} + +static void my_cancel_ares_request_locked(grpc_ares_request* request) { + GPR_ASSERT(request == nullptr); +} + +//////////////////////////////////////////////////////////////////////////////// +// client connection + +static void sched_connect(grpc_closure* closure, grpc_endpoint** ep, + gpr_timespec deadline); + +typedef struct { + grpc_timer timer; + grpc_closure* closure; + grpc_endpoint** ep; + gpr_timespec deadline; +} future_connect; + +static void do_connect(void* arg, grpc_error* error) { + future_connect* fc = static_cast(arg); + if (error != GRPC_ERROR_NONE) { + *fc->ep = nullptr; + grpc_core::ExecCtx::Run(DEBUG_LOCATION, fc->closure, GRPC_ERROR_REF(error)); + } else if (g_server != nullptr) { + grpc_endpoint* client; + grpc_endpoint* server; + grpc_passthru_endpoint_create(&client, &server, g_resource_quota, nullptr); + *fc->ep = client; + + grpc_transport* transport = + grpc_create_chttp2_transport(nullptr, server, false); + grpc_server_setup_transport(g_server, transport, nullptr, nullptr, nullptr); + grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); + + grpc_core::ExecCtx::Run(DEBUG_LOCATION, fc->closure, GRPC_ERROR_NONE); + } else { + sched_connect(fc->closure, fc->ep, fc->deadline); + } + gpr_free(fc); +} + +static void sched_connect(grpc_closure* closure, grpc_endpoint** ep, + gpr_timespec deadline) { + if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) { + *ep = nullptr; + grpc_core::ExecCtx::Run( + DEBUG_LOCATION, closure, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connect deadline exceeded")); + return; + } + + future_connect* fc = static_cast(gpr_malloc(sizeof(*fc))); + fc->closure = closure; + fc->ep = ep; + fc->deadline = deadline; + grpc_timer_init( + &fc->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), + GRPC_CLOSURE_CREATE(do_connect, fc, grpc_schedule_on_exec_ctx)); +} + +static void my_tcp_client_connect(grpc_closure* closure, grpc_endpoint** ep, + grpc_pollset_set* /*interested_parties*/, + const grpc_channel_args* /*channel_args*/, + const grpc_resolved_address* /*addr*/, + grpc_millis deadline) { + sched_connect(closure, ep, + grpc_millis_to_timespec(deadline, GPR_CLOCK_MONOTONIC)); +} + +grpc_tcp_client_vtable fuzz_tcp_client_vtable = {my_tcp_client_connect}; + +//////////////////////////////////////////////////////////////////////////////// +// test driver + +typedef struct validator { + void (*validate)(void* arg, bool success); + void* arg; +} validator; + +static validator* create_validator(void (*validate)(void* arg, bool success), + void* arg) { + validator* v = static_cast(gpr_malloc(sizeof(*v))); + v->validate = validate; + v->arg = arg; + return v; +} + +static void assert_success_and_decrement(void* counter, bool success) { + GPR_ASSERT(success); + --*static_cast(counter); +} + +static void decrement(void* counter, bool /*success*/) { + --*static_cast(counter); +} + +typedef struct connectivity_watch { + int* counter; + gpr_timespec deadline; +} connectivity_watch; + +static connectivity_watch* make_connectivity_watch(gpr_timespec s, + int* counter) { + connectivity_watch* o = + static_cast(gpr_malloc(sizeof(*o))); + o->deadline = s; + o->counter = counter; + return o; +} + +static void validate_connectivity_watch(void* p, bool success) { + connectivity_watch* w = static_cast(p); + if (!success) { + GPR_ASSERT(gpr_time_cmp(gpr_now(w->deadline.clock_type), w->deadline) >= 0); + } + --*w->counter; + gpr_free(w); +} + +static void free_non_null(void* p) { + GPR_ASSERT(p != nullptr); + gpr_free(p); +} + +typedef enum { ROOT, CLIENT, SERVER, PENDING_SERVER } call_state_type; + +#define DONE_FLAG_CALL_CLOSED ((uint64_t)(1 << 0)) + +typedef struct call_state { + call_state_type type; + grpc_call* call; + grpc_byte_buffer* recv_message; + grpc_status_code status; + grpc_metadata_array recv_initial_metadata; + grpc_metadata_array recv_trailing_metadata; + grpc_slice recv_status_details; + int cancelled; + int pending_ops; + bool sent_initial_metadata; + grpc_call_details call_details; + grpc_byte_buffer* send_message; + // starts at 0, individual flags from DONE_FLAG_xxx are set + // as different operations are completed + uint64_t done_flags; + + // array of pointers to free later + size_t num_to_free; + size_t cap_to_free; + void** to_free; + + // array of slices to unref + size_t num_slices_to_unref; + size_t cap_slices_to_unref; + grpc_slice** slices_to_unref; + + struct call_state* next; + struct call_state* prev; +} call_state; + +static call_state* g_active_call; + +static call_state* new_call(call_state* sibling, call_state_type type) { + call_state* c = static_cast(gpr_malloc(sizeof(*c))); + memset(c, 0, sizeof(*c)); + if (sibling != nullptr) { + c->next = sibling; + c->prev = sibling->prev; + c->next->prev = c->prev->next = c; + } else { + c->next = c->prev = c; + } + c->type = type; + return c; +} + +static call_state* maybe_delete_call_state(call_state* call) { + call_state* next = call->next; + + if (call->call != nullptr) return next; + if (call->pending_ops != 0) return next; + + if (call == g_active_call) { + g_active_call = call->next; + GPR_ASSERT(call != g_active_call); + } + + call->prev->next = call->next; + call->next->prev = call->prev; + grpc_metadata_array_destroy(&call->recv_initial_metadata); + grpc_metadata_array_destroy(&call->recv_trailing_metadata); + grpc_slice_unref(call->recv_status_details); + grpc_call_details_destroy(&call->call_details); + + for (size_t i = 0; i < call->num_slices_to_unref; i++) { + grpc_slice_unref(*call->slices_to_unref[i]); + gpr_free(call->slices_to_unref[i]); + } + for (size_t i = 0; i < call->num_to_free; i++) { + gpr_free(call->to_free[i]); + } + gpr_free(call->to_free); + gpr_free(call->slices_to_unref); + + gpr_free(call); + + return next; +} + +static void add_to_free(call_state* call, void* p) { + if (call->num_to_free == call->cap_to_free) { + call->cap_to_free = GPR_MAX(8, 2 * call->cap_to_free); + call->to_free = static_cast( + gpr_realloc(call->to_free, sizeof(*call->to_free) * call->cap_to_free)); + } + call->to_free[call->num_to_free++] = p; +} + +static grpc_slice* add_slice_to_unref(call_state* call, grpc_slice s) { + if (call->num_slices_to_unref == call->cap_slices_to_unref) { + call->cap_slices_to_unref = GPR_MAX(8, 2 * call->cap_slices_to_unref); + call->slices_to_unref = static_cast(gpr_realloc( + call->slices_to_unref, + sizeof(*call->slices_to_unref) * call->cap_slices_to_unref)); + } + call->slices_to_unref[call->num_slices_to_unref] = + static_cast(gpr_malloc(sizeof(grpc_slice))); + *call->slices_to_unref[call->num_slices_to_unref++] = s; + return call->slices_to_unref[call->num_slices_to_unref - 1]; +} + +static void read_metadata(input_stream* inp, size_t* count, + grpc_metadata** metadata, call_state* cs) { + *count = grpc_fuzzer_get_next_byte(inp); + if (*count) { + *metadata = + static_cast(gpr_malloc(*count * sizeof(**metadata))); + memset(*metadata, 0, *count * sizeof(**metadata)); + for (size_t i = 0; i < *count; i++) { + (*metadata)[i].key = read_string_like_slice(inp); + (*metadata)[i].value = read_buffer_like_slice(inp); + (*metadata)[i].flags = grpc_fuzzer_get_next_uint32(inp); + add_slice_to_unref(cs, (*metadata)[i].key); + add_slice_to_unref(cs, (*metadata)[i].value); + } + } else { + *metadata = static_cast(gpr_malloc(1)); + } + add_to_free(cs, *metadata); +} + +static call_state* destroy_call(call_state* call) { + grpc_call_unref(call->call); + call->call = nullptr; + return maybe_delete_call_state(call); +} + +static void finished_request_call(void* csp, bool success) { + call_state* cs = static_cast(csp); + GPR_ASSERT(cs->pending_ops > 0); + --cs->pending_ops; + if (success) { + GPR_ASSERT(cs->call != nullptr); + cs->type = SERVER; + } else { + maybe_delete_call_state(cs); + } +} + +typedef struct { + call_state* cs; + uint8_t has_ops; +} batch_info; + +static void finished_batch(void* p, bool /*success*/) { + batch_info* bi = static_cast(p); + --bi->cs->pending_ops; + if ((bi->has_ops & (1u << GRPC_OP_RECV_MESSAGE)) && + (bi->cs->done_flags & DONE_FLAG_CALL_CLOSED)) { + GPR_ASSERT(bi->cs->recv_message == nullptr); + } + if ((bi->has_ops & (1u << GRPC_OP_RECV_MESSAGE) && + bi->cs->recv_message != nullptr)) { + grpc_byte_buffer_destroy(bi->cs->recv_message); + bi->cs->recv_message = nullptr; + } + if ((bi->has_ops & (1u << GRPC_OP_SEND_MESSAGE))) { + grpc_byte_buffer_destroy(bi->cs->send_message); + bi->cs->send_message = nullptr; + } + if ((bi->has_ops & (1u << GRPC_OP_RECV_STATUS_ON_CLIENT)) || + (bi->has_ops & (1u << GRPC_OP_RECV_CLOSE_ON_SERVER))) { + bi->cs->done_flags |= DONE_FLAG_CALL_CLOSED; + } + maybe_delete_call_state(bi->cs); + gpr_free(bi); +} + +static validator* make_finished_batch_validator(call_state* cs, + uint8_t has_ops) { + batch_info* bi = static_cast(gpr_malloc(sizeof(*bi))); + bi->cs = cs; + bi->has_ops = has_ops; + return create_validator(finished_batch, bi); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + grpc_test_only_set_slice_hash_seed(0); + char* grpc_trace_fuzzer = gpr_getenv("GRPC_TRACE_FUZZER"); + if (squelch && grpc_trace_fuzzer == nullptr) gpr_set_log_function(dont_log); + gpr_free(grpc_trace_fuzzer); + input_stream inp = {data, data + size}; + grpc_set_tcp_client_impl(&fuzz_tcp_client_vtable); + gpr_now_impl = now_impl; + grpc_init(); + grpc_timer_manager_set_threading(false); + { + grpc_core::ExecCtx exec_ctx; + grpc_core::Executor::SetThreadingAll(false); + } + grpc_set_resolver_impl(&fuzzer_resolver); + grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; + grpc_cancel_ares_request_locked = my_cancel_ares_request_locked; + + GPR_ASSERT(g_channel == nullptr); + GPR_ASSERT(g_server == nullptr); + + bool server_shutdown = false; + int pending_server_shutdowns = 0; + int pending_channel_watches = 0; + int pending_pings = 0; + + g_active_call = new_call(nullptr, ROOT); + g_resource_quota = grpc_resource_quota_create("api_fuzzer"); + + grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); + + while (!is_eof(&inp) || g_channel != nullptr || g_server != nullptr || + pending_channel_watches > 0 || pending_pings > 0 || + g_active_call->type != ROOT || g_active_call->next != g_active_call) { + if (is_eof(&inp)) { + if (g_channel != nullptr) { + grpc_channel_destroy(g_channel); + g_channel = nullptr; + } + if (g_server != nullptr) { + if (!server_shutdown) { + grpc_server_shutdown_and_notify( + g_server, cq, + create_validator(assert_success_and_decrement, + &pending_server_shutdowns)); + server_shutdown = true; + pending_server_shutdowns++; + } else if (pending_server_shutdowns == 0) { + grpc_server_destroy(g_server); + g_server = nullptr; + } + } + call_state* s = g_active_call; + do { + if (s->type != PENDING_SERVER && s->call != nullptr) { + s = destroy_call(s); + } else { + s = s->next; + } + } while (s != g_active_call); + + g_now = gpr_time_add(g_now, gpr_time_from_seconds(1, GPR_TIMESPAN)); + } + + grpc_timer_manager_tick(); + + switch (grpc_fuzzer_get_next_byte(&inp)) { + // terminate on bad bytes + default: + end(&inp); + break; + // tickle completion queue + case 0: { + grpc_event ev = grpc_completion_queue_next( + cq, gpr_inf_past(GPR_CLOCK_REALTIME), nullptr); + switch (ev.type) { + case GRPC_OP_COMPLETE: { + validator* v = static_cast(ev.tag); + v->validate(v->arg, ev.success); + gpr_free(v); + break; + } + case GRPC_QUEUE_TIMEOUT: + break; + case GRPC_QUEUE_SHUTDOWN: + abort(); + break; + } + break; + } + // increment global time + case 1: { + g_now = gpr_time_add( + g_now, gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp), + GPR_TIMESPAN)); + break; + } + // create an insecure channel + case 2: { + if (g_channel == nullptr) { + char* target = grpc_fuzzer_get_next_string(&inp, nullptr); + char* target_uri; + gpr_asprintf(&target_uri, "dns:%s", target); + grpc_channel_args* args = read_args(&inp); + g_channel = grpc_insecure_channel_create(target_uri, args, nullptr); + GPR_ASSERT(g_channel != nullptr); + { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args_destroy(args); + } + gpr_free(target_uri); + gpr_free(target); + } else { + end(&inp); + } + break; + } + // destroy a channel + case 3: { + if (g_channel != nullptr) { + grpc_channel_destroy(g_channel); + g_channel = nullptr; + } else { + end(&inp); + } + break; + } + // bring up a server + case 4: { + if (g_server == nullptr) { + grpc_channel_args* args = read_args(&inp); + g_server = grpc_server_create(args, nullptr); + GPR_ASSERT(g_server != nullptr); + { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args_destroy(args); + } + grpc_server_register_completion_queue(g_server, cq, nullptr); + grpc_server_start(g_server); + server_shutdown = false; + GPR_ASSERT(pending_server_shutdowns == 0); + } else { + end(&inp); + } + break; + } + // begin server shutdown + case 5: { + if (g_server != nullptr) { + grpc_server_shutdown_and_notify( + g_server, cq, + create_validator(assert_success_and_decrement, + &pending_server_shutdowns)); + pending_server_shutdowns++; + server_shutdown = true; + } else { + end(&inp); + } + break; + } + // cancel all calls if shutdown + case 6: { + if (g_server != nullptr && server_shutdown) { + grpc_server_cancel_all_calls(g_server); + } else { + end(&inp); + } + break; + } + // destroy server + case 7: { + if (g_server != nullptr && server_shutdown && + pending_server_shutdowns == 0) { + grpc_server_destroy(g_server); + g_server = nullptr; + } else { + end(&inp); + } + break; + } + // check connectivity + case 8: { + if (g_channel != nullptr) { + uint8_t try_to_connect = grpc_fuzzer_get_next_byte(&inp); + if (try_to_connect == 0 || try_to_connect == 1) { + grpc_channel_check_connectivity_state(g_channel, try_to_connect); + } else { + end(&inp); + } + } else { + end(&inp); + } + break; + } + // watch connectivity + case 9: { + if (g_channel != nullptr) { + grpc_connectivity_state st = + grpc_channel_check_connectivity_state(g_channel, 0); + if (st != GRPC_CHANNEL_SHUTDOWN) { + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp), + GPR_TIMESPAN)); + grpc_channel_watch_connectivity_state( + g_channel, st, deadline, cq, + create_validator(validate_connectivity_watch, + make_connectivity_watch( + deadline, &pending_channel_watches))); + pending_channel_watches++; + } + } else { + end(&inp); + } + break; + } + // create a call + case 10: { + bool ok = true; + if (g_channel == nullptr) ok = false; + grpc_call* parent_call = nullptr; + if (g_active_call->type != ROOT) { + if (g_active_call->call == nullptr || g_active_call->type == CLIENT) { + end(&inp); + break; + } + parent_call = g_active_call->call; + } + uint32_t propagation_mask = grpc_fuzzer_get_next_uint32(&inp); + grpc_slice method = read_string_like_slice(&inp); + if (GRPC_SLICE_LENGTH(method) == 0) { + ok = false; + } + grpc_slice host = read_string_like_slice(&inp); + gpr_timespec deadline = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp), + GPR_TIMESPAN)); + + if (ok) { + call_state* cs = new_call(g_active_call, CLIENT); + cs->call = + grpc_channel_create_call(g_channel, parent_call, propagation_mask, + cq, method, &host, deadline, nullptr); + } else { + end(&inp); + } + grpc_slice_unref(method); + grpc_slice_unref(host); + break; + } + // switch the 'current' call + case 11: { + g_active_call = g_active_call->next; + break; + } + // queue some ops on a call + case 12: { + if (g_active_call->type == PENDING_SERVER || + g_active_call->type == ROOT || g_active_call->call == nullptr) { + end(&inp); + break; + } + size_t num_ops = grpc_fuzzer_get_next_byte(&inp); + if (num_ops > 6) { + end(&inp); + break; + } + grpc_op* ops = + static_cast(gpr_malloc(sizeof(grpc_op) * num_ops)); + if (num_ops > 0) memset(ops, 0, sizeof(grpc_op) * num_ops); + bool ok = true; + size_t i; + grpc_op* op; + uint8_t has_ops = 0; + for (i = 0; i < num_ops; i++) { + op = &ops[i]; + switch (grpc_fuzzer_get_next_byte(&inp)) { + default: + /* invalid value */ + op->op = (grpc_op_type)-1; + ok = false; + break; + case GRPC_OP_SEND_INITIAL_METADATA: + if (g_active_call->sent_initial_metadata) { + ok = false; + } else { + g_active_call->sent_initial_metadata = true; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + has_ops |= 1 << GRPC_OP_SEND_INITIAL_METADATA; + read_metadata(&inp, &op->data.send_initial_metadata.count, + &op->data.send_initial_metadata.metadata, + g_active_call); + } + break; + case GRPC_OP_SEND_MESSAGE: + op->op = GRPC_OP_SEND_MESSAGE; + if (g_active_call->send_message != nullptr) { + ok = false; + } else { + has_ops |= 1 << GRPC_OP_SEND_MESSAGE; + g_active_call->send_message = + op->data.send_message.send_message = read_message(&inp); + } + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + has_ops |= 1 << GRPC_OP_SEND_CLOSE_FROM_CLIENT; + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + has_ops |= 1 << GRPC_OP_SEND_STATUS_FROM_SERVER; + read_metadata( + &inp, + &op->data.send_status_from_server.trailing_metadata_count, + &op->data.send_status_from_server.trailing_metadata, + g_active_call); + op->data.send_status_from_server.status = + static_cast( + grpc_fuzzer_get_next_byte(&inp)); + op->data.send_status_from_server.status_details = + add_slice_to_unref(g_active_call, + read_buffer_like_slice(&inp)); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + op->op = GRPC_OP_RECV_INITIAL_METADATA; + has_ops |= 1 << GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = + &g_active_call->recv_initial_metadata; + break; + case GRPC_OP_RECV_MESSAGE: + if (g_active_call->done_flags & DONE_FLAG_CALL_CLOSED) { + ok = false; + } else { + op->op = GRPC_OP_RECV_MESSAGE; + has_ops |= 1 << GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = + &g_active_call->recv_message; + } + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.status = &g_active_call->status; + op->data.recv_status_on_client.trailing_metadata = + &g_active_call->recv_trailing_metadata; + op->data.recv_status_on_client.status_details = + &g_active_call->recv_status_details; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + has_ops |= 1 << GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = + &g_active_call->cancelled; + break; + } + op->reserved = nullptr; + op->flags = grpc_fuzzer_get_next_uint32(&inp); + } + if (g_channel == nullptr) ok = false; + if (ok) { + validator* v = make_finished_batch_validator(g_active_call, has_ops); + g_active_call->pending_ops++; + grpc_call_error error = grpc_call_start_batch( + g_active_call->call, ops, num_ops, v, nullptr); + if (error != GRPC_CALL_OK) { + v->validate(v->arg, false); + gpr_free(v); + } + } else { + end(&inp); + } + if (!ok && (has_ops & (1 << GRPC_OP_SEND_MESSAGE))) { + grpc_byte_buffer_destroy(g_active_call->send_message); + g_active_call->send_message = nullptr; + } + gpr_free(ops); + + break; + } + // cancel current call + case 13: { + if (g_active_call->type != ROOT && g_active_call->call != nullptr) { + grpc_call_cancel(g_active_call->call, nullptr); + } else { + end(&inp); + } + break; + } + // get a calls peer + case 14: { + if (g_active_call->type != ROOT && g_active_call->call != nullptr) { + free_non_null(grpc_call_get_peer(g_active_call->call)); + } else { + end(&inp); + } + break; + } + // get a channels target + case 15: { + if (g_channel != nullptr) { + free_non_null(grpc_channel_get_target(g_channel)); + } else { + end(&inp); + } + break; + } + // send a ping on a channel + case 16: { + if (g_channel != nullptr) { + pending_pings++; + grpc_channel_ping(g_channel, cq, + create_validator(decrement, &pending_pings), + nullptr); + } else { + end(&inp); + } + break; + } + // enable a tracer + case 17: { + char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr); + grpc_tracer_set_enabled(tracer, 1); + gpr_free(tracer); + break; + } + // disable a tracer + case 18: { + char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr); + grpc_tracer_set_enabled(tracer, 0); + gpr_free(tracer); + break; + } + // request a server call + case 19: { + if (g_server == nullptr) { + end(&inp); + break; + } + call_state* cs = new_call(g_active_call, PENDING_SERVER); + cs->pending_ops++; + validator* v = create_validator(finished_request_call, cs); + grpc_call_error error = + grpc_server_request_call(g_server, &cs->call, &cs->call_details, + &cs->recv_initial_metadata, cq, cq, v); + if (error != GRPC_CALL_OK) { + v->validate(v->arg, false); + gpr_free(v); + } + break; + } + // destroy a call + case 20: { + if (g_active_call->type != ROOT && + g_active_call->type != PENDING_SERVER && + g_active_call->call != nullptr) { + destroy_call(g_active_call); + } else { + end(&inp); + } + break; + } + // resize the buffer pool + case 21: { + grpc_resource_quota_resize(g_resource_quota, read_uint22(&inp)); + break; + } + // create a secure channel + case 22: { + if (g_channel == nullptr) { + char* target = grpc_fuzzer_get_next_string(&inp, nullptr); + char* target_uri; + gpr_asprintf(&target_uri, "dns:%s", target); + grpc_channel_args* args = read_args(&inp); + grpc_channel_credentials* creds = read_channel_creds(&inp); + g_channel = + grpc_secure_channel_create(creds, target_uri, args, nullptr); + GPR_ASSERT(g_channel != nullptr); + { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args_destroy(args); + } + gpr_free(target_uri); + gpr_free(target); + grpc_channel_credentials_release(creds); + } else { + end(&inp); + } + break; + } + } + } + + GPR_ASSERT(g_channel == nullptr); + GPR_ASSERT(g_server == nullptr); + GPR_ASSERT(g_active_call->type == ROOT); + GPR_ASSERT(g_active_call->next == g_active_call); + gpr_free(g_active_call); + + grpc_completion_queue_shutdown(cq); + GPR_ASSERT( + grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), nullptr) + .type == GRPC_QUEUE_SHUTDOWN); + grpc_completion_queue_destroy(cq); + + grpc_resource_quota_unref(g_resource_quota); + + grpc_shutdown_blocking(); + return 0; +} diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 86f27295a5f..64603cbc1fc 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -119,7 +119,7 @@ static grpc_ares_request* my_dns_lookup_ares_locked( gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { - *addresses = grpc_core::MakeUnique(); + *addresses = absl::make_unique(); grpc_sockaddr_in sa; sa.sin_family = GRPC_AF_INET; sa.sin_addr.s_addr = 0x100007f; diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc index 9ad2bfad49a..6481405d1b4 100644 --- a/test/core/gprpp/inlined_vector_test.cc +++ b/test/core/gprpp/inlined_vector_test.cc @@ -63,7 +63,7 @@ TEST(InlinedVectorTest, ValuesAreInlined) { TEST(InlinedVectorTest, PushBackWithMove) { InlinedVector, 1> v; - std::unique_ptr i = grpc_core::MakeUnique(3); + std::unique_ptr i = absl::make_unique(3); v.push_back(std::move(i)); EXPECT_EQ(nullptr, i.get()); EXPECT_EQ(1UL, v.size()); @@ -304,15 +304,15 @@ TEST(InlinedVectorTest, MoveAssignmentAllocatedAllocated) { // and move methods are called correctly. class Value { public: - explicit Value(int v) : value_(grpc_core::MakeUnique(v)) {} + explicit Value(int v) : value_(absl::make_unique(v)) {} // copyable Value(const Value& v) { - value_ = grpc_core::MakeUnique(*v.value_); + value_ = absl::make_unique(*v.value_); copied_ = true; } Value& operator=(const Value& v) { - value_ = grpc_core::MakeUnique(*v.value_); + value_ = absl::make_unique(*v.value_); copied_ = true; return *this; } @@ -463,10 +463,10 @@ TEST(InlinedVectorTest, MoveAssignmentMovesElementsAllocated) { TEST(InlinedVectorTest, PopBackInlined) { InlinedVector, 2> v; // Add two elements, pop one out - v.push_back(grpc_core::MakeUnique(3)); + v.push_back(absl::make_unique(3)); EXPECT_EQ(1UL, v.size()); EXPECT_EQ(3, *v[0]); - v.push_back(grpc_core::MakeUnique(5)); + v.push_back(absl::make_unique(5)); EXPECT_EQ(2UL, v.size()); EXPECT_EQ(5, *v[1]); v.pop_back(); @@ -478,7 +478,7 @@ TEST(InlinedVectorTest, PopBackAllocated) { InlinedVector, kInlinedSize> v; // Add elements to ensure allocated backing. for (size_t i = 0; i < kInlinedSize + 1; ++i) { - v.push_back(grpc_core::MakeUnique(3)); + v.push_back(absl::make_unique(3)); EXPECT_EQ(i + 1, v.size()); } size_t sz = v.size(); @@ -494,7 +494,7 @@ TEST(InlinedVectorTest, Resize) { EXPECT_EQ(5UL, v.size()); EXPECT_EQ(nullptr, v[4]); // Size down. - v[4] = grpc_core::MakeUnique(5); + v[4] = absl::make_unique(5); v.resize(1); EXPECT_EQ(1UL, v.size()); } diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 7b3b8393442..b22cd4bdbd3 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -81,7 +81,7 @@ int main(int /*argc*/, char* /*argv*/ []) { grpc_init(); HandshakerRegistry::RegisterHandshakerFactory( true /* at_start */, HANDSHAKER_SERVER, - grpc_core::MakeUnique()); + absl::make_unique()); const char* full_alpn_list[] = {"grpc-exp", "h2"}; GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp")); grpc_shutdown_blocking();