From 454fbd2cec48a8d31cb58ddf71d0171856f05b2f Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 28 Nov 2017 14:37:20 -0800 Subject: [PATCH 1/2] Fix uv TCP server handling of wildcard addresses --- src/core/lib/iomgr/tcp_server_uv.cc | 98 ++++++++++++++++++----------- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/src/core/lib/iomgr/tcp_server_uv.cc b/src/core/lib/iomgr/tcp_server_uv.cc index 2c76fae7fd6..9638f15aaf8 100644 --- a/src/core/lib/iomgr/tcp_server_uv.cc +++ b/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,46 @@ 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 +414,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); From 9bdb171151286cffb0ec36b6ac38493dda1baf2f Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 28 Nov 2017 17:50:53 -0800 Subject: [PATCH 2/2] Clang format --- src/core/lib/iomgr/tcp_server_uv.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/tcp_server_uv.cc b/src/core/lib/iomgr/tcp_server_uv.cc index 9638f15aaf8..ffadf0b1abd 100644 --- a/src/core/lib/iomgr/tcp_server_uv.cc +++ b/src/core/lib/iomgr/tcp_server_uv.cc @@ -349,7 +349,7 @@ static grpc_error* add_addr_to_server(grpc_tcp_server* s, static grpc_error* add_wildcard_addrs_to_server(grpc_tcp_server* s, unsigned port_index, int requested_port, - grpc_tcp_listener **listener) { + grpc_tcp_listener** listener) { grpc_resolved_address wild4; grpc_resolved_address wild6; grpc_tcp_listener* sp = nullptr; @@ -359,12 +359,14 @@ static grpc_error* add_wildcard_addrs_to_server(grpc_tcp_server* s, 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) { + 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) { + if ((v4_err = add_addr_to_server(s, &wild4, port_index, &sp2)) == + GRPC_ERROR_NONE) { *listener = sp2; return GRPC_ERROR_NONE; }