blob: 91c901d89ca16255b23d913888a8044b247ee8d9 [file] [log] [blame]
From 716cb35ab711efbd99a65c599b50f044e4912bd0 Mon Sep 17 00:00:00 2001
From: Chirantan Ekbote <chirantan@google.com>
Date: Mon, 10 Jul 2017 13:22:59 -0700
Subject: [PATCH 4/5] grpc-1.3.0: Support vsock
Add support for vsock as a transport for client <-> server communication. Has
not been sent upstream because upstream has not indicated whether they are
interested in adding support for this transport. Also the patch in its current
form is probably not upstream-able because it assumes that vsock is always
available, which is definitely not the case for all the platforms that upstream
supports.
---
.../ext/filters/client_channel/parse_address.c | 15 +++++++++++
.../ext/filters/client_channel/parse_address.h | 4 +++
src/core/ext/filters/client_channel/subchannel.c | 2 ++
src/core/lib/iomgr/resolve_address_posix.c | 5 ++++
src/core/lib/iomgr/sockaddr_posix.h | 2 ++
src/core/lib/iomgr/sockaddr_utils.c | 9 ++++++-
src/core/lib/iomgr/unix_sockets_posix.c | 31 +++++++++++++++++++++-
src/core/lib/iomgr/unix_sockets_posix.h | 3 +++
8 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/src/core/ext/filters/client_channel/parse_address.c b/src/core/ext/filters/client_channel/parse_address.c
index 0c97062075..2932c56490 100644
--- a/src/core/ext/filters/client_channel/parse_address.c
+++ b/src/core/ext/filters/client_channel/parse_address.c
@@ -38,6 +38,8 @@
#include <string.h>
#ifdef GRPC_HAVE_UNIX_SOCKET
#include <sys/un.h>
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
#endif
#include <grpc/support/alloc.h>
@@ -59,6 +61,19 @@ int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
return 1;
}
+int parse_vsock(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
+ memset(resolved_addr, 0, sizeof(grpc_resolved_address));
+ struct sockaddr_vm *vm = (struct sockaddr_vm *)resolved_addr->addr;
+
+ if (sscanf(uri->path, "%u:%u", &vm->svm_cid, &vm->svm_port) != 2) {
+ return 0;
+ }
+ vm->svm_family = AF_VSOCK;
+
+ resolved_addr->len = sizeof(struct sockaddr_vm);
+ return 1;
+}
+
#else /* GRPC_HAVE_UNIX_SOCKET */
int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr) { abort(); }
diff --git a/src/core/ext/filters/client_channel/parse_address.h b/src/core/ext/filters/client_channel/parse_address.h
index c8d77baa00..ad7182a90b 100644
--- a/src/core/ext/filters/client_channel/parse_address.h
+++ b/src/core/ext/filters/client_channel/parse_address.h
@@ -43,6 +43,10 @@
* unix socket path. Returns true upon success. */
int parse_unix(grpc_uri *uri, grpc_resolved_address *resolved_addr);
+/** Populate \a addr and \a len from \a uri, whose path is expected to contain a
+ * vsock specification. Returns true upon success. */
+int parse_vsock(grpc_uri *uri, grpc_resolved_address *resolved_addr);
+
/** Populate /a addr and \a len from \a uri, whose path is expected to contain a
* host:port pair. Returns true upon success. */
int parse_ipv4(grpc_uri *uri, grpc_resolved_address *resolved_addr);
diff --git a/src/core/ext/filters/client_channel/subchannel.c b/src/core/ext/filters/client_channel/subchannel.c
index 9a7a7a0ee5..f768b1e55a 100644
--- a/src/core/ext/filters/client_channel/subchannel.c
+++ b/src/core/ext/filters/client_channel/subchannel.c
@@ -801,6 +801,8 @@ static void grpc_uri_to_sockaddr(grpc_exec_ctx *exec_ctx, const char *uri_str,
GPR_ASSERT(parse_ipv4(uri, addr));
} else if (strcmp(uri->scheme, "ipv6") == 0) {
GPR_ASSERT(parse_ipv6(uri, addr));
+ } else if (strcmp(uri->scheme, "vsock") == 0) {
+ GPR_ASSERT(parse_vsock(uri, addr));
} else {
GPR_ASSERT(parse_unix(uri, addr));
}
diff --git a/src/core/lib/iomgr/resolve_address_posix.c b/src/core/lib/iomgr/resolve_address_posix.c
index d0ede0f2d5..bd45826f0f 100644
--- a/src/core/lib/iomgr/resolve_address_posix.c
+++ b/src/core/lib/iomgr/resolve_address_posix.c
@@ -70,6 +70,11 @@ static grpc_error *blocking_resolve_address_impl(
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 == NULL) {
diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h
index b150de42f7..15d851dd45 100644
--- a/src/core/lib/iomgr/sockaddr_posix.h
+++ b/src/core/lib/iomgr/sockaddr_posix.h
@@ -41,4 +41,6 @@
#include <sys/types.h>
#include <unistd.h>
+#include <linux/vm_sockets.h> // Needs to come after sys/socket.h
+
#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H */
diff --git a/src/core/lib/iomgr/sockaddr_utils.c b/src/core/lib/iomgr/sockaddr_utils.c
index a6a4cac3e2..ab5fcb0639 100644
--- a/src/core/lib/iomgr/sockaddr_utils.c
+++ b/src/core/lib/iomgr/sockaddr_utils.c
@@ -207,7 +207,7 @@ char *grpc_sockaddr_to_uri(const grpc_resolved_address *resolved_addr) {
resolved_addr = &addr_normalized;
}
const char *scheme = grpc_sockaddr_get_uri_scheme(resolved_addr);
- if (scheme == NULL || strcmp("unix", scheme) == 0) {
+ if (scheme == NULL || strcmp("unix", scheme) == 0 || strcmp("vsock", scheme) == 0) {
return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr);
}
char *path = NULL;
@@ -231,6 +231,8 @@ const char *grpc_sockaddr_get_uri_scheme(
return "ipv6";
case AF_UNIX:
return "unix";
+ case AF_VSOCK:
+ return "vsock";
}
return NULL;
}
@@ -242,6 +244,8 @@ int grpc_sockaddr_get_port(const grpc_resolved_address *resolved_addr) {
return ntohs(((struct sockaddr_in *)addr)->sin_port);
case AF_INET6:
return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
+ case AF_VSOCK:
+ return (int)((struct sockaddr_vm *)addr)->svm_port;
default:
if (grpc_is_unix_socket(resolved_addr)) {
return 1;
@@ -264,6 +268,9 @@ int grpc_sockaddr_set_port(const grpc_resolved_address *resolved_addr,
GPR_ASSERT(port >= 0 && port < 65536);
((struct sockaddr_in6 *)addr)->sin6_port = htons((uint16_t)port);
return 1;
+ case AF_VSOCK:
+ ((struct sockaddr_vm *)addr)->svm_port = (unsigned int)port;
+ return 1;
default:
gpr_log(GPR_ERROR, "Unknown socket family %d in grpc_sockaddr_set_port",
addr->sa_family);
diff --git a/src/core/lib/iomgr/unix_sockets_posix.c b/src/core/lib/iomgr/unix_sockets_posix.c
index 281865aece..98e7fb0a20 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.c
+++ b/src/core/lib/iomgr/unix_sockets_posix.c
@@ -36,6 +36,7 @@
#include "src/core/lib/iomgr/sockaddr.h"
+#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -74,9 +75,30 @@ 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) {
+ 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 = gpr_malloc(sizeof(grpc_resolved_addresses));
+ (*addrs)->naddrs = 1;
+ (*addrs)->addrs = 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;
+}
+
int grpc_is_unix_socket(const grpc_resolved_address *resolved_addr) {
const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr;
- return addr->sa_family == AF_UNIX;
+ return addr->sa_family == AF_UNIX || addr->sa_family == AF_VSOCK;
}
void grpc_unlink_if_unix_domain_socket(
@@ -96,6 +118,13 @@ void grpc_unlink_if_unix_domain_socket(
char *grpc_sockaddr_to_uri_unix_if_possible(
const grpc_resolved_address *resolved_addr) {
const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr;
+ if (addr->sa_family == AF_VSOCK) {
+ char *result;
+ struct sockaddr_vm *vm = (struct sockaddr_vm*)addr;
+ gpr_asprintf(&result, "vsock:%u:%u", vm->svm_cid, vm->svm_port);
+ return result;
+ }
+
if (addr->sa_family != AF_UNIX) {
return NULL;
}
diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h
index 21afd3aa15..57e09b1483 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.h
+++ b/src/core/lib/iomgr/unix_sockets_posix.h
@@ -45,6 +45,9 @@ 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);
void grpc_unlink_if_unix_domain_socket(
--
2.14.0.rc0.284.gd933b75aa4-goog