diff --git a/BUILD b/BUILD index 23e55e2beb1..cae523d8e14 100644 --- a/BUILD +++ b/BUILD @@ -1330,6 +1330,7 @@ grpc_cc_library( "//src/core:lib/iomgr/tcp_windows.cc", "//src/core:lib/iomgr/unix_sockets_posix.cc", "//src/core:lib/iomgr/unix_sockets_posix_noop.cc", + "//src/core:lib/iomgr/vsock.cc", "//src/core:lib/iomgr/wakeup_fd_eventfd.cc", "//src/core:lib/iomgr/wakeup_fd_nospecial.cc", "//src/core:lib/iomgr/wakeup_fd_pipe.cc", @@ -1426,6 +1427,7 @@ grpc_cc_library( "//src/core:lib/iomgr/tcp_server_utils_posix.h", "//src/core:lib/iomgr/tcp_windows.h", "//src/core:lib/iomgr/unix_sockets_posix.h", + "//src/core:lib/iomgr/vsock.h", "//src/core:lib/iomgr/wakeup_fd_pipe.h", "//src/core:lib/iomgr/wakeup_fd_posix.h", "//src/core:lib/resource_quota/api.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b139832c25..cefc0f29aec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2182,6 +2182,7 @@ add_library(grpc src/core/lib/iomgr/timer_manager.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc + src/core/lib/iomgr/vsock.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -2883,6 +2884,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/timer_manager.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc + src/core/lib/iomgr/vsock.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -4414,6 +4416,7 @@ add_library(grpc_authorization_provider src/core/lib/iomgr/timer_manager.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc + src/core/lib/iomgr/vsock.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -11649,6 +11652,7 @@ add_executable(frame_test src/core/lib/iomgr/timer_manager.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc + src/core/lib/iomgr/vsock.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc diff --git a/Makefile b/Makefile index 0f9b5c055c6..09c3152a815 100644 --- a/Makefile +++ b/Makefile @@ -1562,6 +1562,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/timer_manager.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ + src/core/lib/iomgr/vsock.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -2117,6 +2118,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/timer_manager.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ + src/core/lib/iomgr/vsock.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 843c3a1f42c..e1deb879e98 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -823,6 +823,7 @@ libs: - src/core/lib/iomgr/timer_heap.h - src/core/lib/iomgr/timer_manager.h - src/core/lib/iomgr/unix_sockets_posix.h + - src/core/lib/iomgr/vsock.h - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/json/json.h @@ -1613,6 +1614,7 @@ libs: - src/core/lib/iomgr/timer_manager.cc - src/core/lib/iomgr/unix_sockets_posix.cc - src/core/lib/iomgr/unix_sockets_posix_noop.cc + - src/core/lib/iomgr/vsock.cc - src/core/lib/iomgr/wakeup_fd_eventfd.cc - src/core/lib/iomgr/wakeup_fd_nospecial.cc - src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -2203,6 +2205,7 @@ libs: - src/core/lib/iomgr/timer_heap.h - src/core/lib/iomgr/timer_manager.h - src/core/lib/iomgr/unix_sockets_posix.h + - src/core/lib/iomgr/vsock.h - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/json/json.h @@ -2602,6 +2605,7 @@ libs: - src/core/lib/iomgr/timer_manager.cc - src/core/lib/iomgr/unix_sockets_posix.cc - src/core/lib/iomgr/unix_sockets_posix_noop.cc + - src/core/lib/iomgr/vsock.cc - src/core/lib/iomgr/wakeup_fd_eventfd.cc - src/core/lib/iomgr/wakeup_fd_nospecial.cc - src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -3697,6 +3701,7 @@ libs: - src/core/lib/iomgr/timer_heap.h - src/core/lib/iomgr/timer_manager.h - src/core/lib/iomgr/unix_sockets_posix.h + - src/core/lib/iomgr/vsock.h - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/json/json.h @@ -3980,6 +3985,7 @@ libs: - src/core/lib/iomgr/timer_manager.cc - src/core/lib/iomgr/unix_sockets_posix.cc - src/core/lib/iomgr/unix_sockets_posix_noop.cc + - src/core/lib/iomgr/vsock.cc - src/core/lib/iomgr/wakeup_fd_eventfd.cc - src/core/lib/iomgr/wakeup_fd_nospecial.cc - src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -7643,6 +7649,7 @@ targets: - src/core/lib/iomgr/timer_heap.h - src/core/lib/iomgr/timer_manager.h - src/core/lib/iomgr/unix_sockets_posix.h + - src/core/lib/iomgr/vsock.h - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/json/json.h @@ -7907,6 +7914,7 @@ targets: - src/core/lib/iomgr/timer_manager.cc - src/core/lib/iomgr/unix_sockets_posix.cc - src/core/lib/iomgr/unix_sockets_posix_noop.cc + - src/core/lib/iomgr/vsock.cc - src/core/lib/iomgr/wakeup_fd_eventfd.cc - src/core/lib/iomgr/wakeup_fd_nospecial.cc - src/core/lib/iomgr/wakeup_fd_pipe.cc diff --git a/config.m4 b/config.m4 index 154c52ea9fe..bee99942ebb 100644 --- a/config.m4 +++ b/config.m4 @@ -687,6 +687,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/timer_manager.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ + src/core/lib/iomgr/vsock.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ diff --git a/config.w32 b/config.w32 index c7d6232e7dc..158c0fcbcd1 100644 --- a/config.w32 +++ b/config.w32 @@ -652,6 +652,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\timer_manager.cc " + "src\\core\\lib\\iomgr\\unix_sockets_posix.cc " + "src\\core\\lib\\iomgr\\unix_sockets_posix_noop.cc " + + "src\\core\\lib\\iomgr\\vsock.cc " + "src\\core\\lib\\iomgr\\wakeup_fd_eventfd.cc " + "src\\core\\lib\\iomgr\\wakeup_fd_nospecial.cc " + "src\\core\\lib\\iomgr\\wakeup_fd_pipe.cc " + diff --git a/doc/naming.md b/doc/naming.md index 5408e3c0638..8d385915b19 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -49,6 +49,12 @@ Most gRPC implementations support the following URI schemes: as the first character; the implementation will prepend this null. Do not include the null in `abstract_path`. +- `vsock:cid:port` -- VSOCK (Linux systems only) + - `cid` is 32-bit Context Identifier (CID). It indicates the source or + destination, which is either a virtual machine or the host. + - `port` is a 32-bit port number. It differentiates between multiple + services running on a single machine. + The following schemes are supported by the gRPC C-core implementation, but may not be supported in other languages: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3c2bf03332d..d1148fbf37b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -917,6 +917,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_heap.h', 'src/core/lib/iomgr/timer_manager.h', 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/vsock.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/json/json.h', @@ -1957,6 +1958,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_heap.h', 'src/core/lib/iomgr/timer_manager.h', 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/vsock.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/json/json.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 20e682b4184..85b81e2b9af 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1493,6 +1493,8 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix.h', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', + 'src/core/lib/iomgr/vsock.h', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', @@ -2684,6 +2686,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_heap.h', 'src/core/lib/iomgr/timer_manager.h', 'src/core/lib/iomgr/unix_sockets_posix.h', + 'src/core/lib/iomgr/vsock.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/json/json.h', diff --git a/grpc.gemspec b/grpc.gemspec index 75fbdb3c150..d4c6b2b3f56 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1399,6 +1399,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/unix_sockets_posix.cc ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.h ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix_noop.cc ) + s.files += %w( src/core/lib/iomgr/vsock.cc ) + s.files += %w( src/core/lib/iomgr/vsock.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_eventfd.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.cc ) diff --git a/grpc.gyp b/grpc.gyp index b047a97fd11..81657590cc5 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -865,6 +865,7 @@ 'src/core/lib/iomgr/timer_manager.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', @@ -1359,6 +1360,7 @@ 'src/core/lib/iomgr/timer_manager.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', @@ -1875,6 +1877,7 @@ 'src/core/lib/iomgr/timer_manager.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', diff --git a/package.xml b/package.xml index aeee9771a7c..4e13d19978a 100644 --- a/package.xml +++ b/package.xml @@ -1381,6 +1381,8 @@ + + diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc index 2ba70f543e2..6eb61fce4fa 100644 --- a/src/core/ext/filters/client_channel/http_proxy.cc +++ b/src/core/ext/filters/client_channel/http_proxy.cc @@ -180,6 +180,11 @@ absl::optional HttpProxyMapper::MapName( std::string(server_uri).c_str()); return absl::nullopt; } + if (uri->scheme() == "vsock") { + gpr_log(GPR_INFO, "not using proxy for VSock '%s'", + std::string(server_uri).c_str()); + return absl::nullopt; + } // Prefer using 'no_grpc_proxy'. Fallback on 'no_proxy' if it is not set. auto no_proxy_str = GetEnv("no_grpc_proxy"); if (!no_proxy_str.has_value()) { diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/README.md b/src/core/ext/filters/client_channel/resolver/sockaddr/README.md index e307ba88f57..210ffdf3ad4 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/README.md +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/README.md @@ -1 +1 @@ -Support for resolving ipv4:, ipv6:, unix: schemes +Support for resolving ipv4:, ipv6:, unix:, vsock: schemes 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 7dc7859303a..8a4b6584fdd 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 @@ -172,6 +172,26 @@ class UnixAbstractResolverFactory : public ResolverFactory { }; #endif // GRPC_HAVE_UNIX_SOCKET +#ifdef GRPC_HAVE_VSOCK +class VSockResolverFactory : public ResolverFactory { + public: + bool IsValidUri(const URI& uri) const override { + return ParseUri(uri, grpc_parse_vsock, nullptr); + } + + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return CreateSockaddrResolver(std::move(args), grpc_parse_vsock); + } + + std::string GetDefaultAuthority(const URI& /*uri*/) const override { + return "localhost"; + } + + absl::string_view scheme() const override { return "vsock"; } +}; + +#endif // GRPC_HAVE_VSOCK + } // namespace void RegisterSockaddrResolver(CoreConfiguration::Builder* builder) { @@ -185,6 +205,10 @@ void RegisterSockaddrResolver(CoreConfiguration::Builder* builder) { builder->resolver_registry()->RegisterResolverFactory( std::make_unique()); #endif +#ifdef GRPC_HAVE_VSOCK + builder->resolver_registry()->RegisterResolverFactory( + std::make_unique()); +#endif } } // namespace grpc_core diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 3d73351940e..40c1727b9c9 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -71,6 +71,7 @@ #include "src/core/lib/iomgr/resolved_address.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/iomgr/vsock.h" #include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/security/credentials/credentials.h" @@ -98,6 +99,7 @@ using ::grpc_event_engine::experimental::EventEngine; const char kUnixUriPrefix[] = "unix:"; const char kUnixAbstractUriPrefix[] = "unix-abstract:"; +const char kVSockUriPrefix[] = "vsock:"; class Chttp2ServerListener : public Server::ListenerInterface { public: @@ -941,6 +943,8 @@ grpc_error_handle Chttp2ServerAddPort(Server* server, const char* addr, kUnixAbstractUriPrefix)) { resolved_or = grpc_resolve_unix_abstract_domain_address(parsed_addr_unprefixed); + } else if (absl::ConsumePrefix(&parsed_addr_unprefixed, kVSockUriPrefix)) { + resolved_or = grpc_resolve_vsock_address(parsed_addr_unprefixed); } else { resolved_or = GetDNSResolver()->LookupHostnameBlocking(parsed_addr, "https"); diff --git a/src/core/lib/address_utils/parse_address.cc b/src/core/lib/address_utils/parse_address.cc index c72987c5d29..deb2b079723 100644 --- a/src/core/lib/address_utils/parse_address.cc +++ b/src/core/lib/address_utils/parse_address.cc @@ -20,6 +20,12 @@ #include "src/core/lib/address_utils/parse_address.h" +#include "src/core/lib/iomgr/port.h" // IWYU pragma: keep + +#ifdef GRPC_HAVE_VSOCK +#include +#endif + #include #include #include @@ -38,7 +44,6 @@ #include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/status_helper.h" #include "src/core/lib/iomgr/grpc_if_nametoindex.h" -#include "src/core/lib/iomgr/port.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" @@ -144,6 +149,60 @@ grpc_error_handle UnixAbstractSockaddrPopulate( } // namespace grpc_core #endif // GRPC_HAVE_UNIX_SOCKET +#ifdef GRPC_HAVE_VSOCK + +bool grpc_parse_vsock(const grpc_core::URI& uri, + grpc_resolved_address* resolved_addr) { + if (uri.scheme() != "vsock") { + gpr_log(GPR_ERROR, "Expected 'vsock' scheme, got '%s'", + uri.scheme().c_str()); + return false; + } + grpc_error_handle error = + grpc_core::VSockaddrPopulate(uri.path(), resolved_addr); + if (!error.ok()) { + gpr_log(GPR_ERROR, "%s", grpc_core::StatusToString(error).c_str()); + return false; + } + return true; +} + +namespace grpc_core { + +grpc_error_handle VSockaddrPopulate(absl::string_view path, + grpc_resolved_address* resolved_addr) { + memset(resolved_addr, 0, sizeof(*resolved_addr)); + struct sockaddr_vm* vm = + reinterpret_cast(resolved_addr->addr); + vm->svm_family = AF_VSOCK; + std::string s = std::string(path); + if (sscanf(s.c_str(), "%u:%u", &vm->svm_cid, &vm->svm_port) != 2) { + return GRPC_ERROR_CREATE( + absl::StrCat("Failed to parse vsock cid/port: ", s)); + } + resolved_addr->len = static_cast(sizeof(*vm)); + return absl::OkStatus(); +} + +} // namespace grpc_core + +#else // GRPC_HAVE_VSOCK + +bool grpc_parse_vsock(const grpc_core::URI& /* uri */, + grpc_resolved_address* /* resolved_addr */) { + GPR_UNREACHABLE_CODE(return false); +} + +namespace grpc_core { + +grpc_error_handle VSockaddrPopulate( + absl::string_view /* path */, grpc_resolved_address* /* resolved_addr */) { + GPR_UNREACHABLE_CODE(return absl::InvalidArgumentError("vsock unsupported.")); +} + +} // namespace grpc_core +#endif // GRPC_HAVE_VSOCK + bool grpc_parse_ipv4_hostport(absl::string_view hostport, grpc_resolved_address* addr, bool log_errors) { bool success = false; @@ -299,6 +358,9 @@ bool grpc_parse_uri(const grpc_core::URI& uri, if (uri.scheme() == "unix-abstract") { return grpc_parse_unix_abstract(uri, resolved_addr); } + if (uri.scheme() == "vsock") { + return grpc_parse_vsock(uri, resolved_addr); + } if (uri.scheme() == "ipv4") { return grpc_parse_ipv4(uri, resolved_addr); } diff --git a/src/core/lib/address_utils/parse_address.h b/src/core/lib/address_utils/parse_address.h index 808361536cb..cc08aeda72e 100644 --- a/src/core/lib/address_utils/parse_address.h +++ b/src/core/lib/address_utils/parse_address.h @@ -40,6 +40,11 @@ bool grpc_parse_unix(const grpc_core::URI& uri, bool grpc_parse_unix_abstract(const grpc_core::URI& uri, grpc_resolved_address* resolved_addr); +/// Populate \a resolved_addr from \a uri, whose path is expected to contain a +/// vsock cid:port pair. Returns true upon success. +bool grpc_parse_vsock(const grpc_core::URI& uri, + grpc_resolved_address* resolved_addr); + /// Populate \a resolved_addr from \a uri, whose path is expected to contain an /// IPv4 host:port pair. Returns true upon success. bool grpc_parse_ipv4(const grpc_core::URI& uri, @@ -81,6 +86,9 @@ grpc_error_handle UnixSockaddrPopulate(absl::string_view path, grpc_error_handle UnixAbstractSockaddrPopulate( absl::string_view path, grpc_resolved_address* resolved_addr); +/// Populate \a resolved_addr to be a vsock at \a path +grpc_error_handle VSockaddrPopulate(absl::string_view path, + grpc_resolved_address* resolved_addr); } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_ADDRESS_UTILS_PARSE_ADDRESS_H diff --git a/src/core/lib/address_utils/sockaddr_utils.cc b/src/core/lib/address_utils/sockaddr_utils.cc index fe2f5573598..74bc7d29b1f 100644 --- a/src/core/lib/address_utils/sockaddr_utils.cc +++ b/src/core/lib/address_utils/sockaddr_utils.cc @@ -22,6 +22,9 @@ #include #include +#ifdef GRPC_HAVE_VSOCK +#include +#endif #include #include @@ -77,6 +80,25 @@ static absl::StatusOr grpc_sockaddr_to_uri_unix_if_possible( } #endif +#ifdef GRPC_HAVE_VSOCK +static absl::StatusOr grpc_sockaddr_to_uri_vsock_if_possible( + const grpc_resolved_address* resolved_addr) { + const grpc_sockaddr* addr = + reinterpret_cast(resolved_addr->addr); + if (addr->sa_family != AF_VSOCK) { + return absl::InvalidArgumentError( + absl::StrCat("Socket family is not AF_VSOCK: ", addr->sa_family)); + } + const auto* vsock_addr = reinterpret_cast(addr); + return absl::StrCat("vsock:", vsock_addr->svm_cid, ":", vsock_addr->svm_port); +} +#else +static absl::StatusOr grpc_sockaddr_to_uri_vsock_if_possible( + const grpc_resolved_address* /* addr */) { + return absl::InvalidArgumentError("VSOCK is not supported."); +} +#endif + static const uint8_t kV4MappedPrefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}; @@ -224,6 +246,14 @@ absl::StatusOr grpc_sockaddr_to_string( } #endif +#ifdef GRPC_HAVE_VSOCK + if (addr->sa_family == GRPC_AF_VSOCK) { + const sockaddr_vm* addr_vm = reinterpret_cast(addr); + out = absl::StrCat(addr_vm->svm_cid, ":", addr_vm->svm_port); + return out; + } +#endif + const void* ip = nullptr; int port = 0; uint32_t sin6_scope_id = 0; @@ -269,9 +299,16 @@ absl::StatusOr grpc_sockaddr_to_uri( resolved_addr = &addr_normalized; } const char* scheme = grpc_sockaddr_get_uri_scheme(resolved_addr); - if (scheme == nullptr || strcmp("unix", scheme) == 0) { + if (scheme == nullptr) { + return absl::InvalidArgumentError("Unknown address type"); + } + if (strcmp("unix", scheme) == 0) { return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr); } + if (strcmp("vsock", scheme) == 0) { + return grpc_sockaddr_to_uri_vsock_if_possible(resolved_addr); + } + auto path = grpc_sockaddr_to_string(resolved_addr, false /* normalize */); if (!path.ok()) return path; absl::StatusOr uri = @@ -292,6 +329,10 @@ const char* grpc_sockaddr_get_uri_scheme( return "ipv6"; case GRPC_AF_UNIX: return "unix"; +#ifdef GRPC_HAVE_VSOCK + case GRPC_AF_VSOCK: + return "vsock"; +#endif } return nullptr; } @@ -315,6 +356,10 @@ int grpc_sockaddr_get_port(const grpc_resolved_address* resolved_addr) { #ifdef GRPC_HAVE_UNIX_SOCKET case AF_UNIX: return 1; +#endif +#ifdef GRPC_HAVE_VSOCK + case AF_VSOCK: + return 1; #endif default: gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_get_port", diff --git a/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc b/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc index 8daabdb9a29..8c2745c02b2 100644 --- a/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +++ b/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc @@ -148,7 +148,8 @@ absl::Status PrepareSocket(const PosixTcpOptions& options, } }); if (PosixSocketWrapper::IsSocketReusePortSupported() && - options.allow_reuse_port && socket.addr.address()->sa_family != AF_UNIX) { + options.allow_reuse_port && socket.addr.address()->sa_family != AF_UNIX && + !ResolvedAddressIsVSock(socket.addr)) { GRPC_RETURN_IF_ERROR(socket.sock.SetSocketReusePort(1)); } @@ -164,7 +165,8 @@ absl::Status PrepareSocket(const PosixTcpOptions& options, GRPC_RETURN_IF_ERROR(socket.sock.SetSocketNonBlocking(1)); GRPC_RETURN_IF_ERROR(socket.sock.SetSocketCloexec(1)); - if (socket.addr.address()->sa_family != AF_UNIX) { + if (socket.addr.address()->sa_family != AF_UNIX && + !ResolvedAddressIsVSock(socket.addr)) { GRPC_RETURN_IF_ERROR(socket.sock.SetSocketLowLatency(1)); GRPC_RETURN_IF_ERROR(socket.sock.SetSocketReuseAddr(1)); socket.sock.TrySetSocketTcpUserTimeout(options, false); diff --git a/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc b/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc index 4900a06e9a1..105db6cb279 100644 --- a/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +++ b/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc @@ -128,8 +128,8 @@ absl::Status PrepareTcpClientSocket(PosixSocketWrapper sock, if (options.tcp_receive_buffer_size != options.kReadBufferSizeUnset) { GRPC_RETURN_IF_ERROR(sock.SetSocketRcvBuf(options.tcp_receive_buffer_size)); } - if (reinterpret_cast(addr.address())->sa_family != AF_UNIX) { - // If its not a unix socket address. + if (addr.address()->sa_family != AF_UNIX && !ResolvedAddressIsVSock(addr)) { + // If its not a unix socket or vsock address. GRPC_RETURN_IF_ERROR(sock.SetSocketLowLatency(1)); GRPC_RETURN_IF_ERROR(sock.SetSocketReuseAddr(1)); sock.TrySetSocketTcpUserTimeout(options, true); diff --git a/src/core/lib/event_engine/tcp_socket_utils.cc b/src/core/lib/event_engine/tcp_socket_utils.cc index 202f38db333..9b4602d3e42 100644 --- a/src/core/lib/event_engine/tcp_socket_utils.cc +++ b/src/core/lib/event_engine/tcp_socket_utils.cc @@ -36,6 +36,10 @@ #include #endif +#ifdef GRPC_HAVE_VSOCK +#include +#endif + #include #include #include @@ -70,6 +74,10 @@ absl::StatusOr GetScheme( return "ipv6"; case AF_UNIX: return "unix"; +#ifdef GRPC_HAVE_VSOCK + case AF_VSOCK: + return "vsock"; +#endif default: return absl::InvalidArgumentError( absl::StrFormat("Unknown sockaddr family: %d", @@ -142,6 +150,39 @@ absl::StatusOr ResolvedAddrToUriUnixIfPossible( } #endif +#ifdef GRPC_HAVE_VSOCK +absl::StatusOr ResolvedAddrToVsockPathIfPossible( + const EventEngine::ResolvedAddress* resolved_addr) { + const sockaddr* addr = resolved_addr->address(); + if (addr->sa_family != AF_VSOCK) { + return absl::InvalidArgumentError( + absl::StrCat("Socket family is not AF_VSOCK: ", addr->sa_family)); + } + const sockaddr_vm* vm_addr = reinterpret_cast(addr); + return absl::StrCat(vm_addr->svm_cid, ":", vm_addr->svm_port); +} + +absl::StatusOr ResolvedAddrToUriVsockIfPossible( + const EventEngine::ResolvedAddress* resolved_addr) { + auto path = ResolvedAddrToVsockPathIfPossible(resolved_addr); + absl::StatusOr uri = + grpc_core::URI::Create("vsock", /*authority=*/"", std::move(*path), + /*query_parameter_pairs=*/{}, /*fragment=*/""); + if (!uri.ok()) return uri.status(); + return uri->ToString(); +} +#else +absl::StatusOr ResolvedAddrToVsockPathIfPossible( + const EventEngine::ResolvedAddress* /*resolved_addr*/) { + return absl::InvalidArgumentError("VSOCK is not supported."); +} + +absl::StatusOr ResolvedAddrToUriVsockIfPossible( + const EventEngine::ResolvedAddress* /*resolved_addr*/) { + return absl::InvalidArgumentError("VSOCK is not supported."); +} +#endif + } // namespace bool ResolvedAddressIsV4Mapped( @@ -232,6 +273,10 @@ int ResolvedAddressGetPort(const EventEngine::ResolvedAddress& resolved_addr) { #ifdef GRPC_HAVE_UNIX_SOCKET case AF_UNIX: return 1; +#endif +#ifdef GRPC_HAVE_VSOCK + case AF_VSOCK: + return 1; #endif default: gpr_log(GPR_ERROR, "Unknown socket family %d in ResolvedAddressGetPort", @@ -292,6 +337,15 @@ absl::optional ResolvedAddressIsWildcard( } } +bool ResolvedAddressIsVSock(const EventEngine::ResolvedAddress& resolved_addr) { +#ifdef GRPC_HAVE_VSOCK + return resolved_addr.address()->sa_family == AF_VSOCK; +#else + (void)resolved_addr; + return false; +#endif +} + absl::StatusOr ResolvedAddressToNormalizedString( const EventEngine::ResolvedAddress& resolved_addr) { EventEngine::ResolvedAddress addr_normalized; @@ -312,6 +366,10 @@ absl::StatusOr ResolvedAddressToString( } #endif // GRPC_HAVE_UNIX_SOCKET + if (ResolvedAddressIsVSock(resolved_addr)) { + return ResolvedAddrToVsockPathIfPossible(&resolved_addr); + } + const void* ip = nullptr; int port = 0; uint32_t sin6_scope_id = 0; @@ -362,6 +420,9 @@ absl::StatusOr ResolvedAddressToURI( if (*scheme == "unix") { return ResolvedAddrToUriUnixIfPossible(&addr); } + if (*scheme == "vsock") { + return ResolvedAddrToUriVsockIfPossible(&addr); + } auto path = ResolvedAddressToString(addr); GRPC_RETURN_IF_ERROR(path.status()); absl::StatusOr uri = diff --git a/src/core/lib/event_engine/tcp_socket_utils.h b/src/core/lib/event_engine/tcp_socket_utils.h index ac72d3ebc06..632b874bcbf 100644 --- a/src/core/lib/event_engine/tcp_socket_utils.h +++ b/src/core/lib/event_engine/tcp_socket_utils.h @@ -61,6 +61,9 @@ void ResolvedAddressSetPort(EventEngine::ResolvedAddress& resolved_addr, absl::optional ResolvedAddressIsWildcard( const EventEngine::ResolvedAddress& addr); +// Returns true if resolved_addr is an VSOCK address. Otherwise returns false. +bool ResolvedAddressIsVSock(const EventEngine::ResolvedAddress& resolved_addr); + // Converts a EventEngine::ResolvedAddress into a newly-allocated // human-readable string. // Currently, only the AF_INET, AF_INET6, and AF_UNIX families are diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 846c3764de4..732c00e1323 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -37,6 +37,11 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 +#if defined(LINUX_VERSION_CODE) && defined(__GLIBC_PREREQ) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) && __GLIBC_PREREQ(2, 18) +#define GRPC_HAVE_VSOCK 1 +#endif +#endif #define GRPC_LINUX_EVENTFD 1 #define GRPC_POSIX_SOCKET 1 #define GRPC_POSIX_SOCKETUTILS 1 @@ -56,6 +61,11 @@ #define GRPC_LINUX_ERRQUEUE 1 #endif // LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) #endif // LINUX_VERSION_CODE +#if defined(LINUX_VERSION_CODE) && defined(__GLIBC_PREREQ) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) && __GLIBC_PREREQ(2, 18) +#define GRPC_HAVE_VSOCK 1 +#endif +#endif #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1 #define GRPC_POSIX_FORK 1 #define GRPC_POSIX_HOST_NAME_MAX 1 diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h index f46072f8daa..7f89cea6950 100644 --- a/src/core/lib/iomgr/sockaddr_posix.h +++ b/src/core/lib/iomgr/sockaddr_posix.h @@ -33,6 +33,10 @@ #include #include +#ifdef GRPC_HAVE_VSOCK +#include +#endif + typedef struct sockaddr grpc_sockaddr; typedef struct sockaddr_in grpc_sockaddr_in; typedef struct in_addr grpc_in_addr; @@ -47,6 +51,9 @@ typedef struct in6_addr grpc_in6_addr; #define GRPC_AF_UNSPEC AF_UNSPEC #define GRPC_AF_UNIX AF_UNIX +#ifdef GRPC_HAVE_VSOCK +#define GRPC_AF_VSOCK AF_VSOCK +#endif #define GRPC_AF_INET AF_INET #define GRPC_AF_INET6 AF_INET6 diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 68918d3ce1d..57aa21b9030 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -51,6 +51,7 @@ #include "src/core/lib/iomgr/tcp_posix.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/iomgr/vsock.h" #include "src/core/lib/slice/slice_internal.h" extern grpc_core::TraceFlag grpc_tcp_trace; @@ -111,7 +112,7 @@ static grpc_error_handle prepare_socket( err = grpc_set_socket_rcvbuf(fd, options.tcp_receive_buffer_size); if (!err.ok()) goto error; } - if (!grpc_is_unix_socket(addr)) { + if (!grpc_is_unix_socket(addr) && !grpc_is_vsock(addr)) { err = grpc_set_socket_low_latency(fd, 1); if (!err.ok()) goto error; err = grpc_set_socket_reuse_addr(fd, 1); diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc index 3bb93918be6..3c292ac28d0 100644 --- a/src/core/lib/iomgr/tcp_server_posix.cc +++ b/src/core/lib/iomgr/tcp_server_posix.cc @@ -74,6 +74,7 @@ #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/iomgr/tcp_server_utils_posix.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/iomgr/vsock.h" #include "src/core/lib/resource_quota/api.h" #include "src/core/lib/transport/error_utils.h" @@ -755,7 +756,7 @@ static void tcp_server_start(grpc_tcp_server* s, sp = s->head; while (sp != nullptr) { if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr) && - pollsets->size() > 1) { + !grpc_is_vsock(&sp->addr) && pollsets->size() > 1) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "clone_port", clone_port(sp, (unsigned)(pollsets->size() - 1)))); for (i = 0; i < pollsets->size(); i++) { diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc index 574fd02d0de..80e6eca361a 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -42,6 +42,7 @@ #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/tcp_server_utils_posix.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/iomgr/vsock.h" #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100 @@ -190,7 +191,7 @@ grpc_error_handle grpc_tcp_server_prepare_socket( GPR_ASSERT(fd >= 0); - if (so_reuseport && !grpc_is_unix_socket(addr)) { + if (so_reuseport && !grpc_is_unix_socket(addr) && !grpc_is_vsock(addr)) { err = grpc_set_socket_reuse_port(fd, 1); if (!err.ok()) goto error; } @@ -206,7 +207,7 @@ grpc_error_handle grpc_tcp_server_prepare_socket( if (!err.ok()) goto error; err = grpc_set_socket_cloexec(fd, 1); if (!err.ok()) goto error; - if (!grpc_is_unix_socket(addr)) { + if (!grpc_is_unix_socket(addr) && !grpc_is_vsock(addr)) { err = grpc_set_socket_low_latency(fd, 1); if (!err.ok()) goto error; err = grpc_set_socket_reuse_addr(fd, 1); diff --git a/src/core/lib/iomgr/vsock.cc b/src/core/lib/iomgr/vsock.cc new file mode 100644 index 00000000000..c938c68b9b6 --- /dev/null +++ b/src/core/lib/iomgr/vsock.cc @@ -0,0 +1,59 @@ +// +// +// Copyright 2023 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 "src/core/lib/iomgr/vsock.h" + +#ifdef GRPC_HAVE_VSOCK + +#include +#include +#include + +#include "absl/strings/str_cat.h" + +#include +#include + +#include "src/core/lib/address_utils/parse_address.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/crash.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/transport/error_utils.h" + +absl::StatusOr> grpc_resolve_vsock_address( + absl::string_view name) { + grpc_resolved_address addr; + grpc_error_handle error = grpc_core::VSockaddrPopulate(name, &addr); + GRPC_RETURN_IF_ERROR(error); + return std::vector({addr}); +} + +int grpc_is_vsock(const grpc_resolved_address* resolved_addr) { + const grpc_sockaddr* addr = + reinterpret_cast(resolved_addr->addr); + return addr->sa_family == AF_VSOCK; +} +#else +absl::StatusOr> grpc_resolve_vsock_address( + absl::string_view /*name*/) { + return absl::InvalidArgumentError("VSOCK is not supported."); +} + +int grpc_is_vsock(const grpc_resolved_address* /*resolved_addr*/) { return 0; } +#endif diff --git a/src/core/lib/iomgr/vsock.h b/src/core/lib/iomgr/vsock.h new file mode 100644 index 00000000000..8c45b5cbaff --- /dev/null +++ b/src/core/lib/iomgr/vsock.h @@ -0,0 +1,38 @@ +// +// +// Copyright 2023 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// + +#ifndef GRPC_SRC_CORE_LIB_IOMGR_VSOCK_H +#define GRPC_SRC_CORE_LIB_IOMGR_VSOCK_H + +#include + +#include + +#include "absl/strings/string_view.h" + +#include + +#include "src/core/lib/iomgr/port.h" +#include "src/core/lib/iomgr/resolve_address.h" + +absl::StatusOr> grpc_resolve_vsock_address( + absl::string_view name); + +int grpc_is_vsock(const grpc_resolved_address* resolved_addr); + +#endif /* GRPC_SRC_CORE_LIB_IOMGR_VSOCK_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c61a17daaa4..bcc041ac0b5 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -661,6 +661,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/timer_manager.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', + 'src/core/lib/iomgr/vsock.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', diff --git a/test/core/address_utils/parse_address_test.cc b/test/core/address_utils/parse_address_test.cc index 17c2ed0fa17..07b29c2678a 100644 --- a/test/core/address_utils/parse_address_test.cc +++ b/test/core/address_utils/parse_address_test.cc @@ -21,6 +21,10 @@ #include #endif +#ifdef GRPC_HAVE_VSOCK +#include +#endif + #include #include "absl/status/status.h" @@ -80,6 +84,32 @@ static void test_grpc_parse_unix_abstract(const char* uri_text, #endif // GRPC_HAVE_UNIX_SOCKET +#ifdef GRPC_HAVE_VSOCK + +static void test_grpc_parse_vsock(const char* uri_text, uint32_t cid, + uint32_t port) { + grpc_core::ExecCtx exec_ctx; + absl::StatusOr uri = grpc_core::URI::Parse(uri_text); + if (!uri.ok()) { + gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + ASSERT_TRUE(uri.ok()); + } + grpc_resolved_address addr; + + ASSERT_TRUE(grpc_parse_uri(*uri, &addr)); + struct sockaddr_vm* addr_vm = + reinterpret_cast(addr.addr); + ASSERT_EQ(AF_VSOCK, addr_vm->svm_family); + ASSERT_EQ(grpc_ntohl(addr_vm->svm_cid), cid); + ASSERT_EQ(addr_vm->svm_port, port); +} + +#else // GRPC_HAVE_VSOCK + +static void test_grpc_parse_vsock(const char* /* uri_text */, ...) {} + +#endif // GRPC_HAVE_VSOCK + static void test_grpc_parse_ipv4(const char* uri_text, const char* host, unsigned short port) { grpc_core::ExecCtx exec_ctx; @@ -137,6 +167,7 @@ TEST(ParseAddressTest, MainTest) { test_grpc_parse_unix("unix:/path/name", "/path/name"); test_grpc_parse_unix_abstract("unix-abstract:foobar", "foobar"); + test_grpc_parse_vsock("vsock:-1:12345", -1, 12345); test_grpc_parse_ipv4("ipv4:192.0.2.1:12345", "192.0.2.1", 12345); test_grpc_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0); test_grpc_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2); diff --git a/test/core/address_utils/sockaddr_utils_test.cc b/test/core/address_utils/sockaddr_utils_test.cc index 015bf51640f..1b4345c4b8a 100644 --- a/test/core/address_utils/sockaddr_utils_test.cc +++ b/test/core/address_utils/sockaddr_utils_test.cc @@ -262,6 +262,14 @@ TEST(SockAddrUtilsTest, SockAddrToString) { EXPECT_EQ(grpc_sockaddr_to_string(&inputun, true).status(), absl::InvalidArgumentError("empty UDS abstract path")); #endif + +#ifdef GRPC_HAVE_VSOCK + grpc_resolved_address inputvm; + ASSERT_EQ(grpc_core::VSockaddrPopulate("-1:12345", &inputvm), + absl::OkStatus()); + EXPECT_EQ(grpc_sockaddr_to_string(&inputvm, true).value(), + absl::StrCat((uint32_t)-1, ":12345")); +#endif } #ifdef GRPC_HAVE_UNIX_SOCKET @@ -285,6 +293,18 @@ TEST(SockAddrUtilsTest, UnixSockAddrToUri) { #endif // GRPC_HAVE_UNIX_SOCKET +#ifdef GRPC_HAVE_VSOCK + +TEST(SockAddrUtilsTest, VSockAddrToUri) { + grpc_resolved_address addr; + ASSERT_TRUE(absl::OkStatus() == + grpc_core::VSockaddrPopulate("-1:12345", &addr)); + EXPECT_EQ(grpc_sockaddr_to_uri(&addr).value(), + absl::StrCat("vsock:", (uint32_t)-1, ":12345")); +} + +#endif // GRPC_HAVE_VSOCK + TEST(SockAddrUtilsTest, SockAddrSetGetPort) { grpc_resolved_address input4 = MakeAddr4(kIPv4, sizeof(kIPv4)); ASSERT_EQ(grpc_sockaddr_get_port(&input4), 12345); diff --git a/test/core/event_engine/tcp_socket_utils_test.cc b/test/core/event_engine/tcp_socket_utils_test.cc index 07f65d879b7..d3b114d8014 100644 --- a/test/core/event_engine/tcp_socket_utils_test.cc +++ b/test/core/event_engine/tcp_socket_utils_test.cc @@ -16,7 +16,15 @@ #include "src/core/lib/event_engine/tcp_socket_utils.h" #include + +#include "src/core/lib/iomgr/port.h" // IWYU pragma: keep + +#ifdef GRPC_HAVE_VSOCK +#include +#endif + #include +#include #include #include "absl/strings/str_cat.h" @@ -26,8 +34,6 @@ #include -#include "src/core/lib/iomgr/port.h" - #ifdef GRPC_HAVE_UNIX_SOCKET #include #endif @@ -134,6 +140,25 @@ absl::StatusOr UnixAbstractSockaddrPopulate( } #endif // GRPC_HAVE_UNIX_SOCKET +#ifdef GRPC_HAVE_VSOCK +absl::StatusOr VSockaddrPopulate( + absl::string_view path) { + EventEngine::ResolvedAddress resolved_addr; + memset(const_cast(resolved_addr.address()), 0, + resolved_addr.size()); + struct sockaddr_vm* vm = reinterpret_cast( + const_cast(resolved_addr.address())); + vm->svm_family = AF_VSOCK; + std::string s = std::string(path); + if (sscanf(s.c_str(), "%u:%u", &vm->svm_cid, &vm->svm_port) != 2) { + return absl::InternalError( + absl::StrCat("Failed to parse vsock cid/port: ", s)); + } + return EventEngine::ResolvedAddress(reinterpret_cast(vm), + static_cast(sizeof(*vm))); +} +#endif // GRPC_HAVE_VSOCK + } // namespace TEST(TcpSocketUtilsTest, ResolvedAddressIsV4MappedTest) { @@ -255,6 +280,12 @@ TEST(TcpSocketUtilsTest, ResolvedAddressToNormalizedStringTest) { EXPECT_EQ(ResolvedAddressToNormalizedString(inputun3).value(), absl::StrCat(std::string(1, '\0'), max_abspath)); #endif + +#ifdef GRPC_HAVE_VSOCK + EventEngine::ResolvedAddress inputvm = *VSockaddrPopulate("-1:12345"); + EXPECT_EQ(ResolvedAddressToNormalizedString(inputvm).value(), + absl::StrCat((uint32_t)-1, ":12345")); +#endif } TEST(TcpSocketUtilsTest, SockAddrPortTest) { diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 58e741eb377..bcfdeaa3c9d 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -2395,6 +2395,8 @@ src/core/lib/iomgr/timer_manager.h \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix.h \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ +src/core/lib/iomgr/vsock.cc \ +src/core/lib/iomgr/vsock.h \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 9f6c8c8e61f..82749c02861 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -2176,6 +2176,8 @@ src/core/lib/iomgr/timer_manager.h \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix.h \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ +src/core/lib/iomgr/vsock.cc \ +src/core/lib/iomgr/vsock.h \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \