aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorHao Chen <chenhaosjtuacm@google.com>2020-01-10 13:52:35 -0800
committerHao Chen <chenhaosjtuacm@google.com>2020-01-10 13:52:35 -0800
commita0d43cf1a94bc5443ee8ee2499490f6af4da6272 (patch)
tree110b029d64273a9ffb3cb9af91481516cd49183b /src/core
parent987bce6ff47fcdb93db330fccb1e3f4471fbd0ec (diff)
downloadgrpc-grpc-a0d43cf1a94bc5443ee8ee2499490f6af4da6272.tar.gz
Vsock support for GRPC
This is originally from Chrome OS team. Modified to make it builds on non-Linux platforms Test: done on Cufflefish VM with ag/9869094 Bug: b/145631107 Change-Id: I41a5f8af68488cc6c9b9629d9c99b54bc085764a
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ext/filters/client_channel/parse_address.cc32
-rw-r--r--src/core/ext/filters/client_channel/parse_address.h5
-rw-r--r--src/core/lib/iomgr/port.h10
-rw-r--r--src/core/lib/iomgr/resolve_address_posix.cc5
-rw-r--r--src/core/lib/iomgr/sockaddr_posix.h7
-rw-r--r--src/core/lib/iomgr/sockaddr_utils.cc29
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix_common.cc5
-rw-r--r--src/core/lib/iomgr/udp_server.cc2
-rw-r--r--src/core/lib/iomgr/unix_sockets_posix.cc57
-rw-r--r--src/core/lib/iomgr/unix_sockets_posix.h8
12 files changed, 156 insertions, 8 deletions
diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc
index 707beb8876..c737f53d01 100644
--- a/src/core/ext/filters/client_channel/parse_address.cc
+++ b/src/core/ext/filters/client_channel/parse_address.cc
@@ -26,6 +26,10 @@
#include <string.h>
#ifdef GRPC_HAVE_UNIX_SOCKET
#include <sys/un.h>
+#ifdef GRPC_HAVE_LINUX_VSOCK
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
+#endif /* GRPC_HAVE_LINUX_VSOCK */
#endif
#include <grpc/support/alloc.h>
@@ -63,6 +67,32 @@ bool grpc_parse_unix(const grpc_uri* uri,
#endif /* GRPC_HAVE_UNIX_SOCKET */
+#if defined(GRPC_HAVE_UNIX_SOCKET) && defined(GRPC_HAVE_LINUX_VSOCK)
+
+bool grpc_parse_vsock(const grpc_uri* uri,
+ grpc_resolved_address* resolved_addr) {
+ memset(resolved_addr, 0, sizeof(*resolved_addr));
+ struct sockaddr_vm *vm =
+ reinterpret_cast<struct sockaddr_vm *>(resolved_addr->addr);
+
+ if (sscanf(uri->path, "%u:%u", &vm->svm_cid, &vm->svm_port) != 2) {
+ return false;
+ }
+ vm->svm_family = AF_VSOCK;
+
+ resolved_addr->len = static_cast<socklen_t>(sizeof(*vm));
+ return true;
+}
+
+#else /* defined(GRPC_HAVE_UNIX_SOCKET) && defined(GRPC_HAVE_LINUX_VSOCK) */
+
+bool grpc_parse_vsock(const grpc_uri* uri,
+ grpc_resolved_address* resolved_addr) {
+ abort();
+}
+
+#endif /* defined(GRPC_HAVE_UNIX_SOCKET) && defined(GRPC_HAVE_LINUX_VSOCK) */
+
bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
bool log_errors) {
bool success = false;
@@ -200,6 +230,8 @@ bool grpc_parse_uri(const grpc_uri* uri, grpc_resolved_address* resolved_addr) {
return grpc_parse_ipv4(uri, resolved_addr);
} else if (strcmp("ipv6", uri->scheme) == 0) {
return grpc_parse_ipv6(uri, resolved_addr);
+ } else if (strcmp("vsock", uri->scheme) == 0) {
+ return grpc_parse_vsock(uri, resolved_addr);
}
gpr_log(GPR_ERROR, "Can't parse scheme '%s'", uri->scheme);
return false;
diff --git a/src/core/ext/filters/client_channel/parse_address.h b/src/core/ext/filters/client_channel/parse_address.h
index c2af0e6c49..2e7356f0ce 100644
--- a/src/core/ext/filters/client_channel/parse_address.h
+++ b/src/core/ext/filters/client_channel/parse_address.h
@@ -30,6 +30,11 @@
* unix socket path. Returns true upon success. */
bool grpc_parse_unix(const grpc_uri* uri, grpc_resolved_address* resolved_addr);
+/** Populate \a resolved_addr from \a uri, whose path is expected to contain a
+ * vsock specification. Returns true upon success. */
+bool grpc_parse_vsock(const grpc_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_uri* uri, grpc_resolved_address* resolved_addr);
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index 3d459059d7..fde2627e37 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -49,6 +49,11 @@
#define GRPC_HAVE_IP_PKTINFO 1
#define GRPC_HAVE_MSG_NOSIGNAL 1
#define GRPC_HAVE_UNIX_SOCKET 1
+#ifdef LINUX_VERSION_CODE
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#define GRPC_HAVE_LINUX_VSOCK
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) */
+#endif /* LINUX_VERSION_CODE */
#define GRPC_LINUX_EVENTFD 1
#define GRPC_POSIX_SOCKET 1
#define GRPC_POSIX_SOCKETUTILS 1
@@ -65,6 +70,11 @@
#define GRPC_LINUX_ERRQUEUE 1
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
+#ifdef LINUX_VERSION_CODE
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+#define GRPC_HAVE_LINUX_VSOCK
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) */
+#endif /* LINUX_VERSION_CODE */
#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/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc
index c285d7eca6..cad143d823 100644
--- a/src/core/lib/iomgr/resolve_address_posix.cc
+++ b/src/core/lib/iomgr/resolve_address_posix.cc
@@ -59,6 +59,11 @@ static grpc_error* posix_blocking_resolve_address(
return grpc_resolve_unix_domain_address(name + 5, addresses);
}
+ if (name[0] == 'v' && name[1] == 's' && name[2] == 'o' && name[3] == 'c' &&
+ name[4] == 'k' && name[5] == ':' && name[6] != 0) {
+ return grpc_resolve_vsock_address(name + 6, addresses);
+ }
+
/* parse name, splitting it into host and port parts */
gpr_split_host_port(name, &host, &port);
if (host == nullptr) {
diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h
index 3cedd9082d..e32fc9a219 100644
--- a/src/core/lib/iomgr/sockaddr_posix.h
+++ b/src/core/lib/iomgr/sockaddr_posix.h
@@ -48,8 +48,13 @@ typedef struct in6_addr grpc_in6_addr;
#define GRPC_AF_INET AF_INET
#define GRPC_AF_INET6 AF_INET6
+#ifdef GRPC_HAVE_LINUX_VSOCK
+#include <linux/vm_sockets.h> // Needs to come after sys/socket.h
+#define GRPC_AF_VSOCK AF_VSOCK
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+
#define GRPC_AI_PASSIVE AI_PASSIVE
-#endif
+#endif /* GRPC_POSIX_SOCKET_SOCKADDR */
#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H */
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index 1b66dceb13..833b5660fd 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -224,6 +224,8 @@ char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) {
const char* scheme = grpc_sockaddr_get_uri_scheme(resolved_addr);
if (scheme == nullptr || strcmp("unix", scheme) == 0) {
return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr);
+ } else if (strcmp("vsock", scheme) == 0) {
+ return grpc_sockaddr_to_uri_vsock_if_possible(resolved_addr);
}
char* path = nullptr;
char* uri_str = nullptr;
@@ -247,6 +249,10 @@ const char* grpc_sockaddr_get_uri_scheme(
return "ipv6";
case GRPC_AF_UNIX:
return "unix";
+#ifdef GRPC_AF_VSOCK
+ case GRPC_AF_VSOCK:
+ return "vsock";
+#endif /* GRPC_AF_VSOCK */
}
return nullptr;
}
@@ -265,6 +271,15 @@ int grpc_sockaddr_get_port(const grpc_resolved_address* resolved_addr) {
return grpc_ntohs(((grpc_sockaddr_in*)addr)->sin_port);
case GRPC_AF_INET6:
return grpc_ntohs(((grpc_sockaddr_in6*)addr)->sin6_port);
+#ifdef GRPC_AF_VSOCK
+ case GRPC_AF_VSOCK:
+#ifdef GRPC_HAVE_LINUX_VSOCK
+ return static_cast<int>(reinterpret_cast<const struct sockaddr_vm *>(addr)->svm_port);
+#else /* GRPC_HAVE_LINUX_VSOCK */
+ gpr_log(GPR_ERROR, "Unknown vsock implementation");
+ return 0;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+#endif /* GRPC_AF_VSOCK */
default:
if (grpc_is_unix_socket(resolved_addr)) {
return 1;
@@ -277,8 +292,8 @@ int grpc_sockaddr_get_port(const grpc_resolved_address* resolved_addr) {
int grpc_sockaddr_set_port(const grpc_resolved_address* resolved_addr,
int port) {
- const grpc_sockaddr* addr =
- reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
+ grpc_sockaddr* addr =
+ const_cast<grpc_sockaddr*>(reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr));
switch (addr->sa_family) {
case GRPC_AF_INET:
GPR_ASSERT(port >= 0 && port < 65536);
@@ -290,6 +305,16 @@ int grpc_sockaddr_set_port(const grpc_resolved_address* resolved_addr,
((grpc_sockaddr_in6*)addr)->sin6_port =
grpc_htons(static_cast<uint16_t>(port));
return 1;
+#ifdef GRPC_AF_VSOCK
+ case GRPC_AF_VSOCK:
+#ifdef GRPC_HAVE_LINUX_VSOCK
+ reinterpret_cast<struct sockaddr_vm *>(addr)->svm_port = static_cast<unsigned int>(port);
+ return 1;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+ gpr_log(GPR_ERROR, "Unknown vsock implementation");
+ return 0;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+#endif /* GRPC_AF_VSOCK */
default:
gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_set_port",
addr->sa_family);
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 8553ed0db4..207f748f3b 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -73,7 +73,7 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd,
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_cloexec(fd, 1);
if (err != GRPC_ERROR_NONE) 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 != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_tcp_user_timeout(fd, channel_args,
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index 824db07fbf..34a54b1fab 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -487,7 +487,7 @@ static void tcp_server_start(grpc_tcp_server* s, grpc_pollset** pollsets,
sp = s->head;
while (sp != nullptr) {
if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr) &&
- pollset_count > 1) {
+ !grpc_is_vsock(&sp->addr) && pollset_count > 1) {
GPR_ASSERT(GRPC_LOG_IF_ERROR(
"clone_port", clone_port(sp, (unsigned)(pollset_count - 1))));
for (i = 0; i < pollset_count; 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 8d8d3f4273..4398baead2 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
@@ -152,7 +152,8 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
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 != GRPC_ERROR_NONE) goto error;
}
@@ -161,7 +162,7 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd,
if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_cloexec(fd, 1);
if (err != GRPC_ERROR_NONE) 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 != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_reuse_addr(fd, 1);
diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc
index 3dd7cab855..49a5b6cf22 100644
--- a/src/core/lib/iomgr/udp_server.cc
+++ b/src/core/lib/iomgr/udp_server.cc
@@ -404,7 +404,7 @@ static int prepare_socket(grpc_socket_factory* socket_factory, int fd,
}
}
- if (so_reuseport && !grpc_is_unix_socket(addr) &&
+ if (so_reuseport && !grpc_is_unix_socket(addr) && !grpc_is_vsock(addr) &&
grpc_set_socket_reuse_port(fd, 1) != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "Failed to set SO_REUSEPORT for fd %d", fd);
goto error;
diff --git a/src/core/lib/iomgr/unix_sockets_posix.cc b/src/core/lib/iomgr/unix_sockets_posix.cc
index 22fcaf57fc..0cbe3e9f4e 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.cc
+++ b/src/core/lib/iomgr/unix_sockets_posix.cc
@@ -23,6 +23,7 @@
#include "src/core/lib/iomgr/sockaddr.h"
+#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -66,12 +67,49 @@ grpc_error* grpc_resolve_unix_domain_address(const char* name,
return GRPC_ERROR_NONE;
}
+grpc_error* grpc_resolve_vsock_address(const char* name,
+ grpc_resolved_addresses** addrs) {
+#ifdef GRPC_HAVE_LINUX_VSOCK
+ struct sockaddr_vm *vm;
+ unsigned int cid;
+ unsigned int port;
+
+ if (sscanf(name, "%u:%u", &cid, &port) != 2) {
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed to parse cid:port pair");
+ }
+
+ *addrs = static_cast<grpc_resolved_addresses*>(
+ gpr_malloc(sizeof(grpc_resolved_addresses)));
+ (*addrs)->naddrs = 1;
+ (*addrs)->addrs = static_cast<grpc_resolved_address*>(
+ gpr_zalloc(sizeof(grpc_resolved_address)));
+ vm = (struct sockaddr_vm *)(*addrs)->addrs->addr;
+ vm->svm_family = AF_VSOCK;
+ vm->svm_cid = cid;
+ vm->svm_port = port;
+ (*addrs)->addrs->len = sizeof(struct sockaddr_vm);
+ return GRPC_ERROR_NONE;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("vsock not supported");
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+}
+
int grpc_is_unix_socket(const grpc_resolved_address* resolved_addr) {
const grpc_sockaddr* addr =
reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
return addr->sa_family == AF_UNIX;
}
+int grpc_is_vsock(const grpc_resolved_address* resolved_addr) {
+#ifdef GRPC_HAVE_LINUX_VSOCK
+ const grpc_sockaddr* addr =
+ reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
+ return addr->sa_family == AF_VSOCK;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+ return 0;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+}
+
void grpc_unlink_if_unix_domain_socket(
const grpc_resolved_address* resolved_addr) {
const grpc_sockaddr* addr =
@@ -101,4 +139,23 @@ char* grpc_sockaddr_to_uri_unix_if_possible(
return result;
}
+char* grpc_sockaddr_to_uri_vsock_if_possible(
+ const grpc_resolved_address* resolved_addr) {
+#ifdef GRPC_HAVE_LINUX_VSOCK
+ const grpc_sockaddr* addr =
+ reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
+
+ if (addr->sa_family != AF_VSOCK) {
+ return nullptr;
+ }
+
+ char *result;
+ struct sockaddr_vm *vm = (struct sockaddr_vm*)addr;
+ gpr_asprintf(&result, "vsock:%u:%u", vm->svm_cid, vm->svm_port);
+ return result;
+#else /* GRPC_HAVE_LINUX_VSOCK */
+ return nullptr;
+#endif /* GRPC_HAVE_LINUX_VSOCK */
+}
+
#endif
diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h
index 917d0327a9..ed1f03a328 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.h
+++ b/src/core/lib/iomgr/unix_sockets_posix.h
@@ -32,12 +32,20 @@ void grpc_create_socketpair_if_unix(int sv[2]);
grpc_error* grpc_resolve_unix_domain_address(
const char* name, grpc_resolved_addresses** addresses);
+grpc_error* grpc_resolve_vsock_address(
+ const char* name, grpc_resolved_addresses** addrs);
+
int grpc_is_unix_socket(const grpc_resolved_address* resolved_addr);
+int grpc_is_vsock(const grpc_resolved_address* resolved_addr);
+
void grpc_unlink_if_unix_domain_socket(
const grpc_resolved_address* resolved_addr);
char* grpc_sockaddr_to_uri_unix_if_possible(
const grpc_resolved_address* resolved_addr);
+char* grpc_sockaddr_to_uri_vsock_if_possible(
+ const grpc_resolved_address* resolved_addr);
+
#endif /* GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H */