diff --git a/BUILD b/BUILD index de7eda25c68..c14200d9509 100644 --- a/BUILD +++ b/BUILD @@ -5950,6 +5950,8 @@ grpc_cc_library( ], external_deps = [ "absl/memory", + "absl/status", + "absl/status:statusor", "absl/strings", "absl/strings:str_format", "absl/types:optional", diff --git a/src/core/ext/xds/xds_endpoint.cc b/src/core/ext/xds/xds_endpoint.cc index 7dd0aaa91cc..a9e2699e17f 100644 --- a/src/core/ext/xds/xds_endpoint.cc +++ b/src/core/ext/xds/xds_endpoint.cc @@ -46,7 +46,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/error.h" -#include "src/core/lib/iomgr/resolved_address.h" +#include "src/core/lib/transport/error_utils.h" namespace grpc_core { @@ -176,16 +176,14 @@ grpc_error_handle ServerAddressParseAndAppend( } } // Populate grpc_resolved_address. - grpc_resolved_address addr; - grpc_error_handle error = - grpc_string_to_sockaddr(&addr, address_str.c_str(), port); - if (!GRPC_ERROR_IS_NONE(error)) return error; + auto addr = StringToSockaddr(address_str, port); + if (!addr.ok()) return absl_status_to_grpc_error(addr.status()); // Append the address to the list. std::map> attributes; attributes[ServerAddressWeightAttribute::kServerAddressWeightAttributeKey] = absl::make_unique(weight); - list->emplace_back(addr, ChannelArgs(), std::move(attributes)); + list->emplace_back(*addr, ChannelArgs(), std::move(attributes)); return GRPC_ERROR_NONE; } diff --git a/src/core/ext/xds/xds_listener.cc b/src/core/ext/xds/xds_listener.cc index 35f069f6b44..be2bee44865 100644 --- a/src/core/ext/xds/xds_listener.cc +++ b/src/core/ext/xds/xds_listener.cc @@ -567,9 +567,9 @@ grpc_error_handle CidrRangeParse( XdsListenerResource::FilterChainMap::CidrRange* cidr_range) { std::string address_prefix = UpbStringToStdString( envoy_config_core_v3_CidrRange_address_prefix(cidr_range_proto)); - grpc_error_handle error = - grpc_string_to_sockaddr(&cidr_range->address, address_prefix.c_str(), 0); - if (!GRPC_ERROR_IS_NONE(error)) return error; + auto address = StringToSockaddr(address_prefix, /*port=*/0); + if (!address.ok()) return absl_status_to_grpc_error(address.status()); + cidr_range->address = *address; cidr_range->prefix_len = 0; auto* prefix_len_proto = envoy_config_core_v3_CidrRange_prefix_len(cidr_range_proto); diff --git a/src/core/ext/xds/xds_server_config_fetcher.cc b/src/core/ext/xds/xds_server_config_fetcher.cc index 30cd9b1e8cf..c26b73271ca 100644 --- a/src/core/ext/xds/xds_server_config_fetcher.cc +++ b/src/core/ext/xds/xds_server_config_fetcher.cc @@ -962,13 +962,10 @@ const XdsListenerResource::FilterChainData* FindFilterChainDataForSourceType( if (!SplitHostPort(source_uri->path(), &host, &port)) { return nullptr; } - grpc_resolved_address source_addr; - grpc_error_handle error = grpc_string_to_sockaddr( - &source_addr, host.c_str(), 0 /* port doesn't matter here */); - if (!GRPC_ERROR_IS_NONE(error)) { - gpr_log(GPR_DEBUG, "Could not parse string to socket address: %s", - host.c_str()); - GRPC_ERROR_UNREF(error); + auto source_addr = StringToSockaddr(host, 0); // Port doesn't matter here. + if (!source_addr.ok()) { + gpr_log(GPR_DEBUG, "Could not parse \"%s\" as socket address: %s", + host.c_str(), source_addr.status().ToString().c_str()); return nullptr; } // Use kAny only if kSameIporLoopback and kExternal are empty @@ -982,20 +979,20 @@ const XdsListenerResource::FilterChainData* FindFilterChainDataForSourceType( return FindFilterChainDataForSourceIp( source_types_array[static_cast( XdsListenerResource::FilterChainMap::ConnectionSourceType::kAny)], - &source_addr, port); + &*source_addr, port); } - if (IsLoopbackIp(&source_addr) || host == destination_ip) { + if (IsLoopbackIp(&*source_addr) || host == destination_ip) { return FindFilterChainDataForSourceIp( source_types_array[static_cast( XdsListenerResource::FilterChainMap::ConnectionSourceType:: kSameIpOrLoopback)], - &source_addr, port); + &*source_addr, port); } else { return FindFilterChainDataForSourceIp( source_types_array[static_cast( XdsListenerResource::FilterChainMap::ConnectionSourceType:: kExternal)], - &source_addr, port); + &*source_addr, port); } } @@ -1013,13 +1010,11 @@ const XdsListenerResource::FilterChainData* FindFilterChainDataForDestinationIp( if (!SplitHostPort(destination_uri->path(), &host, &port)) { return nullptr; } - grpc_resolved_address destination_addr; - grpc_error_handle error = grpc_string_to_sockaddr( - &destination_addr, host.c_str(), 0 /* port doesn't matter here */); - if (!GRPC_ERROR_IS_NONE(error)) { - gpr_log(GPR_DEBUG, "Could not parse string to socket address: %s", - host.c_str()); - GRPC_ERROR_UNREF(error); + auto destination_addr = + StringToSockaddr(host, 0); // Port doesn't matter here. + if (!destination_addr.ok()) { + gpr_log(GPR_DEBUG, "Could not parse \"%s\" as socket address: %s", + host.c_str(), destination_addr.status().ToString().c_str()); return nullptr; } const XdsListenerResource::FilterChainMap::DestinationIp* best_match = @@ -1037,7 +1032,7 @@ const XdsListenerResource::FilterChainData* FindFilterChainDataForDestinationIp( entry.prefix_range->prefix_len) { continue; } - if (grpc_sockaddr_match_subnet(&destination_addr, + if (grpc_sockaddr_match_subnet(&*destination_addr, &entry.prefix_range->address, entry.prefix_range->prefix_len)) { best_match = &entry; diff --git a/src/core/lib/address_utils/parse_address.cc b/src/core/lib/address_utils/parse_address.cc index e0642a3226c..a1179d903eb 100644 --- a/src/core/lib/address_utils/parse_address.cc +++ b/src/core/lib/address_utils/parse_address.cc @@ -28,12 +28,12 @@ #endif #include +#include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/strip.h" #include -#include "src/core/lib/address_utils/sockaddr_utils.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/grpc_if_nametoindex.h" @@ -317,21 +317,23 @@ uint16_t grpc_strhtons(const char* port) { return htons(static_cast(atoi(port))); } -grpc_error_handle grpc_string_to_sockaddr(grpc_resolved_address* out, - const char* addr, int port) { - memset(out, 0, sizeof(grpc_resolved_address)); - grpc_sockaddr_in6* addr6 = reinterpret_cast(out->addr); - grpc_sockaddr_in* addr4 = reinterpret_cast(out->addr); - if (grpc_inet_pton(GRPC_AF_INET6, addr, &addr6->sin6_addr) == 1) { - addr6->sin6_family = GRPC_AF_INET6; - out->len = sizeof(grpc_sockaddr_in6); - } else if (grpc_inet_pton(GRPC_AF_INET, addr, &addr4->sin_addr) == 1) { - addr4->sin_family = GRPC_AF_INET; - out->len = sizeof(grpc_sockaddr_in); - } else { - return GRPC_ERROR_CREATE_FROM_CPP_STRING( - absl::StrCat("Failed to parse address:", addr)); +namespace grpc_core { + +absl::StatusOr StringToSockaddr( + absl::string_view address_and_port) { + grpc_resolved_address out; + memset(&out, 0, sizeof(grpc_resolved_address)); + if (!grpc_parse_ipv4_hostport(address_and_port, &out, /*log_errors=*/false) && + !grpc_parse_ipv6_hostport(address_and_port, &out, /*log_errors=*/false)) { + return absl::InvalidArgumentError( + absl::StrCat("Failed to parse address:", address_and_port)); } - grpc_sockaddr_set_port(out, port); - return GRPC_ERROR_NONE; + return out; } + +absl::StatusOr StringToSockaddr( + absl::string_view address, int port) { + return StringToSockaddr(JoinHostPort(address, port)); +} + +} // namespace grpc_core diff --git a/src/core/lib/address_utils/parse_address.h b/src/core/lib/address_utils/parse_address.h index 85b24ace3ea..c44ec619449 100644 --- a/src/core/lib/address_utils/parse_address.h +++ b/src/core/lib/address_utils/parse_address.h @@ -23,6 +23,7 @@ #include +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "src/core/lib/iomgr/error.h" @@ -62,13 +63,15 @@ bool grpc_parse_ipv6_hostport(absl::string_view hostport, /* Converts named or numeric port to a uint16 suitable for use in a sockaddr. */ uint16_t grpc_strhtons(const char* port); -// Newer form of grpc_string_to_sockaddr which returns an error instead of -// crashing if \a addr is not IPv6/IPv6 -grpc_error_handle grpc_string_to_sockaddr(grpc_resolved_address* out, - const char* addr, int port); - namespace grpc_core { +// Parses an IPv4 or IPv6 address string and returns a sockaddr with the +// specified address and port. +absl::StatusOr StringToSockaddr( + absl::string_view address_and_port); +absl::StatusOr StringToSockaddr( + absl::string_view address, int port); + /** Populate \a resolved_addr to be a unix socket at |path| */ grpc_error_handle UnixSockaddrPopulate(absl::string_view path, grpc_resolved_address* resolved_addr); diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index f823af70c6c..2d0ccf38d9d 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -20,8 +20,6 @@ #include "src/core/lib/channel/channelz.h" -#include - #include #include #include @@ -42,10 +40,7 @@ #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/uri/uri_parser.h" @@ -424,42 +419,38 @@ namespace { void PopulateSocketAddressJson(Json::Object* json, const char* name, const char* addr_str) { if (addr_str == nullptr) return; - Json::Object data; absl::StatusOr uri = URI::Parse(addr_str); - if (uri.ok() && (uri->scheme() == "ipv4" || uri->scheme() == "ipv6")) { - std::string host; - std::string port; - GPR_ASSERT( - SplitHostPort(absl::StripPrefix(uri->path(), "/"), &host, &port)); - int port_num = -1; - if (!port.empty()) { - port_num = atoi(port.data()); - } - grpc_resolved_address resolved_host; - grpc_error_handle error = - grpc_string_to_sockaddr(&resolved_host, host.c_str(), port_num); - if (GRPC_ERROR_IS_NONE(error)) { - std::string packed_host = grpc_sockaddr_get_packed_host(&resolved_host); - std::string b64_host = absl::Base64Escape(packed_host); - data["tcpip_address"] = Json::Object{ - {"port", port_num}, - {"ip_address", b64_host}, + if (uri.ok()) { + if (uri->scheme() == "ipv4" || uri->scheme() == "ipv6") { + auto address = StringToSockaddr(absl::StripPrefix(uri->path(), "/")); + if (address.ok()) { + std::string packed_host = grpc_sockaddr_get_packed_host(&*address); + (*json)[name] = Json::Object{ + {"tcpip_address", + Json::Object{ + {"port", grpc_sockaddr_get_port(&*address)}, + {"ip_address", absl::Base64Escape(packed_host)}, + }}, + }; + return; + } + } else if (uri->scheme() == "unix") { + (*json)[name] = Json::Object{ + {"uds_address", + Json::Object{ + {"filename", uri->path()}, + }}, }; - (*json)[name] = std::move(data); return; } - GRPC_ERROR_UNREF(error); - } - if (uri.ok() && uri->scheme() == "unix") { - data["uds_address"] = Json::Object{ - {"filename", uri->path()}, - }; - } else { - data["other_address"] = Json::Object{ - {"name", addr_str}, - }; } - (*json)[name] = std::move(data); + // Unknown address type. + (*json)[name] = Json::Object{ + {"other_address", + Json::Object{ + {"name", addr_str}, + }}, + }; } } // namespace diff --git a/src/core/lib/security/authorization/evaluate_args.cc b/src/core/lib/security/authorization/evaluate_args.cc index c1efb202f7b..d8544e962ca 100644 --- a/src/core/lib/security/authorization/evaluate_args.cc +++ b/src/core/lib/security/authorization/evaluate_args.cc @@ -16,6 +16,9 @@ #include "src/core/lib/security/authorization/evaluate_args.h" +#include + +#include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/match.h" #include "absl/strings/numbers.h" @@ -25,7 +28,6 @@ #include "src/core/lib/address_utils/parse_address.h" #include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/credentials/tls/tls_utils.h" #include "src/core/lib/slice/slice.h" #include "src/core/lib/uri/uri_parser.h" @@ -54,13 +56,14 @@ EvaluateArgs::PerChannelArgs::Address ParseEndpointUri( std::string(port_view).c_str()); } address.address_str = std::string(host_view); - grpc_error_handle error = grpc_string_to_sockaddr( - &address.address, address.address_str.c_str(), address.port); - if (!GRPC_ERROR_IS_NONE(error)) { - gpr_log(GPR_DEBUG, "Address %s is not IPv4/IPv6. Error: %s", - address.address_str.c_str(), grpc_error_std_string(error).c_str()); + auto resolved_address = StringToSockaddr(uri->path()); + if (!resolved_address.ok()) { + gpr_log(GPR_DEBUG, "Address \"%s\" is not IPv4/IPv6. Error: %s", + uri->path().c_str(), resolved_address.status().ToString().c_str()); + memset(&address.address, 0, sizeof(address.address)); + } else { + address.address = *resolved_address; } - GRPC_ERROR_UNREF(error); return address; } diff --git a/src/core/lib/security/authorization/matchers.cc b/src/core/lib/security/authorization/matchers.cc index df07b8ee2d6..e9c2d783491 100644 --- a/src/core/lib/security/authorization/matchers.cc +++ b/src/core/lib/security/authorization/matchers.cc @@ -16,10 +16,14 @@ #include "src/core/lib/security/authorization/matchers.h" +#include + #include #include #include "absl/memory/memory.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include @@ -27,7 +31,6 @@ #include "src/core/lib/address_utils/parse_address.h" #include "src/core/lib/address_utils/sockaddr_utils.h" -#include "src/core/lib/iomgr/error.h" namespace grpc_core { @@ -150,16 +153,16 @@ bool HeaderAuthorizationMatcher::Matches(const EvaluateArgs& args) const { IpAuthorizationMatcher::IpAuthorizationMatcher(Type type, Rbac::CidrRange range) : type_(type), prefix_len_(range.prefix_len) { - grpc_error_handle error = - grpc_string_to_sockaddr(&subnet_address_, range.address_prefix.c_str(), - /*port does not matter here*/ 0); - if (GRPC_ERROR_IS_NONE(error)) { - grpc_sockaddr_mask_bits(&subnet_address_, prefix_len_); - } else { - gpr_log(GPR_DEBUG, "CidrRange address %s is not IPv4/IPv6. Error: %s", - range.address_prefix.c_str(), grpc_error_std_string(error).c_str()); + auto address = + StringToSockaddr(range.address_prefix, 0); // Port does not matter here. + if (!address.ok()) { + gpr_log(GPR_DEBUG, "CidrRange address \"%s\" is not IPv4/IPv6. Error: %s", + range.address_prefix.c_str(), address.status().ToString().c_str()); + memset(&subnet_address_, 0, sizeof(subnet_address_)); + return; } - GRPC_ERROR_UNREF(error); + subnet_address_ = *address; + grpc_sockaddr_mask_bits(&subnet_address_, prefix_len_); } bool IpAuthorizationMatcher::Matches(const EvaluateArgs& args) const { diff --git a/test/core/address_utils/sockaddr_utils_test.cc b/test/core/address_utils/sockaddr_utils_test.cc index 3ecb5a7f822..4e82070be81 100644 --- a/test/core/address_utils/sockaddr_utils_test.cc +++ b/test/core/address_utils/sockaddr_utils_test.cc @@ -300,16 +300,14 @@ TEST(SockAddrUtilsTest, SockAddrSetGetPort) { void VerifySocketAddressMatch(const std::string& ip_address, const std::string& subnet, uint32_t mask_bits, bool success) { - grpc_resolved_address addr; - ASSERT_EQ(grpc_string_to_sockaddr(&addr, ip_address.c_str(), false), - GRPC_ERROR_NONE); // Setting the port has no effect on the match. - grpc_sockaddr_set_port(&addr, 12345); - grpc_resolved_address subnet_addr; - ASSERT_EQ(grpc_string_to_sockaddr(&subnet_addr, subnet.c_str(), false), - GRPC_ERROR_NONE); - grpc_sockaddr_mask_bits(&subnet_addr, mask_bits); - EXPECT_EQ(grpc_sockaddr_match_subnet(&addr, &subnet_addr, mask_bits), success) + auto addr = grpc_core::StringToSockaddr(ip_address, /*port=*/12345); + ASSERT_TRUE(addr.ok()) << addr.status(); + auto subnet_addr = grpc_core::StringToSockaddr(subnet, /*port=*/0); + ASSERT_TRUE(subnet_addr.ok()) << subnet_addr.status(); + grpc_sockaddr_mask_bits(&*subnet_addr, mask_bits); + EXPECT_EQ(grpc_sockaddr_match_subnet(&*addr, &*subnet_addr, mask_bits), + success) << "IP=" << ip_address << " Subnet=" << subnet << " Mask=" << mask_bits; } diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm index eac8cdf6b5c..226cb956939 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm @@ -78,8 +78,6 @@ static void must_fail(void* arg, grpc_error_handle error) { } - (void)testSucceeds { - grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = reinterpret_cast(resolved_addr.addr); int svr_fd; int r; int connections_complete_before; @@ -88,12 +86,14 @@ static void must_fail(void* arg, grpc_error_handle error) { gpr_log(GPR_DEBUG, "test_succeeds"); - GPR_ASSERT(grpc_string_to_sockaddr(&resolved_addr, "127.0.0.1", 0) == GRPC_ERROR_NONE); + auto resolved_addr = grpc_core::StringToSockaddr("127.0.0.1:0"); + GPR_ASSERT(resolved_addr.ok()); + struct sockaddr_in* addr = reinterpret_cast(resolved_addr->addr); /* create a phony server */ svr_fd = socket(AF_INET, SOCK_STREAM, 0); GPR_ASSERT(svr_fd >= 0); - GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr.len)); + GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr->len)); GPR_ASSERT(0 == listen(svr_fd, 1)); gpr_mu_lock(&g_mu); @@ -101,20 +101,20 @@ static void must_fail(void* arg, grpc_error_handle error) { gpr_mu_unlock(&g_mu); /* connect to it */ - GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0); + GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr->len) == 0); GRPC_CLOSURE_INIT(&done, must_succeed, nullptr, grpc_schedule_on_exec_ctx); auto args = grpc_core::CoreConfiguration::Get() .channel_args_preconditioning() .PreconditionChannelArgs(nullptr) .ToC(); - grpc_tcp_client_connect(&done, &g_connecting, nullptr, args.get(), &resolved_addr, + grpc_tcp_client_connect(&done, &g_connecting, nullptr, args.get(), &*resolved_addr, grpc_core::Timestamp::InfFuture()); /* await the connection */ do { - resolved_addr.len = sizeof(addr); + resolved_addr->len = sizeof(addr); r = accept(svr_fd, reinterpret_cast(addr), - reinterpret_cast(&resolved_addr.len)); + reinterpret_cast(&resolved_addr->len)); } while (r == -1 && errno == EINTR); GPR_ASSERT(r >= 0); close(r); @@ -137,21 +137,21 @@ static void must_fail(void* arg, grpc_error_handle error) { - (void)testFails { grpc_core::ExecCtx exec_ctx; - grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = reinterpret_cast(resolved_addr.addr); int connections_complete_before; grpc_closure done; int svr_fd; gpr_log(GPR_DEBUG, "test_fails"); - GPR_ASSERT(grpc_string_to_sockaddr(&resolved_addr, "127.0.0.1", 0) == GRPC_ERROR_NONE); + auto resolved_addr = grpc_core::StringToSockaddr("127.0.0.1:0"); + GPR_ASSERT(resolved_addr.ok()); + struct sockaddr_in* addr = reinterpret_cast(resolved_addr->addr); svr_fd = socket(AF_INET, SOCK_STREAM, 0); GPR_ASSERT(svr_fd >= 0); - GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr.len)); + GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr->len)); GPR_ASSERT(0 == listen(svr_fd, 1)); - GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0); + GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr->len) == 0); close(svr_fd); gpr_mu_lock(&g_mu); @@ -164,7 +164,7 @@ static void must_fail(void* arg, grpc_error_handle error) { .channel_args_preconditioning() .PreconditionChannelArgs(nullptr) .ToC(); - grpc_tcp_client_connect(&done, &g_connecting, nullptr, args.get(), &resolved_addr, + grpc_tcp_client_connect(&done, &g_connecting, nullptr, args.get(), &*resolved_addr, grpc_core::Timestamp::InfFuture()); grpc_core::ExecCtx::Get()->Flush(); diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm index 42421911d1d..6d94118183f 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm @@ -106,8 +106,6 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch grpc_core::ExecCtx exec_ctx; - grpc_resolved_address resolved_addr; - struct sockaddr_in *addr = reinterpret_cast(resolved_addr.addr); int svr_fd; int r; std::promise connected_promise; @@ -115,29 +113,30 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch gpr_log(GPR_DEBUG, "test_succeeds"); - GPR_ASSERT(grpc_string_to_sockaddr(&resolved_addr, "127.0.0.1", 0) == GRPC_ERROR_NONE); + auto resolved_addr = grpc_core::StringToSockaddr("127.0.0.1:0"); + struct sockaddr_in *addr = reinterpret_cast(resolved_addr->addr); /* create a phony server */ svr_fd = socket(AF_INET, SOCK_STREAM, 0); XCTAssertGreaterThanOrEqual(svr_fd, 0); - XCTAssertEqual(bind(svr_fd, (struct sockaddr *)addr, (socklen_t)resolved_addr.len), 0); + XCTAssertEqual(bind(svr_fd, (struct sockaddr *)addr, (socklen_t)resolved_addr->len), 0); XCTAssertEqual(listen(svr_fd, 1), 0); /* connect to it */ - XCTAssertEqual(getsockname(svr_fd, (struct sockaddr *)addr, (socklen_t *)&resolved_addr.len), 0); + XCTAssertEqual(getsockname(svr_fd, (struct sockaddr *)addr, (socklen_t *)&resolved_addr->len), 0); init_event_closure(&done, &connected_promise); auto args = grpc_core::CoreConfiguration::Get() .channel_args_preconditioning() .PreconditionChannelArgs(nullptr) .ToC(); - grpc_tcp_client_connect(&done, &ep_, nullptr, args.get(), &resolved_addr, + grpc_tcp_client_connect(&done, &ep_, nullptr, args.get(), &*resolved_addr, grpc_core::Timestamp::InfFuture()); /* await the connection */ do { - resolved_addr.len = sizeof(addr); + resolved_addr->len = sizeof(addr); r = accept(svr_fd, reinterpret_cast(addr), - reinterpret_cast(&resolved_addr.len)); + reinterpret_cast(&resolved_addr->len)); } while (r == -1 && errno == EINTR); XCTAssertGreaterThanOrEqual(r, 0, @"connection failed with return code %@ and errno %@", @(r), @(errno));