From aa76d3d3b642304ba05026593fc8b9cf8b49e072 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Wed, 15 Feb 2017 14:00:01 -0800 Subject: Enclose sin6_scope_id in uri --- src/core/lib/iomgr/sockaddr_utils.c | 12 +++++++++++- src/core/lib/iomgr/tcp_client_posix.c | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/core/lib/iomgr') diff --git a/src/core/lib/iomgr/sockaddr_utils.c b/src/core/lib/iomgr/sockaddr_utils.c index 44bc2f968b..f23f9888d5 100644 --- a/src/core/lib/iomgr/sockaddr_utils.c +++ b/src/core/lib/iomgr/sockaddr_utils.c @@ -162,6 +162,7 @@ int grpc_sockaddr_to_string(char **out, char ntop_buf[INET6_ADDRSTRLEN]; const void *ip = NULL; int port; + uint32_t sin6_scope_id = 0; int ret; *out = NULL; @@ -177,10 +178,19 @@ int grpc_sockaddr_to_string(char **out, const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; ip = &addr6->sin6_addr; port = ntohs(addr6->sin6_port); + sin6_scope_id = addr6->sin6_scope_id; } if (ip != NULL && grpc_inet_ntop(addr->sa_family, ip, ntop_buf, sizeof(ntop_buf)) != NULL) { - ret = gpr_join_host_port(out, ntop_buf, port); + if (sin6_scope_id != 0) { + char *host_with_scope; + /* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */ + gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id); + ret = gpr_join_host_port(out, host_with_scope, port); + gpr_free(host_with_scope); + } else { + ret = gpr_join_host_port(out, ntop_buf, port); + } } else { ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family); } diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c index 9a77c92016..b40c31a5da 100644 --- a/src/core/lib/iomgr/tcp_client_posix.c +++ b/src/core/lib/iomgr/tcp_client_posix.c @@ -37,6 +37,9 @@ #include "src/core/lib/iomgr/tcp_client_posix.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" + #include #include #include -- cgit v1.2.3 From c40d1d84f9d492561cb71ea3f5304ef780d7e574 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Wed, 15 Feb 2017 20:42:06 -0800 Subject: Use the internal slice api Address review comments --- .../ext/client_channel/client_channel_plugin.c | 2 +- .../ext/client_channel/http_connect_handshaker.c | 13 +++++---- src/core/ext/client_channel/parse_address.c | 4 ++- src/core/ext/client_channel/resolver_registry.c | 22 ++++++++------- src/core/ext/client_channel/resolver_registry.h | 5 ++-- src/core/ext/client_channel/subchannel.c | 12 ++++---- src/core/ext/client_channel/subchannel.h | 3 +- src/core/ext/client_channel/uri_parser.c | 33 +++++++++++++--------- src/core/ext/client_channel/uri_parser.h | 4 ++- src/core/ext/lb_policy/grpclb/grpclb.c | 2 +- .../ext/transport/chttp2/client/chttp2_connector.c | 2 +- src/core/lib/iomgr/tcp_client_posix.c | 3 -- test/core/client_channel/parse_address_test.c | 15 +++++++--- .../resolvers/dns_resolver_connectivity_test.c | 2 +- .../client_channel/resolvers/dns_resolver_test.c | 4 +-- .../resolvers/sockaddr_resolver_test.c | 4 +-- test/core/client_channel/uri_fuzzer_test.c | 5 +++- test/core/client_channel/uri_parser_test.c | 21 ++++++++++---- 18 files changed, 95 insertions(+), 61 deletions(-) (limited to 'src/core/lib/iomgr') diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c index d50bba60f6..9220ec5878 100644 --- a/src/core/ext/client_channel/client_channel_plugin.c +++ b/src/core/ext/client_channel/client_channel_plugin.c @@ -62,7 +62,7 @@ static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx, } } char *default_authority = grpc_get_default_authority( - grpc_channel_stack_builder_get_target(builder)); + exec_ctx, grpc_channel_stack_builder_get_target(builder)); if (default_authority != NULL) { grpc_arg arg; arg.type = GRPC_ARG_STRING; diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c index fba32561ac..b83cec00dc 100644 --- a/src/core/ext/client_channel/http_connect_handshaker.c +++ b/src/core/ext/client_channel/http_connect_handshaker.c @@ -280,9 +280,9 @@ static void http_connect_handshaker_do_handshake( const grpc_arg* arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI); GPR_ASSERT(arg != NULL); GPR_ASSERT(arg->type == GRPC_ARG_STRING); - char* canonical_uri = - grpc_resolver_factory_add_default_prefix_if_needed(arg->value.string); - grpc_uri* uri = grpc_uri_parse(canonical_uri, 1); + char* canonical_uri = grpc_resolver_factory_add_default_prefix_if_needed( + exec_ctx, arg->value.string); + grpc_uri* uri = grpc_uri_parse(exec_ctx, canonical_uri, 1); char* server_name = uri->path; if (server_name[0] == '/') ++server_name; // Save state in the handshaker object. @@ -344,10 +344,11 @@ grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server, return &handshaker->base; } -char* grpc_get_http_proxy_server() { +char* grpc_get_http_proxy_server(grpc_exec_ctx* exec_ctx) { char* uri_str = gpr_getenv("http_proxy"); if (uri_str == NULL) return NULL; - grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */); + grpc_uri* uri = + grpc_uri_parse(exec_ctx, uri_str, false /* suppress_errors */); char* proxy_name = NULL; if (uri == NULL || uri->authority == NULL) { gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var"); @@ -375,7 +376,7 @@ done: static void handshaker_factory_add_handshakers( grpc_exec_ctx* exec_ctx, grpc_handshaker_factory* factory, const grpc_channel_args* args, grpc_handshake_manager* handshake_mgr) { - char* proxy_name = grpc_get_http_proxy_server(); + char* proxy_name = grpc_get_http_proxy_server(exec_ctx); if (proxy_name != NULL) { grpc_handshake_manager_add( handshake_mgr, diff --git a/src/core/ext/client_channel/parse_address.c b/src/core/ext/client_channel/parse_address.c index eb1df84bc6..a9baa73657 100644 --- a/src/core/ext/client_channel/parse_address.c +++ b/src/core/ext/client_channel/parse_address.c @@ -121,10 +121,12 @@ int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) { resolved_addr->len = sizeof(*in6); in6->sin6_family = AF_INET6; + /* Handle the RFC6874 syntax for IPv6 zone identifiers. */ char *host_end = (char *)gpr_memrchr(host, '%', strlen(host)); if (host_end != NULL) { + GPR_ASSERT(host_end >= host); + char host_without_scope[INET6_ADDRSTRLEN]; size_t host_without_scope_len = (size_t)(host_end - host); - char host_without_scope[host_without_scope_len + 1]; strncpy(host_without_scope, host, host_without_scope_len); host_without_scope[host_without_scope_len] = '\0'; if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) { diff --git a/src/core/ext/client_channel/resolver_registry.c b/src/core/ext/client_channel/resolver_registry.c index 5110a7cad9..e04c7332d6 100644 --- a/src/core/ext/client_channel/resolver_registry.c +++ b/src/core/ext/client_channel/resolver_registry.c @@ -108,22 +108,23 @@ static grpc_resolver_factory *lookup_factory_by_uri(grpc_uri *uri) { return lookup_factory(uri->scheme); } -static grpc_resolver_factory *resolve_factory(const char *target, +static grpc_resolver_factory *resolve_factory(grpc_exec_ctx *exec_ctx, + const char *target, grpc_uri **uri, char **canonical_target) { grpc_resolver_factory *factory = NULL; GPR_ASSERT(uri != NULL); - *uri = grpc_uri_parse(target, 1); + *uri = grpc_uri_parse(exec_ctx, target, 1); factory = lookup_factory_by_uri(*uri); if (factory == NULL) { grpc_uri_destroy(*uri); gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target); - *uri = grpc_uri_parse(*canonical_target, 1); + *uri = grpc_uri_parse(exec_ctx, *canonical_target, 1); factory = lookup_factory_by_uri(*uri); if (factory == NULL) { - grpc_uri_destroy(grpc_uri_parse(target, 0)); - grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0)); + grpc_uri_destroy(grpc_uri_parse(exec_ctx, target, 0)); + grpc_uri_destroy(grpc_uri_parse(exec_ctx, *canonical_target, 0)); gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, *canonical_target); } @@ -137,7 +138,7 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target, grpc_uri *uri = NULL; char *canonical_target = NULL; grpc_resolver_factory *factory = - resolve_factory(target, &uri, &canonical_target); + resolve_factory(exec_ctx, target, &uri, &canonical_target); grpc_resolver *resolver; grpc_resolver_args resolver_args; memset(&resolver_args, 0, sizeof(resolver_args)); @@ -151,21 +152,22 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target, return resolver; } -char *grpc_get_default_authority(const char *target) { +char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target) { grpc_uri *uri = NULL; char *canonical_target = NULL; grpc_resolver_factory *factory = - resolve_factory(target, &uri, &canonical_target); + resolve_factory(exec_ctx, target, &uri, &canonical_target); char *authority = grpc_resolver_factory_get_default_authority(factory, uri); grpc_uri_destroy(uri); gpr_free(canonical_target); return authority; } -char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target) { +char *grpc_resolver_factory_add_default_prefix_if_needed( + grpc_exec_ctx *exec_ctx, const char *target) { grpc_uri *uri = NULL; char *canonical_target = NULL; - resolve_factory(target, &uri, &canonical_target); + resolve_factory(exec_ctx, target, &uri, &canonical_target); grpc_uri_destroy(uri); return canonical_target == NULL ? gpr_strdup(target) : canonical_target; } diff --git a/src/core/ext/client_channel/resolver_registry.h b/src/core/ext/client_channel/resolver_registry.h index a4606463eb..cb8c59333c 100644 --- a/src/core/ext/client_channel/resolver_registry.h +++ b/src/core/ext/client_channel/resolver_registry.h @@ -73,10 +73,11 @@ grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name); /** Given a target, return a (freshly allocated with gpr_malloc) string representing the default authority to pass from a client. */ -char *grpc_get_default_authority(const char *target); +char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target); /** Returns a newly allocated string containing \a target, adding the default prefix if needed. */ -char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target); +char *grpc_resolver_factory_add_default_prefix_if_needed( + grpc_exec_ctx *exec_ctx, const char *target); #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */ diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c index 8bd284507d..38e6b8013a 100644 --- a/src/core/ext/client_channel/subchannel.c +++ b/src/core/ext/client_channel/subchannel.c @@ -330,7 +330,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, } c->pollset_set = grpc_pollset_set_create(); grpc_resolved_address *addr = gpr_malloc(sizeof(*addr)); - grpc_get_subchannel_address_arg(args->args, addr); + grpc_get_subchannel_address_arg(exec_ctx, args->args, addr); grpc_set_initial_connect_string(&addr, &c->initial_connect_string); static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS}; grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); @@ -777,8 +777,9 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack( return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); } -static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) { - grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); +static void grpc_uri_to_sockaddr(grpc_exec_ctx *exec_ctx, const char *uri_str, + grpc_resolved_address *addr) { + grpc_uri *uri = grpc_uri_parse(exec_ctx, uri_str, 0 /* suppress_errors */); GPR_ASSERT(uri != NULL); if (strcmp(uri->scheme, "ipv4") == 0) { GPR_ASSERT(parse_ipv4(uri, addr)); @@ -790,7 +791,8 @@ static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) { grpc_uri_destroy(uri); } -void grpc_get_subchannel_address_arg(const grpc_channel_args *args, +void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx, + const grpc_channel_args *args, grpc_resolved_address *addr) { const grpc_arg *addr_arg = grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); @@ -798,7 +800,7 @@ void grpc_get_subchannel_address_arg(const grpc_channel_args *args, GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING); memset(addr, 0, sizeof(*addr)); if (*addr_arg->value.string != '\0') { - grpc_uri_to_sockaddr(addr_arg->value.string, addr); + grpc_uri_to_sockaddr(exec_ctx, addr_arg->value.string, addr); } } diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h index 684675eb37..279524bccd 100644 --- a/src/core/ext/client_channel/subchannel.h +++ b/src/core/ext/client_channel/subchannel.h @@ -175,7 +175,8 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, const grpc_subchannel_args *args); /// Sets \a addr from \a args. -void grpc_get_subchannel_address_arg(const grpc_channel_args *args, +void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx, + const grpc_channel_args *args, grpc_resolved_address *addr); /// Returns a new channel arg encoding the subchannel address as a string. diff --git a/src/core/ext/client_channel/uri_parser.c b/src/core/ext/client_channel/uri_parser.c index e521afd0c6..5b3dea8e59 100644 --- a/src/core/ext/client_channel/uri_parser.c +++ b/src/core/ext/client_channel/uri_parser.c @@ -35,7 +35,6 @@ #include -#include #include #include #include @@ -43,6 +42,8 @@ #include #include "src/core/lib/slice/percent_encoding.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" /** a size_t default value... maps to all 1's */ @@ -70,15 +71,15 @@ static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section, } /** Returns a copy of percent decoded \a src[begin, end) */ -static char *decode_and_copy_component(const char *src, size_t begin, - size_t end) { +static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src, + size_t begin, size_t end) { grpc_slice component = grpc_slice_from_copied_buffer(src + begin, end - begin); grpc_slice decoded_component = grpc_permissive_percent_decode_slice(component); - char *out = grpc_slice_to_c_string(decoded_component); - grpc_slice_unref(component); - grpc_slice_unref(decoded_component); + char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII); + grpc_slice_unref_internal(exec_ctx, component); + grpc_slice_unref_internal(exec_ctx, decoded_component); return out; } @@ -181,7 +182,8 @@ static void parse_query_parts(grpc_uri *uri) { } } -grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { +grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text, + int suppress_errors) { grpc_uri *uri; size_t scheme_begin = 0; size_t scheme_end = NOT_SET; @@ -270,13 +272,16 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { uri = gpr_malloc(sizeof(*uri)); memset(uri, 0, sizeof(*uri)); - uri->scheme = decode_and_copy_component(uri_text, scheme_begin, scheme_end); - uri->authority = - decode_and_copy_component(uri_text, authority_begin, authority_end); - uri->path = decode_and_copy_component(uri_text, path_begin, path_end); - uri->query = decode_and_copy_component(uri_text, query_begin, query_end); - uri->fragment = - decode_and_copy_component(uri_text, fragment_begin, fragment_end); + uri->scheme = + decode_and_copy_component(exec_ctx, uri_text, scheme_begin, scheme_end); + uri->authority = decode_and_copy_component(exec_ctx, uri_text, + authority_begin, authority_end); + uri->path = + decode_and_copy_component(exec_ctx, uri_text, path_begin, path_end); + uri->query = + decode_and_copy_component(exec_ctx, uri_text, query_begin, query_end); + uri->fragment = decode_and_copy_component(exec_ctx, uri_text, fragment_begin, + fragment_end); parse_query_parts(uri); return uri; diff --git a/src/core/ext/client_channel/uri_parser.h b/src/core/ext/client_channel/uri_parser.h index 5fe0e8f35e..efd4302c1c 100644 --- a/src/core/ext/client_channel/uri_parser.h +++ b/src/core/ext/client_channel/uri_parser.h @@ -35,6 +35,7 @@ #define GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H #include +#include "src/core/lib/iomgr/exec_ctx.h" typedef struct { char *scheme; @@ -51,7 +52,8 @@ typedef struct { } grpc_uri; /** parse a uri, return NULL on failure */ -grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors); +grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text, + int suppress_errors); /** return the part of a query string after the '=' in "?key=xxx&...", or NULL * if key is not present */ diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 567e65ac69..8ccebd7608 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -774,7 +774,7 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI); GPR_ASSERT(arg != NULL); GPR_ASSERT(arg->type == GRPC_ARG_STRING); - grpc_uri *uri = grpc_uri_parse(arg->value.string, true); + grpc_uri *uri = grpc_uri_parse(exec_ctx, arg->value.string, true); GPR_ASSERT(uri->path[0] != '\0'); glb_policy->server_name = gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path); diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c index 013c96dc70..6e262b0654 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.c +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c @@ -222,7 +222,7 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx, grpc_closure *notify) { chttp2_connector *c = (chttp2_connector *)con; grpc_resolved_address addr; - grpc_get_subchannel_address_arg(args->channel_args, &addr); + grpc_get_subchannel_address_arg(exec_ctx, args->channel_args, &addr); gpr_mu_lock(&c->mu); GPR_ASSERT(c->notify == NULL); c->notify = notify; diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c index b40c31a5da..9a77c92016 100644 --- a/src/core/lib/iomgr/tcp_client_posix.c +++ b/src/core/lib/iomgr/tcp_client_posix.c @@ -37,9 +37,6 @@ #include "src/core/lib/iomgr/tcp_client_posix.h" -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/iomgr/socket_utils_posix.h" - #include #include #include diff --git a/test/core/client_channel/parse_address_test.c b/test/core/client_channel/parse_address_test.c index 79079acb5d..37dd0fba52 100644 --- a/test/core/client_channel/parse_address_test.c +++ b/test/core/client_channel/parse_address_test.c @@ -41,13 +41,15 @@ #include +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_utils.h" #include "test/core/util/test_config.h" #ifdef GRPC_HAVE_UNIX_SOCKET static void test_parse_unix(const char *uri_text, const char *pathname) { - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); grpc_resolved_address addr; GPR_ASSERT(1 == parse_unix(uri, &addr)); @@ -56,6 +58,7 @@ static void test_parse_unix(const char *uri_text, const char *pathname) { GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname)); grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); } #else /* GRPC_HAVE_UNIX_SOCKET */ @@ -66,7 +69,8 @@ static void test_parse_unix(const char *uri_text, const char *pathname) {} static void test_parse_ipv4(const char *uri_text, const char *host, unsigned short port) { - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); grpc_resolved_address addr; char ntop_buf[INET_ADDRSTRLEN]; @@ -79,11 +83,13 @@ static void test_parse_ipv4(const char *uri_text, const char *host, GPR_ASSERT(ntohs(addr_in->sin_port) == port); grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); } static void test_parse_ipv6(const char *uri_text, const char *host, - unsigned short port, u_int32_t scope_id) { - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + unsigned short port, uint32_t scope_id) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); grpc_resolved_address addr; char ntop_buf[INET6_ADDRSTRLEN]; @@ -97,6 +103,7 @@ static void test_parse_ipv6(const char *uri_text, const char *host, GPR_ASSERT(addr_in6->sin6_scope_id == scope_id); grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); } int main(int argc, char **argv) { diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c index f0c6843a68..c60ceb3817 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c @@ -66,7 +66,7 @@ static grpc_error *my_resolve_address(const char *name, const char *addr, static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx, const char *name) { grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns"); - grpc_uri *uri = grpc_uri_parse(name, 0); + grpc_uri *uri = grpc_uri_parse(exec_ctx, name, 0); GPR_ASSERT(uri); grpc_resolver_args args; memset(&args, 0, sizeof(args)); diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c index 5603a57b5f..706f3ce6ad 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_test.c @@ -40,7 +40,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, @@ -57,7 +57,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { static void test_fails(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c index 10df78537c..f36f4dd58c 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c @@ -54,7 +54,7 @@ void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { static void test_succeeds(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, @@ -80,7 +80,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { static void test_fails(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, diff --git a/test/core/client_channel/uri_fuzzer_test.c b/test/core/client_channel/uri_fuzzer_test.c index d2e3fb40ea..baadd4fc65 100644 --- a/test/core/client_channel/uri_fuzzer_test.c +++ b/test/core/client_channel/uri_fuzzer_test.c @@ -38,6 +38,7 @@ #include #include "src/core/ext/client_channel/uri_parser.h" +#include "src/core/lib/iomgr/exec_ctx.h" bool squelch = true; bool leak_check = true; @@ -47,10 +48,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { memcpy(s, data, size); s[size] = 0; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_uri *x; - if ((x = grpc_uri_parse(s, 1))) { + if ((x = grpc_uri_parse(&exec_ctx, s, 1))) { grpc_uri_destroy(x); } + grpc_exec_ctx_finish(&exec_ctx); gpr_free(s); return 0; } diff --git a/test/core/client_channel/uri_parser_test.c b/test/core/client_channel/uri_parser_test.c index 489e4ecd51..8a127f72eb 100644 --- a/test/core/client_channel/uri_parser_test.c +++ b/test/core/client_channel/uri_parser_test.c @@ -37,29 +37,35 @@ #include +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" static void test_succeeds(const char *uri_text, const char *scheme, const char *authority, const char *path, const char *query, const char *fragment) { - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp(scheme, uri->scheme)); GPR_ASSERT(0 == strcmp(authority, uri->authority)); GPR_ASSERT(0 == strcmp(path, uri->path)); GPR_ASSERT(0 == strcmp(query, uri->query)); GPR_ASSERT(0 == strcmp(fragment, uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } static void test_fails(const char *uri_text) { - GPR_ASSERT(NULL == grpc_uri_parse(uri_text, 0)); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GPR_ASSERT(NULL == grpc_uri_parse(&exec_ctx, uri_text, 0)); + grpc_exec_ctx_finish(&exec_ctx); } static void test_query_parts() { { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://foo/path?a&b=B&c=&#frag"; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -86,12 +92,14 @@ static void test_query_parts() { GPR_ASSERT(NULL == grpc_uri_get_query_arg(uri, "")); GPR_ASSERT(0 == strcmp("frag", uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } { /* test the current behavior of multiple query part values */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://auth/path?foo=bar=baz&foobar=="; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -103,12 +111,14 @@ static void test_query_parts() { GPR_ASSERT(0 == strcmp("bar", grpc_uri_get_query_arg(uri, "foo"))); GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "foobar"))); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } { /* empty query */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://foo/path"; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -119,6 +129,7 @@ static void test_query_parts() { GPR_ASSERT(NULL == uri->query_parts); GPR_ASSERT(NULL == uri->query_parts_values); GPR_ASSERT(0 == strcmp("", uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } } -- cgit v1.2.3 From f26236a159300c92633fafd0a906691165bc3289 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 7 Mar 2017 09:43:51 -0800 Subject: Silence accept4 message when its irrelevant --- src/core/lib/iomgr/tcp_server_posix.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/core/lib/iomgr') diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 36f878fdd4..b93e9c410a 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -114,6 +114,8 @@ struct grpc_tcp_server { /* is this server shutting down? */ bool shutdown; + /* have listeners been shutdown? */ + bool shutdown_listeners; /* use SO_REUSEPORT */ bool so_reuseport; /* expand wildcard addresses to a list of all local addresses */ @@ -422,7 +424,12 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) { grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); return; default: - gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); + if (!sp->server->shutdown_listeners) { + gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); + } else { + /* if we have shutdown listeners, accept4 could fail, and we + needn't notify users */ + } goto error; } } @@ -438,11 +445,6 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) { grpc_fd *fdobj = grpc_fd_create(fd, name); - if (read_notifier_pollset == NULL) { - gpr_log(GPR_ERROR, "Read notifier pollset is not set on the fd"); - goto error; - } - grpc_pollset_add_fd(exec_ctx, read_notifier_pollset, fdobj); // Create acceptor. @@ -941,6 +943,7 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { gpr_mu_lock(&s->mu); + s->shutdown_listeners = true; /* shutdown all fd's */ if (s->active_ports) { grpc_tcp_listener *sp; -- cgit v1.2.3 From 702a445dc199bd3308bbb70b94ef50386cedd215 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 7 Mar 2017 09:53:00 -0800 Subject: Fix initialization --- src/core/lib/iomgr/tcp_server_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/lib/iomgr') diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index b93e9c410a..a17f6d48ef 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -163,7 +163,7 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx, grpc_tcp_server **server) { gpr_once_init(&check_init, init); - grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server)); + grpc_tcp_server *s = gpr_zalloc(sizeof(grpc_tcp_server)); s->so_reuseport = has_so_reuseport; s->resource_quota = grpc_resource_quota_create(NULL); s->expand_wildcard_addrs = false; -- cgit v1.2.3 From 144446434507dcc6d4583a04e723904df5cd2718 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 7 Mar 2017 16:21:55 -0800 Subject: Fix locking --- src/core/lib/iomgr/tcp_server_posix.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core/lib/iomgr') diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index a17f6d48ef..5f286a6723 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -424,12 +424,14 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) { grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure); return; default: + gpr_mu_lock(&sp->server->mu); if (!sp->server->shutdown_listeners) { gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno)); } else { /* if we have shutdown listeners, accept4 could fail, and we needn't notify users */ } + gpr_mu_unlock(&sp->server->mu); goto error; } } -- cgit v1.2.3 From 69709e2819f5eeeb47a16f7ed964dd1196b94ff0 Mon Sep 17 00:00:00 2001 From: Robbie Shade Date: Wed, 8 Mar 2017 12:54:28 -0500 Subject: Fix flaky use-after-free in udp_server --- src/core/lib/iomgr/udp_server.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/core/lib/iomgr') diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 2a1c8d39fa..d1bcd89af1 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -485,7 +485,11 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s, grpc_schedule_on_exec_ctx); grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure); - s->active_ports++; + /* Registered for both read and write callbacks: increment active_ports + * twice to account for this, and delay free-ing of memory until both + * on_read and on_write have fired. */ + s->active_ports += 2; + sp = sp->next; } -- cgit v1.2.3