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 \