diff options
Diffstat (limited to 'src')
41 files changed, 721 insertions, 282 deletions
diff --git a/src/core/ext/census/tracing.c b/src/core/ext/census/tracing.c index 8f0e12296d..3b5d6dab2b 100644 --- a/src/core/ext/census/tracing.c +++ b/src/core/ext/census/tracing.c @@ -31,19 +31,15 @@ * */ -//#include "src/core/ext/census/tracing.h" - #include <grpc/census.h> /* TODO(aveitch): These are all placeholder implementations. */ -// int census_trace_mask(const census_context *context) { -// return CENSUS_TRACE_MASK_NONE; -// } - -// void census_set_trace_mask(int trace_mask) {} +int census_trace_mask(const census_context *context) { + return CENSUS_TRACE_MASK_NONE; +} -// void census_trace_print(census_context *context, uint32_t type, -// const char *buffer, size_t n) {} +void census_set_trace_mask(int trace_mask) {} -// void SetTracerParams(const Params& params); +void census_trace_print(census_context *context, uint32_t type, + const char *buffer, size_t n) {} diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c index 988b7a1d5c..d50bba60f6 100644 --- a/src/core/ext/client_channel/client_channel_plugin.c +++ b/src/core/ext/client_channel/client_channel_plugin.c @@ -38,6 +38,7 @@ #include <grpc/support/alloc.h> #include "src/core/ext/client_channel/client_channel.h" +#include "src/core/ext/client_channel/http_connect_handshaker.h" #include "src/core/ext/client_channel/lb_policy_registry.h" #include "src/core/ext/client_channel/resolver_registry.h" #include "src/core/ext/client_channel/subchannel_index.h" @@ -84,6 +85,7 @@ void grpc_client_channel_init(void) { set_default_host_if_unset, NULL); grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter, (void *)&grpc_client_channel_filter); + grpc_http_connect_register_handshaker_factory(); } void grpc_client_channel_shutdown(void) { diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c index 27b117af84..fba32561ac 100644 --- a/src/core/ext/client_channel/http_connect_handshaker.c +++ b/src/core/ext/client_channel/http_connect_handshaker.c @@ -44,6 +44,7 @@ #include "src/core/ext/client_channel/resolver_registry.h" #include "src/core/ext/client_channel/uri_parser.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/http/format_request.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/slice/slice_internal.h" @@ -54,6 +55,8 @@ typedef struct http_connect_handshaker { grpc_handshaker base; char* proxy_server; + grpc_http_header* headers; + size_t num_headers; gpr_refcount refcount; gpr_mu mu; @@ -89,6 +92,11 @@ static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx, gpr_free(handshaker->read_buffer_to_destroy); } gpr_free(handshaker->proxy_server); + for (size_t i = 0; i < handshaker->num_headers; ++i) { + gpr_free(handshaker->headers[i].key); + gpr_free(handshaker->headers[i].value); + } + gpr_free(handshaker->headers); grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer); grpc_http_parser_destroy(&handshaker->http_parser); grpc_http_response_destroy(&handshaker->http_response); @@ -289,6 +297,8 @@ static void http_connect_handshaker_do_handshake( request.host = server_name; request.http.method = "CONNECT"; request.http.path = server_name; + request.http.hdrs = handshaker->headers; + request.http.hdr_count = handshaker->num_headers; request.handshaker = &grpc_httpcli_plaintext; grpc_slice request_slice = grpc_httpcli_format_connect_request(&request); grpc_slice_buffer_add(&handshaker->write_buffer, request_slice); @@ -306,7 +316,9 @@ static const grpc_handshaker_vtable http_connect_handshaker_vtable = { http_connect_handshaker_destroy, http_connect_handshaker_shutdown, http_connect_handshaker_do_handshake}; -grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server) { +grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server, + grpc_http_header* headers, + size_t num_headers) { GPR_ASSERT(proxy_server != NULL); http_connect_handshaker* handshaker = gpr_malloc(sizeof(*handshaker)); memset(handshaker, 0, sizeof(*handshaker)); @@ -314,6 +326,14 @@ grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server) { gpr_mu_init(&handshaker->mu); gpr_ref_init(&handshaker->refcount, 1); handshaker->proxy_server = gpr_strdup(proxy_server); + if (num_headers > 0) { + handshaker->headers = gpr_malloc(sizeof(grpc_http_header) * num_headers); + for (size_t i = 0; i < num_headers; ++i) { + handshaker->headers[i].key = gpr_strdup(headers[i].key); + handshaker->headers[i].value = gpr_strdup(headers[i].value); + } + handshaker->num_headers = num_headers; + } grpc_slice_buffer_init(&handshaker->write_buffer); grpc_closure_init(&handshaker->request_done_closure, on_write_done, handshaker, grpc_schedule_on_exec_ctx); @@ -347,3 +367,33 @@ done: grpc_uri_destroy(uri); return proxy_name; } + +// +// handshaker factory +// + +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(); + if (proxy_name != NULL) { + grpc_handshake_manager_add( + handshake_mgr, + grpc_http_connect_handshaker_create(proxy_name, NULL, 0)); + gpr_free(proxy_name); + } +} + +static void handshaker_factory_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshaker_factory* factory) {} + +static const grpc_handshaker_factory_vtable handshaker_factory_vtable = { + handshaker_factory_add_handshakers, handshaker_factory_destroy}; + +static grpc_handshaker_factory handshaker_factory = { + &handshaker_factory_vtable}; + +void grpc_http_connect_register_handshaker_factory() { + grpc_handshaker_factory_register(true /* at_start */, HANDSHAKER_CLIENT, + &handshaker_factory); +} diff --git a/src/core/ext/client_channel/http_connect_handshaker.h b/src/core/ext/client_channel/http_connect_handshaker.h index ea293852e6..c2e68de716 100644 --- a/src/core/ext/client_channel/http_connect_handshaker.h +++ b/src/core/ext/client_channel/http_connect_handshaker.h @@ -35,12 +35,18 @@ #define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/http/parser.h" -/// Does NOT take ownership of \a proxy_server. -grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server); +/// Creates a new HTTP CONNECT handshaker. +grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server, + grpc_http_header* headers, + size_t num_headers); /// Returns the name of the proxy to use, or NULL if no proxy is configured. /// Caller takes ownership of result. char* grpc_get_http_proxy_server(); +/// Registers handshaker factory. +void grpc_http_connect_register_handshaker_factory(); + #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_CONNECT_HANDSHAKER_H */ diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c index bb2b012507..655d9dc586 100644 --- a/src/core/ext/resolver/dns/native/dns_resolver.c +++ b/src/core/ext/resolver/dns/native/dns_resolver.c @@ -189,7 +189,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now); gpr_timespec timeout = gpr_time_sub(next_try, now); const char *msg = grpc_error_string(error); - gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg); + gpr_log(GPR_INFO, "dns resolution failed (will retry): %s", msg); grpc_error_free_string(msg); GPR_ASSERT(!r->have_retry_timer); r->have_retry_timer = true; diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c index 2385f91dbd..2c5dfaea60 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.c +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c @@ -46,6 +46,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/slice/slice_internal.h" @@ -58,9 +59,6 @@ typedef struct { bool shutdown; bool connecting; - grpc_chttp2_add_handshakers_func add_handshakers; - void *add_handshakers_user_data; - grpc_closure *notify; grpc_connect_in_args args; grpc_connect_out_args *result; @@ -151,16 +149,8 @@ static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, static void start_handshake_locked(grpc_exec_ctx *exec_ctx, chttp2_connector *c) { c->handshake_mgr = grpc_handshake_manager_create(); - char *proxy_name = grpc_get_http_proxy_server(); - if (proxy_name != NULL) { - grpc_handshake_manager_add(c->handshake_mgr, - grpc_http_connect_handshaker_create(proxy_name)); - gpr_free(proxy_name); - } - if (c->add_handshakers != NULL) { - c->add_handshakers(exec_ctx, c->add_handshakers_user_data, + grpc_handshakers_add(exec_ctx, HANDSHAKER_CLIENT, c->args.channel_args, c->handshake_mgr); - } grpc_handshake_manager_do_handshake( exec_ctx, c->handshake_mgr, c->endpoint, c->args.channel_args, c->args.deadline, NULL /* acceptor */, on_handshake_done, c); @@ -250,15 +240,11 @@ static const grpc_connector_vtable chttp2_connector_vtable = { chttp2_connector_ref, chttp2_connector_unref, chttp2_connector_shutdown, chttp2_connector_connect}; -grpc_connector *grpc_chttp2_connector_create( - grpc_exec_ctx *exec_ctx, grpc_chttp2_add_handshakers_func add_handshakers, - void *add_handshakers_user_data) { +grpc_connector *grpc_chttp2_connector_create() { chttp2_connector *c = gpr_malloc(sizeof(*c)); memset(c, 0, sizeof(*c)); c->base.vtable = &chttp2_connector_vtable; gpr_mu_init(&c->mu); gpr_ref_init(&c->refs, 1); - c->add_handshakers = add_handshakers; - c->add_handshakers_user_data = add_handshakers_user_data; return &c->base; } diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.h b/src/core/ext/transport/chttp2/client/chttp2_connector.h index 58eba22417..f5d1025432 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.h +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.h @@ -35,17 +35,7 @@ #define GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H #include "src/core/ext/client_channel/connector.h" -#include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/iomgr/exec_ctx.h" -typedef void (*grpc_chttp2_add_handshakers_func)( - grpc_exec_ctx* exec_ctx, void* user_data, - grpc_handshake_manager* handshake_mgr); - -/// If \a add_handshakers is non-NULL, it will be called with -/// \a add_handshakers_user_data to add handshakers. -grpc_connector* grpc_chttp2_connector_create( - grpc_exec_ctx* exec_ctx, grpc_chttp2_add_handshakers_func add_handshakers, - void* add_handshakers_user_data); +grpc_connector* grpc_chttp2_connector_create(); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H */ diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 1d3592ef06..c9f4021216 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -53,8 +53,7 @@ static void client_channel_factory_unref( static grpc_subchannel *client_channel_factory_create_subchannel( grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory, const grpc_subchannel_args *args) { - grpc_connector *connector = grpc_chttp2_connector_create( - exec_ctx, NULL /* add_handshakers */, NULL /* user_data */); + grpc_connector *connector = grpc_chttp2_connector_create(); grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args); grpc_connector_unref(exec_ctx, connector); return s; @@ -96,17 +95,16 @@ grpc_channel *grpc_insecure_channel_create(const char *target, "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3, (target, args, reserved)); GPR_ASSERT(reserved == NULL); - grpc_client_channel_factory *factory = - (grpc_client_channel_factory *)&client_channel_factory; // Add channel arg containing the client channel factory. - grpc_arg arg = grpc_client_channel_factory_create_channel_arg(factory); + grpc_arg arg = + grpc_client_channel_factory_create_channel_arg(&client_channel_factory); grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1); // Create channel. grpc_channel *channel = client_channel_factory_create_channel( - &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args); + &exec_ctx, &client_channel_factory, target, + GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args); // Clean up. grpc_channel_args_destroy(&exec_ctx, new_args); - grpc_client_channel_factory_unref(&exec_ctx, factory); grpc_exec_ctx_finish(&exec_ctx); return channel != NULL ? channel : grpc_lame_client_channel_create( target, GRPC_STATUS_INTERNAL, diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 54663ef6a4..f979d9bad5 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -46,40 +46,16 @@ #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/channel.h" -typedef struct { - grpc_client_channel_factory base; - gpr_refcount refs; - grpc_channel_security_connector *security_connector; -} client_channel_factory; - static void client_channel_factory_ref( - grpc_client_channel_factory *cc_factory) { - client_channel_factory *f = (client_channel_factory *)cc_factory; - gpr_ref(&f->refs); -} + grpc_client_channel_factory *cc_factory) {} static void client_channel_factory_unref( - grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) { - client_channel_factory *f = (client_channel_factory *)cc_factory; - if (gpr_unref(&f->refs)) { - GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &f->security_connector->base, - "client_channel_factory"); - gpr_free(f); - } -} - -static void add_handshakers(grpc_exec_ctx *exec_ctx, void *security_connector, - grpc_handshake_manager *handshake_mgr) { - grpc_channel_security_connector_add_handshakers(exec_ctx, security_connector, - handshake_mgr); -} + grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {} static grpc_subchannel *client_channel_factory_create_subchannel( grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory, const grpc_subchannel_args *args) { - client_channel_factory *f = (client_channel_factory *)cc_factory; - grpc_connector *connector = grpc_chttp2_connector_create( - exec_ctx, add_handshakers, f->security_connector); + grpc_connector *connector = grpc_chttp2_connector_create(); grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args); grpc_connector_unref(exec_ctx, connector); return s; @@ -106,6 +82,9 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable = client_channel_factory_create_subchannel, client_channel_factory_create_channel}; +static grpc_client_channel_factory client_channel_factory = { + &client_channel_factory_vtable}; + /* Create a secure client channel: Asynchronously: - resolve target - connect to it (trying alternatives as presented) @@ -138,33 +117,26 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds, return grpc_lame_client_channel_create( target, GRPC_STATUS_INTERNAL, "Failed to create security connector."); } - // Create client channel factory. - client_channel_factory *f = gpr_malloc(sizeof(*f)); - memset(f, 0, sizeof(*f)); - f->base.vtable = &client_channel_factory_vtable; - gpr_ref_init(&f->refs, 1); - GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, - "grpc_secure_channel_create"); - f->security_connector = security_connector; // Add channel args containing the client channel factory and security // connector. - grpc_arg new_args[2]; - new_args[0] = grpc_client_channel_factory_create_channel_arg(&f->base); - new_args[1] = grpc_security_connector_to_arg(&security_connector->base); - grpc_channel_args *args_copy = grpc_channel_args_copy_and_add( + grpc_arg args_to_add[2]; + args_to_add[0] = + grpc_client_channel_factory_create_channel_arg(&client_channel_factory); + args_to_add[1] = grpc_security_connector_to_arg(&security_connector->base); + grpc_channel_args *new_args = grpc_channel_args_copy_and_add( new_args_from_connector != NULL ? new_args_from_connector : args, - new_args, GPR_ARRAY_SIZE(new_args)); + args_to_add, GPR_ARRAY_SIZE(args_to_add)); if (new_args_from_connector != NULL) { grpc_channel_args_destroy(&exec_ctx, new_args_from_connector); } // Create channel. grpc_channel *channel = client_channel_factory_create_channel( - &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy); + &exec_ctx, &client_channel_factory, target, + GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args); // Clean up. - GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &f->security_connector->base, + GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &security_connector->base, "secure_client_channel_factory_create_channel"); - grpc_channel_args_destroy(&exec_ctx, args_copy); - grpc_client_channel_factory_unref(&exec_ctx, &f->base); + grpc_channel_args_destroy(&exec_ctx, new_args); grpc_exec_ctx_finish(&exec_ctx); return channel; /* may be NULL */ } diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c index 86f5a198c2..574d1a7710 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.c +++ b/src/core/ext/transport/chttp2/server/chttp2_server.c @@ -46,6 +46,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -54,24 +55,6 @@ #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/server.h" -void grpc_chttp2_server_handshaker_factory_add_handshakers( - grpc_exec_ctx *exec_ctx, - grpc_chttp2_server_handshaker_factory *handshaker_factory, - grpc_handshake_manager *handshake_mgr) { - if (handshaker_factory != NULL) { - handshaker_factory->vtable->add_handshakers(exec_ctx, handshaker_factory, - handshake_mgr); - } -} - -void grpc_chttp2_server_handshaker_factory_destroy( - grpc_exec_ctx *exec_ctx, - grpc_chttp2_server_handshaker_factory *handshaker_factory) { - if (handshaker_factory != NULL) { - handshaker_factory->vtable->destroy(exec_ctx, handshaker_factory); - } -} - typedef struct pending_handshake_manager_node { grpc_handshake_manager *handshake_mgr; struct pending_handshake_manager_node *next; @@ -81,7 +64,6 @@ typedef struct { grpc_server *server; grpc_tcp_server *tcp_server; grpc_channel_args *args; - grpc_chttp2_server_handshaker_factory *handshaker_factory; gpr_mu mu; bool shutdown; grpc_closure tcp_server_shutdown_complete; @@ -198,8 +180,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp, connection_state->accepting_pollset = accepting_pollset; connection_state->acceptor = acceptor; connection_state->handshake_mgr = handshake_mgr; - grpc_chttp2_server_handshaker_factory_add_handshakers( - exec_ctx, state->handshaker_factory, connection_state->handshake_mgr); + grpc_handshakers_add(exec_ctx, HANDSHAKER_SERVER, state->args, + connection_state->handshake_mgr); // TODO(roth): We should really get this timeout value from channel // args instead of hard-coding it. const gpr_timespec deadline = gpr_time_add( @@ -233,8 +215,6 @@ static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *arg, // Flush queued work before destroying handshaker factory, since that // may do a synchronous unref. grpc_exec_ctx_flush(exec_ctx); - grpc_chttp2_server_handshaker_factory_destroy(exec_ctx, - state->handshaker_factory); if (destroy_done != NULL) { destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error)); grpc_exec_ctx_flush(exec_ctx); @@ -259,10 +239,10 @@ static void server_destroy_listener(grpc_exec_ctx *exec_ctx, grpc_tcp_server_unref(exec_ctx, tcp_server); } -grpc_error *grpc_chttp2_server_add_port( - grpc_exec_ctx *exec_ctx, grpc_server *server, const char *addr, - grpc_channel_args *args, - grpc_chttp2_server_handshaker_factory *handshaker_factory, int *port_num) { +grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx, + grpc_server *server, const char *addr, + grpc_channel_args *args, + int *port_num) { grpc_resolved_addresses *resolved = NULL; grpc_tcp_server *tcp_server = NULL; size_t i; @@ -293,7 +273,6 @@ grpc_error *grpc_chttp2_server_add_port( state->server = server; state->tcp_server = tcp_server; state->args = args; - state->handshaker_factory = handshaker_factory; state->shutdown = true; gpr_mu_init(&state->mu); @@ -348,7 +327,6 @@ error: grpc_tcp_server_unref(exec_ctx, tcp_server); } else { grpc_channel_args_destroy(exec_ctx, args); - grpc_chttp2_server_handshaker_factory_destroy(exec_ctx, handshaker_factory); gpr_free(state); } *port_num = 0; diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.h b/src/core/ext/transport/chttp2/server/chttp2_server.h index aa364b565d..2581ebaae9 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.h +++ b/src/core/ext/transport/chttp2/server/chttp2_server.h @@ -36,43 +36,12 @@ #include <grpc/impl/codegen/grpc_types.h> -#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/iomgr/exec_ctx.h" -/// A server handshaker factory is used to create handshakers for server -/// connections. -typedef struct grpc_chttp2_server_handshaker_factory - grpc_chttp2_server_handshaker_factory; - -typedef struct { - void (*add_handshakers)( - grpc_exec_ctx *exec_ctx, - grpc_chttp2_server_handshaker_factory *handshaker_factory, - grpc_handshake_manager *handshake_mgr); - void (*destroy)(grpc_exec_ctx *exec_ctx, - grpc_chttp2_server_handshaker_factory *handshaker_factory); -} grpc_chttp2_server_handshaker_factory_vtable; - -struct grpc_chttp2_server_handshaker_factory { - const grpc_chttp2_server_handshaker_factory_vtable *vtable; -}; - -void grpc_chttp2_server_handshaker_factory_add_handshakers( - grpc_exec_ctx *exec_ctx, - grpc_chttp2_server_handshaker_factory *handshaker_factory, - grpc_handshake_manager *handshake_mgr); - -void grpc_chttp2_server_handshaker_factory_destroy( - grpc_exec_ctx *exec_ctx, - grpc_chttp2_server_handshaker_factory *handshaker_factory); - /// Adds a port to \a server. Sets \a port_num to the port number. -/// If \a handshaker_factory is not NULL, it will be used to create -/// handshakers for the port. -/// Takes ownership of \a args and \a handshaker_factory. -grpc_error *grpc_chttp2_server_add_port( - grpc_exec_ctx *exec_ctx, grpc_server *server, const char *addr, - grpc_channel_args *args, - grpc_chttp2_server_handshaker_factory *handshaker_factory, int *port_num); +/// Takes ownership of \a args. +grpc_error *grpc_chttp2_server_add_port(grpc_exec_ctx *exec_ctx, + grpc_server *server, const char *addr, + grpc_channel_args *args, int *port_num); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H */ diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index 7e286d4e46..bf5026bea6 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -47,8 +47,7 @@ int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) { (server, addr)); grpc_error *err = grpc_chttp2_server_add_port( &exec_ctx, server, addr, - grpc_channel_args_copy(grpc_server_get_channel_args(server)), - NULL /* handshaker_factory */, &port_num); + grpc_channel_args_copy(grpc_server_get_channel_args(server)), &port_num); if (err != GRPC_ERROR_NONE) { const char *msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index b5e4996b16..395c79a71d 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -49,34 +49,6 @@ #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/server.h" -typedef struct { - grpc_chttp2_server_handshaker_factory base; - grpc_server_security_connector *security_connector; -} server_security_handshaker_factory; - -static void server_security_handshaker_factory_add_handshakers( - grpc_exec_ctx *exec_ctx, grpc_chttp2_server_handshaker_factory *hf, - grpc_handshake_manager *handshake_mgr) { - server_security_handshaker_factory *handshaker_factory = - (server_security_handshaker_factory *)hf; - grpc_server_security_connector_add_handshakers( - exec_ctx, handshaker_factory->security_connector, handshake_mgr); -} - -static void server_security_handshaker_factory_destroy( - grpc_exec_ctx *exec_ctx, grpc_chttp2_server_handshaker_factory *hf) { - server_security_handshaker_factory *handshaker_factory = - (server_security_handshaker_factory *)hf; - GRPC_SECURITY_CONNECTOR_UNREF( - exec_ctx, &handshaker_factory->security_connector->base, "server"); - gpr_free(hf); -} - -static const grpc_chttp2_server_handshaker_factory_vtable - server_security_handshaker_factory_vtable = { - server_security_handshaker_factory_add_handshakers, - server_security_handshaker_factory_destroy}; - int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; @@ -105,20 +77,19 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, gpr_free(msg); goto done; } - // Create handshaker factory. - server_security_handshaker_factory *handshaker_factory = - gpr_malloc(sizeof(*handshaker_factory)); - memset(handshaker_factory, 0, sizeof(*handshaker_factory)); - handshaker_factory->base.vtable = &server_security_handshaker_factory_vtable; - handshaker_factory->security_connector = sc; // Create channel args. - grpc_arg channel_arg = grpc_server_credentials_to_arg(creds); - grpc_channel_args *args = grpc_channel_args_copy_and_add( - grpc_server_get_channel_args(server), &channel_arg, 1); + grpc_arg args_to_add[2]; + args_to_add[0] = grpc_server_credentials_to_arg(creds); + args_to_add[1] = grpc_security_connector_to_arg(&sc->base); + grpc_channel_args *args = + grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server), + args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Add server port. - err = grpc_chttp2_server_add_port(&exec_ctx, server, addr, args, - &handshaker_factory->base, &port_num); + err = grpc_chttp2_server_add_port(&exec_ctx, server, addr, args, &port_num); done: + if (sc != NULL) { + GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "server"); + } grpc_exec_ctx_finish(&exec_ctx); if (err != GRPC_ERROR_NONE) { const char *msg = grpc_error_string(err); diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c index b4c5ed769b..20043f5fbf 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.c @@ -109,7 +109,7 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx, (((uint32_t)p->reason_bytes[2]) << 8) | (((uint32_t)p->reason_bytes[3])); grpc_error *error = GRPC_ERROR_NONE; - if (reason != GRPC_CHTTP2_NO_ERROR) { + if (reason != GRPC_CHTTP2_NO_ERROR || s->header_frames_received < 2) { error = grpc_error_set_int(GRPC_ERROR_CREATE("RST_STREAM"), GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason); grpc_status_code status_code = grpc_chttp2_http2_error_to_grpc_status( diff --git a/src/core/lib/channel/handshaker_factory.c b/src/core/lib/channel/handshaker_factory.c new file mode 100644 index 0000000000..3c30a4e1d2 --- /dev/null +++ b/src/core/lib/channel/handshaker_factory.c @@ -0,0 +1,54 @@ +/* + * + * Copyright 2016, 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 "src/core/lib/channel/handshaker_factory.h" + +#include <grpc/support/log.h> + +void grpc_handshaker_factory_add_handshakers( + grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory, + const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) { + if (handshaker_factory != NULL) { + GPR_ASSERT(handshaker_factory->vtable != NULL); + handshaker_factory->vtable->add_handshakers(exec_ctx, handshaker_factory, + args, handshake_mgr); + } +} + +void grpc_handshaker_factory_destroy( + grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory) { + if (handshaker_factory != NULL) { + GPR_ASSERT(handshaker_factory->vtable != NULL); + handshaker_factory->vtable->destroy(exec_ctx, handshaker_factory); + } +} diff --git a/src/core/lib/channel/handshaker_factory.h b/src/core/lib/channel/handshaker_factory.h new file mode 100644 index 0000000000..1984546104 --- /dev/null +++ b/src/core/lib/channel/handshaker_factory.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2016, 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. + * + */ + +#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H +#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H + +#include <grpc/impl/codegen/grpc_types.h> + +#include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/iomgr/exec_ctx.h" + +// A handshaker factory is used to create handshakers. + +typedef struct grpc_handshaker_factory grpc_handshaker_factory; + +typedef struct { + void (*add_handshakers)(grpc_exec_ctx *exec_ctx, + grpc_handshaker_factory *handshaker_factory, + const grpc_channel_args *args, + grpc_handshake_manager *handshake_mgr); + void (*destroy)(grpc_exec_ctx *exec_ctx, + grpc_handshaker_factory *handshaker_factory); +} grpc_handshaker_factory_vtable; + +struct grpc_handshaker_factory { + const grpc_handshaker_factory_vtable *vtable; +}; + +void grpc_handshaker_factory_add_handshakers( + grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory, + const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr); + +void grpc_handshaker_factory_destroy( + grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory); + +#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H */ diff --git a/src/core/lib/channel/handshaker_registry.c b/src/core/lib/channel/handshaker_registry.c new file mode 100644 index 0000000000..2e5f04064c --- /dev/null +++ b/src/core/lib/channel/handshaker_registry.c @@ -0,0 +1,113 @@ +/* + * + * Copyright 2016, 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 "src/core/lib/channel/handshaker_registry.h" + +#include <string.h> + +#include <grpc/support/alloc.h> + +// +// grpc_handshaker_factory_list +// + +typedef struct { + grpc_handshaker_factory** list; + size_t num_factories; +} grpc_handshaker_factory_list; + +static void grpc_handshaker_factory_list_register( + grpc_handshaker_factory_list* list, bool at_start, + grpc_handshaker_factory* factory) { + list->list = gpr_realloc( + list->list, (list->num_factories + 1) * sizeof(grpc_handshaker_factory*)); + if (at_start) { + memmove(list->list + 1, list->list, + sizeof(grpc_handshaker_factory*) * list->num_factories); + list->list[0] = factory; + } else { + list->list[list->num_factories] = factory; + } + ++list->num_factories; +} + +static void grpc_handshaker_factory_list_add_handshakers( + grpc_exec_ctx* exec_ctx, grpc_handshaker_factory_list* list, + const grpc_channel_args* args, grpc_handshake_manager* handshake_mgr) { + for (size_t i = 0; i < list->num_factories; ++i) { + grpc_handshaker_factory_add_handshakers(exec_ctx, list->list[i], args, + handshake_mgr); + } +} + +static void grpc_handshaker_factory_list_destroy( + grpc_exec_ctx* exec_ctx, grpc_handshaker_factory_list* list) { + for (size_t i = 0; i < list->num_factories; ++i) { + grpc_handshaker_factory_destroy(exec_ctx, list->list[i]); + } + gpr_free(list->list); +} + +// +// plugin +// + +static grpc_handshaker_factory_list + g_handshaker_factory_lists[NUM_HANDSHAKER_TYPES]; + +void grpc_handshaker_factory_registry_init() { + memset(g_handshaker_factory_lists, 0, sizeof(g_handshaker_factory_lists)); +} + +void grpc_handshaker_factory_registry_shutdown(grpc_exec_ctx* exec_ctx) { + for (size_t i = 0; i < NUM_HANDSHAKER_TYPES; ++i) { + grpc_handshaker_factory_list_destroy(exec_ctx, + &g_handshaker_factory_lists[i]); + } +} + +void grpc_handshaker_factory_register(bool at_start, + grpc_handshaker_type handshaker_type, + grpc_handshaker_factory* factory) { + grpc_handshaker_factory_list_register( + &g_handshaker_factory_lists[handshaker_type], at_start, factory); +} + +void grpc_handshakers_add(grpc_exec_ctx* exec_ctx, + grpc_handshaker_type handshaker_type, + const grpc_channel_args* args, + grpc_handshake_manager* handshake_mgr) { + grpc_handshaker_factory_list_add_handshakers( + exec_ctx, &g_handshaker_factory_lists[handshaker_type], args, + handshake_mgr); +} diff --git a/src/core/lib/channel/handshaker_registry.h b/src/core/lib/channel/handshaker_registry.h new file mode 100644 index 0000000000..53c1b173af --- /dev/null +++ b/src/core/lib/channel/handshaker_registry.h @@ -0,0 +1,63 @@ +/* + * + * Copyright 2016, 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. + * + */ + +#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H +#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H + +#include <grpc/impl/codegen/grpc_types.h> + +#include "src/core/lib/channel/handshaker_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" + +typedef enum { + HANDSHAKER_CLIENT = 0, + HANDSHAKER_SERVER, + NUM_HANDSHAKER_TYPES, // Must be last. +} grpc_handshaker_type; + +void grpc_handshaker_factory_registry_init(); +void grpc_handshaker_factory_registry_shutdown(grpc_exec_ctx* exec_ctx); + +/// Registers a new handshaker factory. Takes ownership. +/// If \a at_start is true, the new handshaker will be at the beginning of +/// the list. Otherwise, it will be added to the end. +void grpc_handshaker_factory_register(bool at_start, + grpc_handshaker_type handshaker_type, + grpc_handshaker_factory* factory); + +void grpc_handshakers_add(grpc_exec_ctx* exec_ctx, + grpc_handshaker_type handshaker_type, + const grpc_channel_args* args, + grpc_handshake_manager* handshake_mgr); + +#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H */ diff --git a/src/core/lib/iomgr/iocp_windows.c b/src/core/lib/iomgr/iocp_windows.c index 60ebe43676..f0f4a6ff39 100644 --- a/src/core/lib/iomgr/iocp_windows.c +++ b/src/core/lib/iomgr/iocp_windows.c @@ -80,7 +80,6 @@ grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx, LPOVERLAPPED overlapped; grpc_winsocket *socket; grpc_winsocket_callback_info *info; - grpc_closure *closure = NULL; success = GetQueuedCompletionStatus( g_iocp, &bytes, &completion_key, &overlapped, deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type))); diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c index 97d7827461..dafe851ce8 100644 --- a/src/core/lib/iomgr/tcp_server_windows.c +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -184,7 +184,6 @@ void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, } static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { - int immediately_done = 0; grpc_tcp_listener *sp; gpr_mu_lock(&s->mu); @@ -240,7 +239,7 @@ static grpc_error *prepare_socket(SOCKET sock, error = GRPC_WSA_ERROR(WSAGetLastError(), "getsockname"); goto failure; } - sockname_temp.len = sockname_temp_len; + sockname_temp.len = (size_t)sockname_temp_len; *port = grpc_sockaddr_get_port(&sockname_temp); return GRPC_ERROR_NONE; @@ -248,7 +247,7 @@ static grpc_error *prepare_socket(SOCKET sock, failure: GPR_ASSERT(error != GRPC_ERROR_NONE); char *tgtaddr = grpc_sockaddr_to_uri(addr); - grpc_error *final_error = grpc_error_set_int( + grpc_error_set_int( grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING( "Failed to prepare server socket", &error, 1), GRPC_ERROR_STR_TARGET_ADDRESS, tgtaddr), @@ -261,7 +260,6 @@ failure: static void decrement_active_ports_and_notify_locked(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *sp) { - int notify = 0; sp->shutting_down = 0; GPR_ASSERT(sp->server->active_ports > 0); if (0 == --sp->server->active_ports) { @@ -375,7 +373,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { int peer_name_len = (int)peer_name.len; err = getpeername(sock, (struct sockaddr *)peer_name.addr, &peer_name_len); - peer_name.len = peer_name_len; + peer_name.len = (size_t)peer_name_len; if (!err) { peer_name_string = grpc_sockaddr_to_uri(&peer_name); } else { @@ -498,7 +496,7 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s, if (0 == getsockname(sp->socket->socket, (struct sockaddr *)sockname_temp.addr, &sockname_temp_len)) { - sockname_temp.len = sockname_temp_len; + sockname_temp.len = (size_t)sockname_temp_len; *port = grpc_sockaddr_get_port(&sockname_temp); if (*port > 0) { allocated_addr = gpr_malloc(sizeof(grpc_resolved_address)); diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c index e886cc59a0..5e75856c7a 100644 --- a/src/core/lib/security/transport/security_handshaker.c +++ b/src/core/lib/security/transport/security_handshaker.c @@ -42,6 +42,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/tsi_error.h" @@ -438,6 +439,45 @@ static grpc_handshaker *fail_handshaker_create() { } // +// handshaker factories +// + +static void client_handshaker_factory_add_handshakers( + grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory, + const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) { + grpc_channel_security_connector *security_connector = + (grpc_channel_security_connector *)grpc_find_security_connector_in_args( + args); + grpc_channel_security_connector_add_handshakers(exec_ctx, security_connector, + handshake_mgr); +} + +static void server_handshaker_factory_add_handshakers( + grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *hf, + const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) { + grpc_server_security_connector *security_connector = + (grpc_server_security_connector *)grpc_find_security_connector_in_args( + args); + grpc_server_security_connector_add_handshakers(exec_ctx, security_connector, + handshake_mgr); +} + +static void handshaker_factory_destroy( + grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory) {} + +static const grpc_handshaker_factory_vtable client_handshaker_factory_vtable = { + client_handshaker_factory_add_handshakers, handshaker_factory_destroy}; + +static grpc_handshaker_factory client_handshaker_factory = { + &client_handshaker_factory_vtable}; + +static const grpc_handshaker_factory_vtable server_handshaker_factory_vtable = { + server_handshaker_factory_add_handshakers, handshaker_factory_destroy}; + +static grpc_handshaker_factory server_handshaker_factory = { + &server_handshaker_factory_vtable}; + +// // exported functions // @@ -452,3 +492,10 @@ grpc_handshaker *grpc_security_handshaker_create( return security_handshaker_create(exec_ctx, handshaker, connector); } } + +void grpc_security_register_handshaker_factories() { + grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_CLIENT, + &client_handshaker_factory); + grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_SERVER, + &server_handshaker_factory); +} diff --git a/src/core/lib/security/transport/security_handshaker.h b/src/core/lib/security/transport/security_handshaker.h index 5ddbf4b451..0b9eda178f 100644 --- a/src/core/lib/security/transport/security_handshaker.h +++ b/src/core/lib/security/transport/security_handshaker.h @@ -43,4 +43,7 @@ grpc_handshaker *grpc_security_handshaker_create( grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, grpc_security_connector *connector); +/// Registers security handshaker factories. +void grpc_security_register_handshaker_factories(); + #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H */ diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index e20e602547..f61bf1582e 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -44,6 +44,7 @@ #include "src/core/lib/channel/compress_filter.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/channel/deadline_filter.h" +#include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/channel/http_client_filter.h" #include "src/core/lib/channel/http_server_filter.h" #include "src/core/lib/channel/message_size_filter.h" @@ -204,6 +205,8 @@ void grpc_init(void) { grpc_executor_init(); gpr_timers_global_init(); grpc_cq_global_init(); + grpc_handshaker_factory_registry_init(); + grpc_security_init(); for (i = 0; i < g_number_of_plugins; i++) { if (g_all_of_the_plugins[i].init != NULL) { g_all_of_the_plugins[i].init(); @@ -238,6 +241,7 @@ void grpc_shutdown(void) { } } grpc_mdctx_global_shutdown(&exec_ctx); + grpc_handshaker_factory_registry_shutdown(&exec_ctx); } gpr_mu_unlock(&g_init_mu); grpc_exec_ctx_finish(&exec_ctx); diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index b1bf57c10d..3d1c528be0 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -36,6 +36,7 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); +void grpc_security_init(void); int grpc_is_initialized(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c index 520a8aa84f..a44407d3bb 100644 --- a/src/core/lib/surface/init_secure.c +++ b/src/core/lib/surface/init_secure.c @@ -41,6 +41,7 @@ #include "src/core/lib/security/transport/auth_filters.h" #include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/security_connector.h" +#include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/tsi/transport_security_interface.h" @@ -87,3 +88,5 @@ void grpc_register_security_filters(void) { grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, maybe_prepend_server_auth_filter, NULL); } + +void grpc_security_init() { grpc_security_register_handshaker_factories(); } diff --git a/src/core/lib/surface/init_unsecure.c b/src/core/lib/surface/init_unsecure.c index f952739e0a..dbc9223ae0 100644 --- a/src/core/lib/surface/init_unsecure.c +++ b/src/core/lib/surface/init_unsecure.c @@ -36,3 +36,5 @@ void grpc_security_pre_init(void) {} void grpc_register_security_filters(void) {} + +void grpc_security_init(void) {} diff --git a/src/php/bin/generate_proto_php.sh b/src/php/bin/generate_proto_php.sh index c558bc5769..416fa9df97 100755 --- a/src/php/bin/generate_proto_php.sh +++ b/src/php/bin/generate_proto_php.sh @@ -39,10 +39,13 @@ protoc --proto_path=src/proto/math \ # replace the Empty message with EmptyMessage # because Empty is a PHP reserved word -sed -i 's/message Empty/message EmptyMessage/g' \ - src/proto/grpc/testing/empty.proto -sed -i 's/grpc\.testing\.Empty/grpc\.testing\.EmptyMessage/g' \ - src/proto/grpc/testing/test.proto +output_file=$(mktemp) +sed 's/message Empty/message EmptyMessage/g' \ + src/proto/grpc/testing/empty.proto > $output_file +mv $output_file ./src/proto/grpc/testing/empty.proto +sed 's/grpc\.testing\.Empty/grpc\.testing\.EmptyMessage/g' \ + src/proto/grpc/testing/test.proto > $output_file +mv $output_file ./src/proto/grpc/testing/test.proto protoc --proto_path=. \ --php_out=src/php/tests/interop \ @@ -53,7 +56,10 @@ protoc --proto_path=. \ src/proto/grpc/testing/test.proto # change it back -sed -i 's/message EmptyMessage/message Empty/g' \ - src/proto/grpc/testing/empty.proto -sed -i 's/grpc\.testing\.EmptyMessage/grpc\.testing\.Empty/g' \ - src/proto/grpc/testing/test.proto +sed 's/message EmptyMessage/message Empty/g' \ + src/proto/grpc/testing/empty.proto > $output_file +mv $output_file ./src/proto/grpc/testing/empty.proto +sed 's/grpc\.testing\.EmptyMessage/grpc\.testing\.Empty/g' \ + src/proto/grpc/testing/test.proto > $output_file +mv $output_file ./src/proto/grpc/testing/test.proto + diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 3a49ea8708..64b1137c2a 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -478,6 +478,7 @@ PHP_METHOD(Call, startBatch) { true); add_property_zval(result, "status", recv_status); PHP_GRPC_DELREF(recv_status); + PHP_GRPC_FREE_STD_ZVAL(recv_status); break; case GRPC_OP_RECV_CLOSE_ON_SERVER: add_property_bool(result, "cancelled", cancelled); @@ -501,6 +502,7 @@ cleanup: } if (ops[i].op == GRPC_OP_RECV_MESSAGE) { grpc_byte_buffer_destroy(message); + PHP_GRPC_FREE_STD_ZVAL(message_str); } } RETURN_DESTROY_ZVAL(result); diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c index 3aafc3a19b..043817facd 100644 --- a/src/php/ext/grpc/call_credentials.c +++ b/src/php/ext/grpc/call_credentials.c @@ -111,9 +111,7 @@ PHP_METHOD(CallCredentials, createComposite) { grpc_call_credentials *creds = grpc_composite_call_credentials_create(cred1->wrapped, cred2->wrapped, NULL); - zval *creds_object; - PHP_GRPC_MAKE_STD_ZVAL(creds_object); - creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); + zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -155,9 +153,7 @@ PHP_METHOD(CallCredentials, createFromPlugin) { grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL); - zval *creds_object; - PHP_GRPC_MAKE_STD_ZVAL(creds_object); - creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); + zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -211,6 +207,8 @@ void plugin_destroy_state(void *ptr) { plugin_state *state = (plugin_state *)ptr; efree(state->fci); efree(state->fci_cache); + PHP_GRPC_FREE_STD_ZVAL(state->fci->params); + PHP_GRPC_FREE_STD_ZVAL(state->fci->retval); efree(state); } diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index a32c4a4ea2..36a8223b88 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -121,9 +121,7 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { */ PHP_METHOD(ChannelCredentials, createDefault) { grpc_channel_credentials *creds = grpc_google_default_credentials_create(); - zval *creds_object; - PHP_GRPC_MAKE_STD_ZVAL(creds_object); - creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); + zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -160,9 +158,7 @@ PHP_METHOD(ChannelCredentials, createSsl) { grpc_channel_credentials *creds = grpc_ssl_credentials_create( pem_root_certs, pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL); - zval *creds_object; - PHP_GRPC_MAKE_STD_ZVAL(creds_object); - creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); + zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -191,9 +187,7 @@ PHP_METHOD(ChannelCredentials, createComposite) { grpc_channel_credentials *creds = grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped, NULL); - zval *creds_object; - PHP_GRPC_MAKE_STD_ZVAL(creds_object); - creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); + zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h index 1d7824113f..72e982d6fc 100644 --- a/src/php/ext/grpc/php7_wrapper.h +++ b/src/php/ext/grpc/php7_wrapper.h @@ -50,8 +50,13 @@ #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val, dup) #define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv) +#define PHP_GRPC_FREE_STD_ZVAL(pzv) #define PHP_GRPC_DELREF(zv) Z_DELREF_P(zv) +#define RETURN_DESTROY_ZVAL(val) \ + RETURN_ZVAL(val, false /* Don't execute copy constructor */, \ + true /* Dealloc original before returning */) + #define PHP_GRPC_WRAP_OBJECT_START(name) \ typedef struct name { \ zend_object std; @@ -144,8 +149,15 @@ static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len, #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val) #define PHP_GRPC_MAKE_STD_ZVAL(pzv) \ pzv = (zval *)emalloc(sizeof(zval)); +#define PHP_GRPC_FREE_STD_ZVAL(pzv) efree(pzv); #define PHP_GRPC_DELREF(zv) +#define RETURN_DESTROY_ZVAL(val) \ + RETVAL_ZVAL(val, false /* Don't execute copy constructor */, \ + true /* Dealloc original before returning */); \ + efree(val); \ + return + #define PHP_GRPC_WRAP_OBJECT_START(name) \ typedef struct name { #define PHP_GRPC_WRAP_OBJECT_END(name) \ diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index e57a06545e..13083b0bc7 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -61,10 +61,6 @@ extern zend_module_entry grpc_module_entry; #include "grpc/grpc.h" -#define RETURN_DESTROY_ZVAL(val) \ - RETURN_ZVAL(val, false /* Don't execute copy constructor */, \ - true /* Dealloc original before returning */) - /* These are all function declarations */ /* Code that runs at module initialization */ PHP_MINIT_FUNCTION(grpc); diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index 1610c8ebb0..3e39fee246 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -113,9 +113,7 @@ PHP_METHOD(ServerCredentials, createSsl) { grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex( pem_root_certs, &pem_key_cert_pair, 1, GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL); - zval *creds_object; - PHP_GRPC_MAKE_STD_ZVAL(creds_object); - creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC); + zval *creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c index 945231b47f..7ada915aad 100644 --- a/src/php/ext/grpc/timeval.c +++ b/src/php/ext/grpc/timeval.c @@ -115,11 +115,9 @@ PHP_METHOD(Timeval, add) { } wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); - zval *sum; - PHP_GRPC_MAKE_STD_ZVAL(sum); - sum = - grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) - TSRMLS_CC); + zval *sum = + grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(sum); } @@ -141,11 +139,9 @@ PHP_METHOD(Timeval, subtract) { } wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); - zval *diff; - PHP_GRPC_MAKE_STD_ZVAL(diff); - diff = - grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) - TSRMLS_CC); + zval *diff = + grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(diff); } @@ -206,9 +202,7 @@ PHP_METHOD(Timeval, similar) { * @return Timeval The current time */ PHP_METHOD(Timeval, now) { - zval *now; - PHP_GRPC_MAKE_STD_ZVAL(now); - now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC); + zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(now); } @@ -217,13 +211,9 @@ PHP_METHOD(Timeval, now) { * @return Timeval Zero length time interval */ PHP_METHOD(Timeval, zero) { - zval *grpc_php_timeval_zero; - PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_zero); - grpc_php_timeval_zero = - grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC); - RETURN_ZVAL(grpc_php_timeval_zero, - false, /* Copy original before returning? */ - true /* Destroy original before returning */); + zval *grpc_php_timeval_zero = + grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC); + RETURN_DESTROY_ZVAL(grpc_php_timeval_zero); } /** @@ -231,10 +221,8 @@ PHP_METHOD(Timeval, zero) { * @return Timeval Infinite future time value */ PHP_METHOD(Timeval, infFuture) { - zval *grpc_php_timeval_inf_future; - PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_future); - grpc_php_timeval_inf_future = - grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC); + zval *grpc_php_timeval_inf_future = + grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future); } @@ -243,10 +231,8 @@ PHP_METHOD(Timeval, infFuture) { * @return Timeval Infinite past time value */ PHP_METHOD(Timeval, infPast) { - zval *grpc_php_timeval_inf_past; - PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_past); - grpc_php_timeval_inf_past = - grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC); + zval *grpc_php_timeval_inf_past = + grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past); } diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index aec60af094..a9e77b9396 100644 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -271,7 +271,7 @@ class BaseStub * @return ClientStreamingSurfaceActiveCall The active call object */ public function _clientStreamRequest($method, - callable $deserialize, + $deserialize, array $metadata = [], array $options = []) { @@ -307,7 +307,7 @@ class BaseStub */ public function _serverStreamRequest($method, $argument, - callable $deserialize, + $deserialize, array $metadata = [], array $options = []) { @@ -340,7 +340,7 @@ class BaseStub * @return BidiStreamingSurfaceActiveCall The active call object */ public function _bidiRequest($method, - callable $deserialize, + $deserialize, array $metadata = [], array $options = []) { diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto index be387cf786..529313cfb1 100644 --- a/src/proto/grpc/testing/control.proto +++ b/src/proto/grpc/testing/control.proto @@ -78,6 +78,14 @@ message SecurityParams { string server_host_override = 2; } +message ChannelArg { + string name = 1; + oneof value { + string str_value = 2; + int32 int_value = 3; + } +} + message ClientConfig { // List of targets to connect to. At least one target needs to be specified. repeated string server_targets = 1; @@ -103,6 +111,8 @@ message ClientConfig { // If we use an OTHER_CLIENT client_type, this string gives more detail string other_client_api = 15; + + repeated ChannelArg channel_args = 16; } message ClientStatus { ClientStats stats = 1; } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index d43f93b94f..e27e9e181d 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -82,6 +82,8 @@ CORE_SOURCE_FILES = [ 'src/core/lib/channel/connected_channel.c', 'src/core/lib/channel/deadline_filter.c', 'src/core/lib/channel/handshaker.c', + 'src/core/lib/channel/handshaker_factory.c', + 'src/core/lib/channel/handshaker_registry.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/channel/message_size_filter.c', diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py index 83b46c914e..650e4756e7 100644 --- a/src/python/grpcio_tests/tests/qps/benchmark_client.py +++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py @@ -68,12 +68,8 @@ class BenchmarkClient: else: channel = grpc.insecure_channel(server) - connected_event = threading.Event() - def wait_for_ready(connectivity): - if connectivity == grpc.ChannelConnectivity.READY: - connected_event.set() - channel.subscribe(wait_for_ready, try_to_connect=True) - connected_event.wait() + # waits for the channel to be ready before we start sending messages + grpc.channel_ready_future(channel).result() if config.payload_config.WhichOneof('payload') == 'simple_params': self._generic = False diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 390ea13021..b8116729b5 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -110,10 +110,13 @@ def _get_channel(target, args): channel_credentials = grpc.ssl_channel_credentials( root_certificates=root_certificates) options = (('grpc.ssl_target_name_override', args.server_host_override,),) - return grpc.secure_channel( - target, channel_credentials, options=options) + channel = grpc.secure_channel(target, channel_credentials, options=options) else: - return grpc.insecure_channel(target) + channel = grpc.insecure_channel(target) + + # waits for the channel to be ready before we start sending messages + grpc.channel_ready_future(channel).result() + return channel def run_test(args): test_cases = _parse_weighted_test_cases(args.test_cases) diff --git a/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb index fde328e4c5..7d1072e512 100644 --- a/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +++ b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb @@ -54,6 +54,10 @@ module Grpc rpc :EmptyCall, Empty, Empty # One request followed by one response. rpc :UnaryCall, SimpleRequest, SimpleResponse + # One request followed by one response. Response has cache control + # headers set such that a caching HTTP proxy (such as GFE) can + # satisfy subsequent requests. + rpc :CacheableUnaryCall, SimpleRequest, SimpleResponse # One request followed by a sequence of responses (streamed download). # The server returns the payload with client desired type and sizes. rpc :StreamingOutputCall, StreamingOutputCallRequest, stream(StreamingOutputCallResponse) @@ -69,6 +73,9 @@ module Grpc # stream of responses are returned to the client when the server starts with # first request. rpc :HalfDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse) + # The test server will not implement this method. It will be used + # to test the behavior when clients call unimplemented methods. + rpc :UnimplementedCall, Empty, Empty end Stub = Service.rpc_stub_class diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index f101f9d89e..9c4ee9c6f2 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -158,14 +158,26 @@ def create_stub(opts) GRPC.logger.info("... connecting securely to #{address}") stub_opts[:channel_args].merge!(compression_channel_args) - Grpc::Testing::TestService::Stub.new(address, creds, **stub_opts) + if opts.test_case == "unimplemented_service" + Grpc::Testing::UnimplementedService::Stub.new(address, creds, **stub_opts) + else + Grpc::Testing::TestService::Stub.new(address, creds, **stub_opts) + end else GRPC.logger.info("... connecting insecurely to #{address}") - Grpc::Testing::TestService::Stub.new( - address, - :this_channel_is_insecure, - channel_args: compression_channel_args - ) + if opts.test_case == "unimplemented_service" + Grpc::Testing::UnimplementedService::Stub.new( + address, + :this_channel_is_insecure, + channel_args: compression_channel_args + ) + else + Grpc::Testing::TestService::Stub.new( + address, + :this_channel_is_insecure, + channel_args: compression_channel_args + ) + end end end @@ -502,6 +514,153 @@ class NamedTests op.wait end + def unimplemented_method + begin + resp = @stub.unimplemented_call(Empty.new) + rescue GRPC::Unimplemented => e + return + rescue Exception => e + fail AssertionError, "Expected BadStatus. Received: #{e.inspect}" + end + fail AssertionError, "GRPC::Unimplemented should have been raised. Was not." + end + + def unimplemented_service + begin + resp = @stub.unimplemented_call(Empty.new) + rescue GRPC::Unimplemented => e + return + rescue Exception => e + fail AssertionError, "Expected BadStatus. Received: #{e.inspect}" + end + fail AssertionError, "GRPC::Unimplemented should have been raised. Was not." + end + + def status_code_and_message + + # Function wide constants. + message = "test status method" + code = GRPC::Core::StatusCodes::UNKNOWN + + # Testing with UnaryCall. + payload = Payload.new(type: :COMPRESSABLE, body: nulls(1)) + echo_status = EchoStatus.new(code: code, message: message) + req = SimpleRequest.new(response_type: :COMPRESSABLE, + response_size: 1, + payload: payload, + response_status: echo_status) + seen_correct_exception = false + begin + resp = @stub.unary_call(req) + rescue GRPC::Unknown => e + if e.details != message + fail AssertionError, + "Expected message #{message}. Received: #{e.details}" + end + seen_correct_exception = true + rescue Exception => e + fail AssertionError, "Expected BadStatus. Received: #{e.inspect}" + end + + if not seen_correct_exception + fail AssertionError, "Did not see expected status from UnaryCall" + end + + # testing with FullDuplex + req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters + duplex_req = req_cls.new(payload: Payload.new(body: nulls(1)), + response_type: :COMPRESSABLE, + response_parameters: [p_cls.new(size: 1)], + response_status: echo_status) + seen_correct_exception = false + begin + resp = @stub.full_duplex_call([duplex_req]) + resp.each { |r| } + rescue GRPC::Unknown => e + if e.details != message + fail AssertionError, + "Expected message #{message}. Received: #{e.details}" + end + seen_correct_exception = true + rescue Exception => e + fail AssertionError, "Expected BadStatus. Received: #{e.inspect}" + end + + if not seen_correct_exception + fail AssertionError, "Did not see expected status from FullDuplexCall" + end + + end + + + def custom_metadata + + # Function wide constants + req_size, wanted_response_size = 271_828, 314_159 + initial_metadata_key = "x-grpc-test-echo-initial" + initial_metadata_value = "test_initial_metadata_value" + trailing_metadata_key = "x-grpc-test-echo-trailing-bin" + trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b" + + metadata = { + initial_metadata_key => initial_metadata_value, + trailing_metadata_key => trailing_metadata_value + } + + # Testing with UnaryCall + payload = Payload.new(type: :COMPRESSABLE, body: nulls(req_size)) + req = SimpleRequest.new(response_type: :COMPRESSABLE, + response_size: wanted_response_size, + payload: payload) + + op = @stub.unary_call(req, metadata: metadata, return_op: true) + op.execute + if not op.metadata.has_key?(initial_metadata_key) + fail AssertionError, "Expected initial metadata. None received" + elsif op.metadata[initial_metadata_key] != metadata[initial_metadata_key] + fail AssertionError, + "Expected initial metadata: #{metadata[initial_metadata_key]}. "\ + "Received: #{op.metadata[initial_metadata_key]}" + end + if not op.trailing_metadata.has_key?(trailing_metadata_key) + fail AssertionError, "Expected trailing metadata. None received" + elsif op.trailing_metadata[trailing_metadata_key] != + metadata[trailing_metadata_key] + fail AssertionError, + "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ + "Received: #{op.trailing_metadata[trailing_metadata_key]}" + end + + # Testing with FullDuplex + req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters + duplex_req = req_cls.new(payload: Payload.new(body: nulls(req_size)), + response_type: :COMPRESSABLE, + response_parameters: [p_cls.new(size: wanted_response_size)]) + + duplex_op = @stub.full_duplex_call([duplex_req], metadata: metadata, + return_op: true) + resp = duplex_op.execute + resp.each { |r| } # ensures that the server sends trailing data + duplex_op.wait + if not duplex_op.metadata.has_key?(initial_metadata_key) + fail AssertionError, "Expected initial metadata. None received" + elsif duplex_op.metadata[initial_metadata_key] != + metadata[initial_metadata_key] + fail AssertionError, + "Expected initial metadata: #{metadata[initial_metadata_key]}. "\ + "Received: #{duplex_op.metadata[initial_metadata_key]}" + end + if not duplex_op.trailing_metadata[trailing_metadata_key] + fail AssertionError, "Expected trailing metadata. None received" + elsif duplex_op.trailing_metadata[trailing_metadata_key] != + metadata[trailing_metadata_key] + fail AssertionError, + "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ + "Received: #{duplex_op.trailing_metadata[trailing_metadata_key]}" + end + + end + def all all_methods = NamedTests.instance_methods(false).map(&:to_s) all_methods.each do |m| |