Unix domain socket support

pull/525/head
Craig Tiller 10 years ago
parent bb62706f84
commit ae7fe92389
  1. 1586
      Makefile
  2. 13
      src/core/iomgr/resolve_address.c
  3. 2
      src/core/iomgr/sockaddr_utils.c
  4. 6
      src/core/iomgr/tcp_client_posix.c
  5. 13
      src/core/iomgr/tcp_server_posix.c
  6. 121
      test/core/end2end/fixtures/chttp2_fullstack_uds.c
  7. 1
      test/core/end2end/gen_build_json.py
  8. 2
      test/core/util/grpc_profiler.c
  9. 192
      tools/run_tests/tests.json

1586
Makefile

File diff suppressed because one or more lines are too long

@ -39,6 +39,7 @@
#include "src/core/iomgr/resolve_address.h" #include "src/core/iomgr/resolve_address.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h>
#include <string.h> #include <string.h>
#include "src/core/iomgr/iomgr_internal.h" #include "src/core/iomgr/iomgr_internal.h"
@ -123,6 +124,18 @@ grpc_resolved_addresses *grpc_blocking_resolve_address(
size_t i; size_t i;
grpc_resolved_addresses *addrs = NULL; grpc_resolved_addresses *addrs = NULL;
const gpr_timespec start_time = gpr_now(); const gpr_timespec start_time = gpr_now();
struct sockaddr_un *un;
if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && name[4] == ':' && name[5] != 0) {
addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
addrs->naddrs = 1;
addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address));
un = (struct sockaddr_un *)addrs->addrs->addr;
un->sun_family = AF_UNIX;
strcpy(un->sun_path, name + 5);
addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family);
return addrs;
}
/* parse name, splitting it into host and port parts */ /* parse name, splitting it into host and port parts */
split_host_port(name, &host, &port); split_host_port(name, &host, &port);

@ -166,6 +166,8 @@ int grpc_sockaddr_get_port(const struct sockaddr *addr) {
return ntohs(((struct sockaddr_in *)addr)->sin_port); return ntohs(((struct sockaddr_in *)addr)->sin_port);
case AF_INET6: case AF_INET6:
return ntohs(((struct sockaddr_in6 *)addr)->sin6_port); return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
case AF_UNIX:
return 1;
default: default:
gpr_log(GPR_ERROR, "Unknown socket family %d in %s", addr->sa_family, gpr_log(GPR_ERROR, "Unknown socket family %d in %s", addr->sa_family,
__FUNCTION__); __FUNCTION__);

@ -62,13 +62,13 @@ typedef struct {
int refs; int refs;
} async_connect; } async_connect;
static int prepare_socket(int fd) { static int prepare_socket(const struct sockaddr* addr, int fd) {
if (fd < 0) { if (fd < 0) {
goto error; goto error;
} }
if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
!grpc_set_socket_low_latency(fd, 1)) { (addr->sa_family != AF_UNIX && !grpc_set_socket_low_latency(fd, 1))) {
gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
strerror(errno)); strerror(errno));
goto error; goto error;
@ -200,7 +200,7 @@ void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *ep),
addr = (struct sockaddr *)&addr4_copy; addr = (struct sockaddr *)&addr4_copy;
addr_len = sizeof(addr4_copy); addr_len = sizeof(addr4_copy);
} }
if (!prepare_socket(fd)) { if (!prepare_socket(addr, fd)) {
cb(arg, NULL); cb(arg, NULL);
return; return;
} }

@ -48,12 +48,14 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "src/core/iomgr/pollset_posix.h" #include "src/core/iomgr/pollset_posix.h"
#include "src/core/iomgr/resolve_address.h"
#include "src/core/iomgr/sockaddr_utils.h" #include "src/core/iomgr/sockaddr_utils.h"
#include "src/core/iomgr/socket_utils_posix.h" #include "src/core/iomgr/socket_utils_posix.h"
#include "src/core/iomgr/tcp_posix.h" #include "src/core/iomgr/tcp_posix.h"
@ -73,6 +75,8 @@ typedef struct {
int fd; int fd;
grpc_fd *emfd; grpc_fd *emfd;
grpc_tcp_server *server; grpc_tcp_server *server;
gpr_uint8 addr[GRPC_MAX_SOCKADDR_SIZE];
int addr_len;
} server_port; } server_port;
/* the overall server */ /* the overall server */
@ -121,6 +125,10 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s) {
/* delete ALL the things */ /* delete ALL the things */
for (i = 0; i < s->nports; i++) { for (i = 0; i < s->nports; i++) {
server_port *sp = &s->ports[i]; server_port *sp = &s->ports[i];
if (((struct sockaddr *)sp->addr)->sa_family == AF_UNIX) {
struct sockaddr_un *un = (struct sockaddr_un *)sp->addr;
unlink(un->sun_path);
}
grpc_fd_orphan(sp->emfd, NULL, NULL); grpc_fd_orphan(sp->emfd, NULL, NULL);
} }
gpr_free(s->ports); gpr_free(s->ports);
@ -170,8 +178,7 @@ static int prepare_socket(int fd, const struct sockaddr *addr, int addr_len) {
} }
if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) || if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
!grpc_set_socket_low_latency(fd, 1) || (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) || !grpc_set_socket_reuse_addr(fd, 1)))) {
!grpc_set_socket_reuse_addr(fd, 1)) {
gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
strerror(errno)); strerror(errno));
goto error; goto error;
@ -265,6 +272,8 @@ static int add_socket_to_server(grpc_tcp_server *s, int fd,
sp->server = s; sp->server = s;
sp->fd = fd; sp->fd = fd;
sp->emfd = grpc_fd_create(fd); sp->emfd = grpc_fd_create(fd);
memcpy(sp->addr, addr, addr_len);
sp->addr_len = addr_len;
GPR_ASSERT(sp->emfd); GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu); gpr_mu_unlock(&s->mu);
} }

