Merge pull request #13532 from murgatroid99/uv_tcp_wildcard_handling

Fix uv TCP server handling of wildcard addresses
pull/13633/head
Michael Lumish 7 years ago committed by GitHub
commit 65212e06ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 100
      src/core/lib/iomgr/tcp_server_uv.cc

@ -260,15 +260,36 @@ static void on_connect(uv_stream_t* server, int status) {
grpc_exec_ctx_finish(&exec_ctx);
}
static grpc_error* add_socket_to_server(grpc_tcp_server* s, uv_tcp_t* handle,
const grpc_resolved_address* addr,
unsigned port_index,
grpc_tcp_listener** listener) {
static grpc_error* add_addr_to_server(grpc_tcp_server* s,
const grpc_resolved_address* addr,
unsigned port_index,
grpc_tcp_listener** listener) {
grpc_tcp_listener* sp = NULL;
int port = -1;
int status;
grpc_error* error;
grpc_resolved_address sockname_temp;
uv_tcp_t* handle = (uv_tcp_t*)gpr_malloc(sizeof(uv_tcp_t));
int family = grpc_sockaddr_get_family(addr);
status = uv_tcp_init_ex(uv_default_loop(), handle, (unsigned int)family);
#if defined(GPR_LINUX) && defined(SO_REUSEPORT)
if (family == AF_INET || family == AF_INET6) {
int fd;
uv_fileno((uv_handle_t*)handle, &fd);
int enable = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
}
#endif /* GPR_LINUX && SO_REUSEPORT */
if (status != 0) {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to initialize UV tcp handle");
error =
grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
grpc_slice_from_static_string(uv_strerror(status)));
return error;
}
// The last argument to uv_tcp_bind is flags
status = uv_tcp_bind(handle, (struct sockaddr*)addr->addr, 0);
@ -325,20 +346,48 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, uv_tcp_t* handle,
return GRPC_ERROR_NONE;
}
static grpc_error* add_wildcard_addrs_to_server(grpc_tcp_server* s,
unsigned port_index,
int requested_port,
grpc_tcp_listener** listener) {
grpc_resolved_address wild4;
grpc_resolved_address wild6;
grpc_tcp_listener* sp = nullptr;
grpc_tcp_listener* sp2 = nullptr;
grpc_error* v6_err = GRPC_ERROR_NONE;
grpc_error* v4_err = GRPC_ERROR_NONE;
grpc_sockaddr_make_wildcards(requested_port, &wild4, &wild6);
/* Try listening on IPv6 first. */
if ((v6_err = add_addr_to_server(s, &wild6, port_index, &sp)) ==
GRPC_ERROR_NONE) {
*listener = sp;
return GRPC_ERROR_NONE;
}
if ((v4_err = add_addr_to_server(s, &wild4, port_index, &sp2)) ==
GRPC_ERROR_NONE) {
*listener = sp2;
return GRPC_ERROR_NONE;
}
grpc_error* root_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to add any wildcard listeners");
root_err = grpc_error_add_child(root_err, v6_err);
root_err = grpc_error_add_child(root_err, v4_err);
return root_err;
}
grpc_error* grpc_tcp_server_add_port(grpc_tcp_server* s,
const grpc_resolved_address* addr,
int* port) {
// This function is mostly copied from tcp_server_windows.c
grpc_tcp_listener* sp = NULL;
uv_tcp_t* handle;
grpc_resolved_address addr6_v4mapped;
grpc_resolved_address wildcard;
grpc_resolved_address* allocated_addr = NULL;
grpc_resolved_address sockname_temp;
unsigned port_index = 0;
int status;
grpc_error* error = GRPC_ERROR_NONE;
int family;
GRPC_UV_ASSERT_SAME_THREAD();
@ -367,38 +416,15 @@ grpc_error* grpc_tcp_server_add_port(grpc_tcp_server* s,
}
}
if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
addr = &addr6_v4mapped;
}
/* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
if (grpc_sockaddr_is_wildcard(addr, port)) {
grpc_sockaddr_make_wildcard6(*port, &wildcard);
addr = &wildcard;
}
handle = (uv_tcp_t*)gpr_malloc(sizeof(uv_tcp_t));
family = grpc_sockaddr_get_family(addr);
status = uv_tcp_init_ex(uv_default_loop(), handle, (unsigned int)family);
#if defined(GPR_LINUX) && defined(SO_REUSEPORT)
if (family == AF_INET || family == AF_INET6) {
int fd;
uv_fileno((uv_handle_t*)handle, &fd);
int enable = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(enable));
}
#endif /* GPR_LINUX && SO_REUSEPORT */
if (status == 0) {
error = add_socket_to_server(s, handle, addr, port_index, &sp);
error = add_wildcard_addrs_to_server(s, port_index, *port, &sp);
} else {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to initialize UV tcp handle");
error =
grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
grpc_slice_from_static_string(uv_strerror(status)));
if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
addr = &addr6_v4mapped;
}
error = add_addr_to_server(s, addr, port_index, &sp);
}
gpr_free(allocated_addr);

Loading…
Cancel
Save