@ -0,0 +1,121 @@
/*
*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/core/end2end/end2end_tests.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "src/core/channel/client_channel.h"
#include "src/core/channel/connected_channel.h"
#include "src/core/channel/http_filter.h"
#include "src/core/channel/http_server_filter.h"
#include "src/core/support/string.h"
#include "src/core/surface/channel.h"
#include "src/core/surface/client.h"
#include "src/core/surface/server.h"
#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
typedef struct fullstack_fixture_data {
char *localaddr;
} fullstack_fixture_data;
static int unique = 1;
static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
grpc_channel_args *client_args, grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
memset(&f, 0, sizeof(f));
gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++);
f.fixture_data = ffd;
f.client_cq = grpc_completion_queue_create();
f.server_cq = grpc_completion_queue_create();
return f;
}
void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
fullstack_fixture_data *ffd = f->fixture_data;
f->client = grpc_channel_create(ffd->localaddr, client_args);
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
fullstack_fixture_data *ffd = f->fixture_data;
if (f->server) {
grpc_server_destroy(f->server);
}
f->server = grpc_server_create(f->server_cq, server_args);
GPR_ASSERT(grpc_server_add_http2_port(f->server, ffd->localaddr));
grpc_server_start(f->server);
}
void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
fullstack_fixture_data *ffd = f->fixture_data;
gpr_free(ffd->localaddr);
gpr_free(ffd);
}
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/fullstack_uds", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, };
int main(int argc, char **argv) {
size_t i;
grpc_test_init(argc, argv);
grpc_init();
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
grpc_end2end_tests(configs[i]);
}
grpc_shutdown();
return 0;
}

@ -8,6 +8,7 @@ import simplejson
END2END_FIXTURES = [ END2END_FIXTURES = [
'chttp2_fake_security', 'chttp2_fake_security',
'chttp2_fullstack', 'chttp2_fullstack',
'chttp2_fullstack_uds',
'chttp2_simple_ssl_fullstack', 'chttp2_simple_ssl_fullstack',
'chttp2_simple_ssl_with_oauth2_fullstack', 'chttp2_simple_ssl_with_oauth2_fullstack',
'chttp2_socket_pair', 'chttp2_socket_pair',

@ -33,7 +33,7 @@
#include "test/core/util/grpc_profiler.h" #include "test/core/util/grpc_profiler.h"
#if GRPC_HAVE_PERFTOOLS #if 0&&GRPC_HAVE_PERFTOOLS
#include <gperftools/profiler.h> #include <gperftools/profiler.h>
void grpc_profiler_start(const char *filename) { ProfilerStart(filename); } void grpc_profiler_start(const char *filename) { ProfilerStart(filename); }

@ -681,6 +681,198 @@
"language": "c", "language": "c",
"name": "chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test" "name": "chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test"
}, },
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_after_accept_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_after_invoke_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_before_invoke_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_in_a_vacuum_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_census_simple_request_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_disappearing_server_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_empty_batch_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_graceful_server_shutdown_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_invoke_large_request_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_max_concurrent_streams_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_no_op_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_ping_pong_streaming_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_response_with_metadata_and_payload_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_response_with_payload_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_with_large_metadata_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_with_payload_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_simple_delayed_request_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_simple_request_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_thread_stress_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_after_accept_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_after_invoke_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_before_invoke_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_census_simple_request_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_disappearing_server_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_graceful_server_shutdown_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_invoke_large_request_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_max_concurrent_streams_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_no_op_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_ping_pong_streaming_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_response_with_payload_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_with_large_metadata_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_request_with_payload_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_simple_delayed_request_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_simple_request_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_thread_stress_legacy_test"
},
{
"language": "c",
"name": "chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test"
},
{ {
"language": "c", "language": "c",
"name": "chttp2_simple_ssl_fullstack_cancel_after_accept_test" "name": "chttp2_simple_ssl_fullstack_cancel_after_accept_test"

Loading…
Cancel
Save